Changeset - 67ead6cfe058
ennstatus/__init__.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import os.path
 
import json
 

	
 
from flask import Flask, render_template
 
from flask.ext.bootstrap import Bootstrap
 
from flask.ext.wtf import CsrfProtect
 
from flask.ext.moment import Moment
 

	
 
from werkzeug.contrib.fixers import ProxyFix
 

	
 
import gnupg
 

	
 
bootstrap = Bootstrap()
 
csrf = CsrfProtect()
 
moment = Moment()
 

	
 
config_file = os.path.abspath('config.json')
 

	
 

	
 
def create_app():
 

	
 
    app = Flask(__name__)
 

	
 
    import ennstatus.config as config
 
    config.init_app(app)
 

	
 
    if not hasattr(app.config, 'from_json'):
 
        def from_json(file, silent=True):
 
            try:
 
                with open(file, encoding='utf-8') as json_file:
 
                    obj = json.load(json_file)
 
            except IOError:
 
                if silent:
 
                    return False
 
                raise
 

	
 
            for key in obj:
 
                if key.isupper():
 
                    app.config[key] = obj[key]
 

	
 
            return True
 

	
 
        app.config.from_json = from_json
 

	
 
    app.config.from_json(config_file)
 

	
 
    app.wsgi_app = ProxyFix(app.wsgi_app)
 

	
ennstatus/api/__init__.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
ennstatus/api/auth.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from flask import current_app
 
from flask.ext.httpauth import HTTPDigestAuth
 

	
 
httpauth = HTTPDigestAuth()
 

	
 

	
 
@httpauth.get_password
 
def get_pw(username):
 

	
 
    if username in current_app.config['ENNSTATUS_SERVERS']:
 
        return current_app.config['ENNSTATUS_SERVERS'][username]['PASSWORD']
 

	
 
    return None
ennstatus/api/model.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import ipaddress
 
import json
 
import functools
 
import statistics
 

	
 
from pathlib import Path
 
from datetime import datetime
 

	
 
import jsonschema
 
import strict_rfc3339
 
import requests
 

	
 
from flask import current_app
 
from pkg_resources import resource_filename
 

	
 
from ..utils import check_ip
 

	
 

	
 
schema = json.load(
 
    open(
 
        resource_filename('ennstatus.api', 'schema/server.json'),
 
        encoding='utf-8'
 
    )
 
)
 

	
 
validate = functools.partial(
 
    jsonschema.validate,
 
    schema=schema,
 
    format_checker=jsonschema.FormatChecker()
 
)
 

	
 

	
 
def calculate_weight(data):
 

	
 
    obj = {}
 

	
 
    for subkey in ('1_week', '1_month', '3_months', '1_year', '5_years'):
 

	
 
        try:
 
            subdata = data[subkey]
 
        except KeyError:
 
            continue
 

	
 
        factor = subdata['factor']
 

	
 
        values = [x * factor for x in subdata['values'] if x is not None]
 

	
 
        if values:
ennstatus/api/views.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import ipaddress
 
import json
 

	
 
from datetime import datetime
 

	
 
from flask import (Blueprint, request, current_app, jsonify, render_template,
 
                   abort)
 

	
 
from werkzeug.exceptions import BadRequest
 

	
 
import strict_rfc3339
 
import pygeoip
 
import requests
 

	
 
from ennstatus import csrf
 
from ennstatus.status.functions import (single_server, all_servers,
 
                                        all_servers_by_type)
 
from .model import Server
 
from .auth import httpauth
 

	
 
api_page = Blueprint('api', __name__)
 
gi4 = pygeoip.GeoIP('/usr/share/GeoIP/GeoIP.dat', pygeoip.MEMORY_CACHE)
 
gi6 = pygeoip.GeoIP('/usr/share/GeoIP/GeoIPv6.dat', pygeoip.MEMORY_CACHE)
 

	
 

	
 
@csrf.exempt
 
@api_page.route('/update', methods=('POST',))
 
@httpauth.login_required
 
def update():
 

	
 
    current_app.logger.info('Handling update')
 

	
 
    try:
 
        servers = current_app.config['ENNSTATUS_SERVERS']
 
    except KeyError as e:
 
        current_app.logger.error(str(e))
 
        return abort(500)
 

	
 
    username = httpauth.username()
 

	
 
    try:
 
        if request.remote_addr not in servers[username]['IPS']:
 
            current_app.logger.warn(
 
                'Unallowed IP {} tried to update data!'.format(
 
                    request.remote_addr
 
                )
 
            )
 
            return 'IP not allowed!\n', 403, {'Content-Type': 'text/plain'}
ennstatus/cli/__init__.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import pathlib
 

	
 
import click
 

	
 

	
 
@click.group()
 
@click.option('-p', '--path', default='/srv/http/enn.lu',
 
              help='Path where the config files are',
 
              type=click.Path(exists=True,
 
                              file_okay=False,
 
                              writable=True,
 
                              readable=True)
 
              )
 
@click.pass_context
 
def cli(ctx, path):
 
    ctx.obj = {}
 
    path = pathlib.Path(path)
 
    ctx.obj['path'] = path
 
    ctx.obj['config_file'] = path / 'config.json'
 
    ctx.obj['data_dir'] = path / 'data'
 

	
 

	
 
from .commands import config
 
cli.add_command(config, 'config')
 

	
 
if __name__ == '__main__':
 
    cli()
ennstatus/cli/commands/__init__.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from .config import config
 

	
 
__all__ = ['config']
ennstatus/cli/commands/config.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import json
 
import ipaddress
 

	
 
from pprint import pprint
 

	
 
import click
 

	
 
from ...utils import check_ip
 

	
 

	
 
@click.group(short_help='Configure ennstatus')
 
def config():
 
    pass
 

	
 

	
 
@config.command('show', short_help='Show current configuration')
 
@click.pass_obj
 
def show(obj):
 

	
 
    with obj['config_file'].open(encoding='utf-8') as f:
 
        config = json.load(f)
 
    pprint(config)
 

	
 

	
 
@config.group(short_help='Configure servers')
 
def server():
 
    pass
 

	
 

	
 
@server.command('add', short_help='Add server')
 
@click.argument('name')
 
@click.option('-i', '--ips', prompt='IPs (comma separated)')
 
@click.password_option()
 
@click.option('--bridgeprogram/--no-bridgeprogram', default=False)
 
@click.pass_obj
 
def add(obj, name, ips, password, bridgeprogram):
 

	
 
    with obj['config_file'].open() as f:
 
        config = json.load(f)
 

	
 
    name = name.lower()
 
    ips = [ip.strip() for ip in ips.split(',')]
 

	
 
    try:
 
        if name in config['ENNSTATUS_SERVERS']:
 
            try:
 
                click.confirm('Server already exits! Overwrite?', abort=True)
 
            except click.Abort as e:
ennstatus/config.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import os
 
import base64
 

	
 

	
 
def init_app(app):
 

	
 
    config = app.config
 

	
 
    _default_secret_key = base64.b64encode(os.urandom(32)).decode('utf-8')
 

	
 
    config['SECRET_KEY'] = os.environ.get('SECRET_KEY', _default_secret_key)
 

	
 
    # Flask-Bootstrap
 
    config.setdefault('BOOTSTRAP_SERVE_LOCAL', True)
 

	
 
    # ennstatus
 

	
 
    # moment.js string formatting
 
    # http://momentjs.com/docs/#/displaying/format/
 
    config.setdefault('ENNSTATUS_MOMENTJS_FORMAT', 'DD MMMM YYYY HH:mm:ss')
 

	
 
    config.setdefault('ENNSTATUS_STRFTIME_FORMAT', '%d %B %Y %H:%M:%S')
ennstatus/donate/__init__.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
ennstatus/donate/forms.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from flask_wtf import Form
 
from wtforms import SelectField, SubmitField
 
from wtforms.validators import DataRequired
 

	
 

	
 
class DateForm(Form):
 
    year = SelectField('Year', validators=[DataRequired()])
 
    month = SelectField('Month',
 
                        choices=[
 
                            ('{:02d}'.format(i), str(i)) for i in range(1, 13)
 
                        ],
 
                        validators=[DataRequired()])
 

	
 
    submit = SubmitField('Submit')
ennstatus/donate/functions.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import os
 
import os.path
 
import csv
 

	
 

	
 
def load_csv(date):
 

	
 
    filename = '.'.join([date, 'csv'])
 
    path = os.path.join('donations', filename)
 

	
 
    with open(path, encoding='utf-8', newline='') as csvfile:
 
        csvreader = csv.reader(csvfile, delimiter=',')
 

	
 
        for row in csvreader:
 
            yield row
 

	
 

	
 
def get_choices():
 

	
 
    files = os.listdir('donations')
 

	
 
    for file in files:
 
        if not file.startswith('.') \
 
           and file.endswith('.csv'):
 
            yield os.path.splitext(file)[0]
ennstatus/donate/views.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from flask import (Blueprint, render_template, request,
 
                   redirect, url_for, current_app)
 

	
 
from ennstatus.donate.forms import DateForm
 
from ennstatus.donate.functions import load_csv, get_choices
 

	
 
from ennstatus.root.forms import BPMForm
 
from ennstatus.root.constants import BPM_ADDRESSES
 

	
 
donate_page = Blueprint('donate', __name__)
 

	
 

	
 
@donate_page.route('/', methods=('GET', 'POST'))
 
def index():
 

	
 
    current_app.logger.info('Handling index')
 
    form = BPMForm()
 
    country_choices = [choice[0] for choice in form.country.choices]
 

	
 
    if request.method == 'POST':
 
        current_app.logger.debug('Validating form')
 
        if form.validate_on_submit():
 
            country = form.country.data
 
            return redirect(url_for('donate.index', country=country))
 
    else:
 
        if 'country' in request.args:
 
            country = request.args['country']
 
            if country in country_choices:
 
                current_app.logger.info('Showing country %s' % country)
 
            else:
 
                current_app.logger.warn('Country %s not found' % country)
 
                country = 'luxembourg'
 
        else:
 
            current_app.logger.info('Using default country')
 
            country = 'luxembourg'
 

	
 
    form.country.data = country
 
    address = BPM_ADDRESSES[country]
 

	
 
    return render_template('donate/index.html', form=form, address=address)
 

	
 

	
 
@donate_page.route('/received',
 
                   methods=('GET', 'POST'))
 
def received():
 

	
 
    current_app.logger.info('Handling received')
 
    form = DateForm()
ennstatus/log.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import logging
 
import logging.handlers
 

	
 
import os.path
 

	
 
logging_debug_string = ('%(levelname)s:%(name)s:%(asctime)s:%(filename)s'
 
                        ':%(lineno)d: %(message)s')
 
logging_string = '%(levelname)s - %(name)s - %(asctime)s - %(message)s'
 
logging_debug_formatter = logging.Formatter(logging_debug_string)
 
logging_formatter = logging.Formatter(logging_string)
 

	
 

	
 
def init_logging(app):
 

	
 
    app.logger.setLevel(logging.DEBUG)
 
    stream_handler = logging.StreamHandler()
 
    stream_handler.setLevel(logging.DEBUG)
 
    stream_handler.setFormatter(logging_debug_formatter)
 

	
 
    if not os.path.exists('log/ennstatus.log'):
 
        open('log/ennstatus.log', mode='a').close()
 

	
 
    rotating_file_handler = logging.handlers.RotatingFileHandler(
 
        'log/ennstatus.log',
 
        maxBytes=1300000,
 
        backupCount=10,
 
        encoding='utf-8')
 
    rotating_file_handler.setLevel(logging.INFO)
 
    rotating_file_handler.setFormatter(logging_formatter)
 

	
 
    if app.debug or ('ENABLE_DEBUG_LOG' in app.config and
 
                     app.config['ENABLE_DEBUG_LOG']):
 

	
 
        if not os.path.exists('log/ennstatus_debug.log'):
 
            open('log/ennstatus_debug.log', mode='a').close()
 

	
 
        second_rotating_file_handler = logging.handlers.RotatingFileHandler(
 
            'log/ennstatus_debug.log',
 
            maxBytes=1300000,
 
            backupCount=20,
 
            encoding='utf-8')
 
        second_rotating_file_handler.setLevel(logging.DEBUG)
 
        second_rotating_file_handler.setFormatter(logging_debug_formatter)
 
        app.logger.addHandler(second_rotating_file_handler)
 

	
 
    smtp_handler = logging.handlers.SMTPHandler(
 
        'localhost',
 
        'ennstatus@enn.lu',
ennstatus/root/__init__.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
ennstatus/root/constants.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 

	
 
BPM_ADDRESSES = {
 
    'germany': {
 
        'address': 'Zum Bürgerwehr 28',
 
        'postal_code': 'D-54516',
 
        'city': 'Wittlich',
 
        'country': 'Germany',
 
    },
 
    'belgium': {
 
        'address': '3, Rue des Deux Luxembourg',
 
        'postal_code': 'B-6791',
 
        'city': 'Athus',
 
        'country': 'Belgium',
 
    },
 
    'france': {
 
        'address': 'Les Maragolles',
 
        'postal_code': 'F-54720',
 
        'city': 'Lexy',
 
        'country': 'France',
 
    },
 
    'luxembourg': {
 
        'address': '34, Rue Gabriel Lippmann',
 
        'postal_code': 'L-5365',
 
        'city': 'Munsbach',
 
        'country': 'Luxembourg',
 
    },
 
}
ennstatus/root/forms.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from flask_wtf import Form
 
from wtforms import (SelectField,
 
                     StringField,
 
                     RadioField,
 
                     BooleanField,
 
                     SubmitField
 
                     )
 
from wtforms.validators import InputRequired, Email, Length, DataRequired
 

	
 

	
 
COUNTRIES = [
 
    ('luxembourg', 'Luxembourg'),
 
    ('belgium', 'Belgium'),
 
    ('france', 'France'),
 
    ('germany', 'Germany'),
 
]
 

	
 

	
 
class BPMForm(Form):
 
    country = SelectField('Country',
 
                          validators=[DataRequired()],
 
                          choices=COUNTRIES)
 
    submit = SubmitField('Submit')
 

	
 

	
 
class MembershipForm(Form):
 

	
 
    username = StringField('Username*',
 
                           validators=[
 
                               InputRequired('This field is required!'),
 
                               Length(max=255)
 
                           ]
 
                           )
 
    email = StringField('E-Mail*',
 
                        validators=[
 
                            InputRequired('This field is required!'),
 
                            Email()
 
                        ]
 
                        )
 
    fullname = StringField('Full name',
 
                           validators=[Length(max=65536)],
 
                           )
 
    street = StringField('Nr., Street',
 
                         validators=[Length(max=4000)],
 
                         )
 
    zip = StringField('ZIP-Code',
 
                      validators=[Length(max=30)],
 
                      )
ennstatus/root/functions.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from flask import render_template, current_app, flash
 

	
 
from flask_mail import Mail, Message
 

	
 
from ennstatus.status.functions import mail
 

	
 

	
 
def send_membership_mail(form):
 
    try:
 
        body = render_template('root/membership_mail.txt',
 
                               username=form.username.data,
 
                               email=form.email.data,
 
                               membership=form.membership.data,
 
                               c3l=form.c3l.data,
 
                               fullname=form.fullname.data,
 
                               street=form.street.data,
 
                               zip=form.zip.data,
 
                               city=form.city.data,
 
                               country=form.country.data,
 
                               gpg=form.gpg.data
 
                               )
 

	
 
        recipients = current_app.config['ENNSTATUS_MEMBERSHIP_MAIL']
 
        with mail.connect() as conn:
 
            for recipient in recipients:
 
                msg = Message(
 
                    'New membership application',
 
                    sender='ennstatus@enn.lu'
 
                )
 
                msg.add_recipient(recipient)
 
                current_app.logger.debug('Before encryption')
 
                current_app.logger.debug(body)
 
                if current_app.extensions['gnupg']:
 
                    encrypted_body = str(
 
                        current_app.extensions['gnupg'].encrypt(
 
                            body,
 
                            recipient,
 
                            always_trust=True
 
                        )
 
                    )
 
                else:
 
                    encrypted_body = None
 
                current_app.logger.debug('After encryption')
 
                current_app.logger.debug(body)
 
                msg.body = encrypted_body if encrypted_body else body
 
                conn.send(msg)
 
        flash('Application successfully submitted!', 'success')
 
    except KeyError:
ennstatus/root/views.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from flask import (Blueprint, render_template, current_app,
 
                   request, redirect, url_for, flash)
 

	
 
from ennstatus.root.forms import BPMForm, MembershipForm, BridgeprogramForm
 
from ennstatus.root.constants import BPM_ADDRESSES
 
from ennstatus.root.functions import (send_membership_mail,
 
                                      send_bridgeprogram_mail)
 

	
 
root_page = Blueprint('root', __name__)
 

	
 

	
 
@root_page.route('/')
 
def index():
 
    return render_template('root/index.html')
 

	
 

	
 
@root_page.route('/about')
 
def about():
 
    return render_template('root/about.html')
 

	
 

	
 
@root_page.route('/partners')
 
def partners():
 
    return render_template('root/partners.html')
 

	
 

	
 
@root_page.route('/bridgeprogram', methods=('GET', 'POST'))
 
def bridgeprogram():
 

	
 
    current_app.logger.info('Handling bridgeprogram')
 
    form = BridgeprogramForm()
 

	
 
    if request.method == 'POST':
 
        current_app.logger.debug('Validation form')
 
        if form.validate_on_submit():
 
            send_bridgeprogram_mail(form)
 
            return redirect(url_for('root.bridgeprogram'))
 

	
 
    return render_template('root/bridgeprogram.html', form=form)
 

	
 

	
 
@root_page.route('/member')
 
def member():
 
    return render_template('root/member.html')
 

	
 

	
 
@root_page.route('/membership', methods=('GET', 'POST'))
 
def membership():
ennstatus/statistics/__init__.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
ennstatus/statistics/views.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from collections import defaultdict
 

	
 
from flask import Blueprint, render_template, current_app, jsonify
 

	
 
from ennstatus.status.functions import split_all_servers_to_types
 

	
 
statistics_page = Blueprint('statistics', __name__)
 

	
 

	
 
@statistics_page.route('/worldmap')
 
def worldmap():
 
    return render_template('statistics/worldmap.html')
 

	
 

	
 
@statistics_page.route('/data/worldmap')
 
def data_worldmap():
 
    servers = split_all_servers_to_types()
 
    countries = defaultdict(int)
 

	
 
    for key, value in servers.items():
 
        for server in value:
 
            countries[server['country']] += 1
 

	
 
    maximum = max(countries.values())
 

	
 
    countries['max'] = maximum
 

	
 
    return jsonify(countries)
ennstatus/status/__init__.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
ennstatus/status/forms.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from flask_wtf import Form
 
from wtforms import SelectField, SubmitField
 
from wtforms.validators import DataRequired
 

	
 
SERVERTYPES = [
 
    ('all', 'All'),
 
    ('exit', 'Exits'),
 
    ('relay', 'Relays'),
 
    ('bridge', 'Bridges')
 
]
 

	
 

	
 
class ServerTypeForm(Form):
 
    servertype = SelectField(
 
        'Servertype',
 
        validators=[DataRequired()],
 
        choices=SERVERTYPES
 
    )
 
    submit = SubmitField('Submit')
ennstatus/status/functions.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
import os
 
import os.path
 
import json
 

	
 
from collections import defaultdict
 
from datetime import datetime
 

	
 
from flask import current_app
 
from flask_mail import Mail, Message
 

	
 
from ..api.model import Server
 

	
 
mail = Mail()
 

	
 

	
 
def single_server(name):
 

	
 
    server = Server.from_file_by_name(name)
 

	
 
    if server:
 
        server.check_status()
 

	
 
    return server
 

	
 

	
 
def _get_json_files(root, files):
 

	
 
    for f in files:
 
        if f.endswith('.json'):
 
            yield f
 

	
 

	
 
def all_servers():
 

	
 
    for root, _, files in os.walk('data'):
 
        for f in _get_json_files(root, files):
 
            yield single_server(f[:-5])
 

	
 

	
 
def all_servers_by_type(type):
 

	
 
    for server in all_servers():
 
        try:
 
            if server.type == type:
 
                yield server
 
        except TypeError:
 
            continue
 

	
ennstatus/status/views.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 
from flask import (Blueprint,
 
                   render_template,
 
                   current_app,
 
                   request,
 
                   redirect,
 
                   url_for)
 

	
 
from ennstatus.status.functions import (all_servers_by_type, single_server,
 
                                        split_all_servers_to_types)
 

	
 
from .forms import ServerTypeForm
 

	
 
status_page = Blueprint('status', __name__)
 

	
 

	
 
@status_page.route('/', methods=('GET', 'POST'))
 
def index():
 
    current_app.logger.info('Handling status index!')
 

	
 
    form = ServerTypeForm()
 

	
 
    if request.method == 'POST':
 
        current_app.logger.debug('Validating form')
 
        if form.validate_on_submit():
 
            servertype = form.servertype.data
 
            if servertype != 'all':
 
                return redirect(url_for('status.' + servertype))
 

	
 
    servers = split_all_servers_to_types()
 

	
 
    current_app.logger.info('Returning servers')
 
    return render_template('status/index.html', exit=servers['exit'],
 
                           relay=servers['relay'], bridge=servers['bridge'],
 
                           form=form)
 

	
 

	
 
@status_page.route('/exit')
 
def exit():
 
    servers = list(all_servers_by_type('exit'))
 
    form = ServerTypeForm()
 
    form.servertype.data = 'exit'
 
    return render_template('status/index.html', exit=servers, form=form)
 

	
 

	
 
@status_page.route('/relay')
 
def relay():
 
    servers = list(all_servers_by_type('relay'))
 
    form = ServerTypeForm()
ennstatus/utils.py
Show inline comments
 
# Ënnstatus
 
# Copyright (C) 2015  Dennis Fink
 
#
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 

	
 

	
 
def check_ip(ipaddress):
 
    return not any({
 
        ipaddress.is_private,
 
        ipaddress.is_multicast,
 
        ipaddress.is_unspecified,
 
        ipaddress.is_reserved,
 
        ipaddress.is_loopback
 
    })
0 comments (0 inline, 0 general)