Changeset - 447435fa7bff
.hgignore
Show inline comments
 
syntax: glob
 

	
 
*.pyc
 
__pycache__/*
 
*~
 
*.s[a-w][a-z]
 
*.un~
 
Session.vim
 
.netrwhist
 
log/*
 
vnstats/*
 

	
 
docs/build/*
 
test/*
 

	
 
run.py
 
*.csv
 
*.json
 
*.orig
 

	
 
Ennstatus.egg-info/*
 
doc/*
ennstatus/api/views.py
Show inline comments
 
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'}
 
    except KeyError as e:
 
        current_app.logger.error(str(e))
 
        return abort(500)
 

	
 
    try:
 
        data = request.get_json()
 
    except BadRequest:
 
        current_app.logger.info('No JSON data supplied!')
 
        return 'No JSON data supplied!\n', 400, {'Content-Type': 'text/plain'}
 

	
 
    try:
 
        if username != data['name'].lower():
 
            current_app.logger.warn(
 
                'Unallowed user {} tried to update {}!'.format(
 
                    username, data['name']
 
                )
 
            )
 
            return ('You are not allowed to update this server\n',
 
                    403, {'Content-Type': 'text/plain'})
 
    except KeyError:
 
        return abort(409)
 

	
 
    if 'ip' in data:
 
        ip = data['ip']
 
    elif 'ip6' in data:
 
        ip = data['ip6']
 
    else:
 
        ip = request.remote_addr
 
        try:
 
            temp_ip = ipaddress.ip_address(ip)
 
        except ipaddress.AddressValueError:
 
            return 'IP not allowed!\n', 403, {'Content-Type': 'text/plain'}
 
        else:
 
            if temp_ip.version == 4:
 
                data['ip'] = ip
 
            elif temp_ip.verison == 6:
 
                data['ip6'] = ip
 

	
 
    try:
 
        country = gi4.country_name_by_addr(ip)
 
    except pygeoip.GeoIPError:
 
        country = gi6.country_name_by_addr(ip)
 

	
 
    data['country'] = country
 
    data['last_updated'] = strict_rfc3339.timestamp_to_rfc3339_utcoffset(
 
        datetime.utcnow().timestamp()
 
    )
 

	
 
    try:
 
        server = Server.from_dict(data)
 
    except Exception as e:
 
        current_app.logger.warning(' '.join([str(e), str(data)]))
 
        return str(e), 409, {'Content-Type': 'text/plain'}
 

	
 
    try:
 
        server.update_weights()
 
    except NotImplementedError:
 
        pass
 
    except requests.HTTPError as e:
 
        current_app.logger.error(str(e), exc_info=True)
 
        pass
 

	
 
    try:
 
        server.save()
 
    except Exception as e:
 
        current_app.logger.error(str(e))
 
        return str(e), 500, {'Content-Type': 'text/plain'}
 

	
 
    current_app.logger.info('Return result')
 
    return (
 
        server.json(), 201,
 
        {
 
            'Location': '/api/export/json/single?server_name={}'.format(
 
                server.name
 
            )
 
        }
 
    )
 

	
 

	
 
@api_page.route('/export', defaults={'server_type': 'all'})
 
@api_page.route(('/export/<any("all", "exit", "bridge", "relay", "single")'
 
                 ':server_type>'))
 
def export(server_type):
 

	
 
    current_app.logger.info('Handling export')
 
    if server_type == 'single':
 
        server_name = request.args.get('server_name', None)
 
        if server_name is not None:
 
            server = single_server(server_name)
 
            if server:
 
                return server.json(), 200, {'Content-Type': 'application/json'}
 
            else:
 
                current_app.logger.warning('Server not found!')
 
                return ('Server not found!\n',
 
                        404, {'Content-Type': 'text/plain'})
 
        else:
 
            current_app.logger.warning('No server_name specified!')
 
            return ('No server_name specified!\n',
 
                    400, {'Content-Type': 'text/plain'})
 

	
 
    else:
 
        if server_type == 'all':
 
            current_app.logger.info('Getting all servers!')
 
            servers = [
 
                json.loads(
 
                    server.json()
 
                ) for server in all_servers()
 
            ]
 
        else:
 
            current_app.logger.info('Getting all {}!'.format(server_type))
 
            servers = [
 
                json.loads(
 
                    server.json()
 
                ) for server in all_servers_by_type(server_type.lower())
 
            ]
 

	
 
        return json.dumps(servers), 200, {'Content-Type': 'application/json'}
 

	
 

	
 
@api_page.route('/fingerprints', defaults={'server_type': 'all'})
 
@api_page.route('/fingerprints/<any("all", "exit", "relay"):server_type>')
 
def fingerprint(server_type):
 
    if server_type == 'all':
 
        servers = [server.fingerprint for server in all_servers()
 
                   if server.type != 'bridge']
 
    else:
 
        servers = [server.fingerprint
 
                   for server in all_servers_by_type(server_type.lower())]
 

	
 
    return '\n'.join(servers), 200, {'Content-Type': 'text/plain'}
ennstatus/root/functions.py
Show inline comments
 
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 sended!', 'success')
 
        flash('Application successfully submitted!', 'success')
 
    except KeyError:
 
        flash(
 
            'Internal server error! Please get in touch with us at info@enn.lu!',
 
            'error'
 
        )
 
        current_app.logger.error('Membership admin not found!')
 
    except AssertionError:
 
        pass
 
    except Exception as e:
 
        flash(
 
            'Internal server error! Please get in touch with us at info@enn.lu!',
 
            'error'
 
        )
 
        current_app.logger.error('Unexpected error: %s' % e,
 
                                 exc_info=True)
 

	
 

	
 
def send_bridgeprogram_mail(form):
 

	
 
    try:
 
        body = render_template('root/bridgeprogram_mail.txt',
 
                               fullname=form.fullname.data,
 
                               email=form.email.data,
 
                               bridgename=form.bridgename.data,
 
                               duration=form.duration.data,
 
                               payment=form.payment.data
 
                               )
 

	
 
        recipients = current_app.config['ENNSTATUS_BRIDGEPROGRAM_MAIL']
 
        with mail.connect() as conn:
 
            for recipient in recipients:
 
                msg = Message('New bridge program application',
 
                              sender='ennstatus@enn.lu')
 
                msg.add_recipient(recipient)
 
                if current_app.extensions['gnupg']:
 
                    encrypted_body = str(
 
                        current_app.extensions['gnupg'].encrypt(
 
                            body,
 
                            recipient,
 
                            always_trust=True
 
                        )
 
                    )
 
                else:
 
                    encrypted_body = None
 
                msg.body = encrypted_body if encrypted_body else body
 
                conn.send(msg)
 
        flash(
 
            'Application successfully sended! We will send you an email with further information!',
 
            'Application successfully submitted! We will send you an email with further information!',
 
            'success'
 
        )
 
    except KeyError:
 
        flash(
 
            'Internal server error! Please get in touch with us at info@enn.lu',
 
            'error'
 
        )
 
        current_app.logger.error('Bridgeprogram admin not found!')
 
    except AssertionError:
 
        pass
 
    except Exception as e:
 
        flash(
 
            'Internal server error! Please get in touch with us at info@enn.lu!',
 
            'error'
 
        )
 
        current_app.logger.error('Unexpected error: %s' % e,
 
                                 exc_info=True)
ennstatus/root/views.py
Show inline comments
 
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('/services')
 
def services():
 
    return render_template('root/services.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():
 

	
 
    current_app.logger.info('Handling membership')
 
    form = MembershipForm()
 

	
 
    if request.method == 'POST':
 
        current_app.logger.debug('Validating form')
 
        if form.validate_on_submit():
 
            send_membership_mail(form)
 
            return redirect(url_for('root.member'))
 

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

	
 

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

	
 

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

	
 
    current_app.logger.info('Handling contact')
 
    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('root.contact', 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('root/contact.html', form=form, address=address)
 

	
 

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

	
 

	
 
@root_page.route('/ennstatus')
 
def ennstatus():
 
    return render_template('root/ennstatus.html')
ennstatus/static/css/ennstatus.css
Show inline comments
 
blockquote {
 
    border: none;
 
}
 

	
 
.thumbnail {
 
    border: none;
 
}
 

	
 
.container {
 
    margin-top:1%;
 
}
 

	
 
.navbar-default {
 
   background-color: #00ae18;
 
   /* border-radius: 50px; */
 
}
 

	
 
h1, h2, h3, h4 {
 
   color: #00ae18;
 
}
 

	
 
.navbar-default .navbar-brand {
 
   color: #fff;
 
}
 

	
 
.navbar-default img.navbar-brand {
 
  padding: 10px 0 10px 10px;
 
}
 

	
 
.navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus {
 
   color: #333;
 
}
 

	
 
.navbar-default .navbar-nav > li > a {
 
   color: #fff;
 
}
 

	
 
.dropdown-menu {
 
   background-color: #00ae18;
 
}
 

	
 
.dropdown-menu > li > a {
 
  color: #fff;
 
}
 

	
 
.dropdown-menu > li > a:hover {
 
   background-color: #00bf1a;
 
   color: #333;
 
}
 

	
 
.navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus {
 
   background-color: #00bf1a;
 
   color: #fff;
 
}
 

	
 
.dropdown-menu .divider {
 
    background-color: #00bf1a;
 
}
 

	
 
a, a:hover, a:active, a:visited {
 
    color: #af24cb;
 
}
 

	
 

	
 

	
 
/* Multi level dropdown menu http://bootsnipp.com/snippets/featured/multi-level-dropdown-menu-bs3 */
 

	
 
.dropdown-submenu {
 
    position: relative;
 
}
 

	
 
.dropdown-submenu > .dropdown-menu {
 
    top: 0;
 
    left: 100%;
 
    margin-top: -6px;
 
    margin-left: -1px;
 
    -webkit-border-radius: 0 6px 6px 6px;
 
    -moz-border-radius: 0 6px 6px 6px;
 
    border-radius: 0 6px 6px 6px;
 
}
 

	
 
.dropdown-submenu:hover > .dropdown-menu {
 
    display: block;
 
}
 

	
 
.dropdown-submenu > a:after {
 
    display: block;
 
    content: " ";
 
    float: right;
 
    width: 0;
 
    height: 0;
 
    border-color: transparent;
 
    border-style: solid;
 
    border-width: 5px 0 5px 5px;
 
    border-left-color: #ccc;
 
    margin-top: 5px;
 
    margin-right: -10px;
 
}
 

	
 
.dropdown-submenu:hover > a:after {
 
    border-left-color: #fff;
 
}
 

	
 
.dropdown-submenu .pull-left {
 
    float: none;
 
}
 

	
 
.dropdown-submenu .pull-left > .dropdown-menu {
 
    left: -100%;
 
    margin-left: 10px;
 
    -webkit-border-radius: 6px 0 6px 6px;
 
    -moz-border-radius: 6px 0 6px 6px;
 
    border-radius: 6px 0 6px 6px;
 
}
 

	
 
/* fancy bootstrap checkboxes */
 

	
 
.form-group input[type="checkbox"] {
 
    display: none;
 
}
 

	
 
.form-group input[type="checkbox"] + .btn-group > label span {
 
    width: 20px;
 
}
 

	
 
.form-group input[type="checkbox"] + .btn-group > label span:first-child {
 
    display: none;
 
}
 

	
 
.form-group input[type="checkbox"] + .btn-group > label span:last-child {
 
    display: inline-block;
 
}
 

	
 
.form-group input[type="checkbox"]:checked + .btn-group > label span:first-child {
 
    display: inline-block;
 
}
 

	
 
.form-group input[type="checkbox"]:checked + .btn-group > label span:last-child {
 
    display: none;
 
}
 

	
 
.form-group input[type="radio"] {
 
    display: none;
 
}
 

	
 
.form-group input[type="radio"] + .btn-group > label span {
 
    width: 20px;
 
}
 

	
 
.form-group input[type="radio"] + .btn-group > label span:first-child {
 
    display: none;
 
}
 

	
 
.form-group input[type="radio"] + .btn-group > label span:last-child {
 
    display: inline-block;
 
}
 

	
 
.form-group input[type="radio"]:checked + .btn-group > label span:first-child {
 
    display: inline-block;
 
}
 

	
 
.form-group input[type="radio"]:checked + .btn-group > label span:last-child {
 
    display: none;
 
}
 

	
 
.checkbox label, .radio label {
 
    padding-left: 12px;
 
}
 

	
 
.btn {
 
    margin-top: 5px;
 
    margin-bottom: 5px;
 
}
 

	
 
.highlighted-label {
 
    font-size: 24px;
 
    margin-bottom: 10px;
 
    font-weight: 500;
 
    line-height: 1.1;
 
    box-sizing: border-box;
 
    display: inline-block;
 
}
 

	
 
.highlighted-label-big {
 
    font-size: 30px;
 
    margin-bottom: 10px;
 
    font-weight: 500;
 
    line-height: 1.1;
 
    box-sizing: border-box;
 
    display: inline-block;
 

	
 
}
 

	
 
.btn-enn {
 
    color: #fff;
 
    background-color: #00ae18;
 
    border-color: #009414;
 
}
 

	
 
footer {
 
    margin-bottom: 20px;
 
}
ennstatus/status/views.py
Show inline comments
 
from flask import Blueprint, render_template, current_app
 

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

	
 
status_page = Blueprint('status', __name__)
 

	
 

	
 
@status_page.route('/')
 
def index():
 
    current_app.logger.info('Handling status index!')
 

	
 
    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'])
 

	
 

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

	
 

	
 
@status_page.route('/relay')
 
def relay():
 
    servers = list(all_servers_by_type('relay'))
 
    return render_template('status/index.html', relay=servers)
 

	
 

	
 
@status_page.route('/bridge')
 
def bridge():
 
    servers = list(all_servers_by_type('bridge'))
 
    return render_template('status/index.html', bridge=servers)
 

	
 

	
 
@status_page.route('/single/<server_name>')
 
def single(server_name):
 
    server = single_server(server_name.lower())
 
    kwargs = {server['server_type'].lower(): [server]}
 
    return render_template('status/index.html', **kwargs)
 

	
 

	
 
@status_page.route('/about')
 
def about():
 
    return render_template('status/about.html')
ennstatus/templates/base.html
Show inline comments
 
{% extends "bootstrap/base.html" %}
 

	
 
{% import 'macros.html' as base_macros with context %}
 

	
 
{% if '.onion' in request.url_root %}
 
  {% set wiki_url = config['ENNSTATUS_WIKI_ONION_ADDRESS'] %}
 
{% elif '.bit' in request.url_root %}
 
  {% set wiki_url = config['ENNSTATUS_WIKI_BIT_ADDRESS'] %}
 
{% else %}
 
  {% set wiki_url = "wiki.enn.lu" %}
 
{% endif %}
 

	
 
{% block title %}
 
  Frënn vun der Ënn - {{ title }}
 
{% endblock %}
 

	
 
{% block metas %}
 
  {{ super() }}
 
  <meta charset="utf-8">
 
  <meta name="application-name" content="Ënnstatus">
 
  <meta name="author" content="Frënn vun der Ënn">
 

	
 
  <meta name="twitter:card" content="summary" />
 
  <meta name="twitter:site" content="@FrennVunDerEnn" />
 
  <meta name="twitter:title" content="Frënn vun der Ënn A.S.B.L." />
 
  <meta name="twitter:description" content="Luxembourg based non-profit organization defending civil rights on the internet." />
 
  <meta name="twitter:image" content="{{ url_for('static', filename='images/logo/FVDE_logo_resize.png', _external=True) }}" />
 
{% endblock %}
 

	
 
{% block styles %}
 
  {{ super() }}
 
  <link rel="stylesheet" href="{{ url_for('static', filename='css/ennstatus.css') }}" />
 
  <link rel="shortcut icon" href="{{ url_for('static', filename='images/favicon.png') }}">
 
{% endblock %}
 

	
 
{% block body %}
 
<a href="#content" class="sr-only">Skip to main content</a>
 
<div class="container">
 
  {% block navbar %}
 
  <div class="navbar navbar-default">
 
    <div class="navbar-header">
 
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
 
        <span class="icon-bar"></span>
 
        <span class="icon-bar"></span>
 
        <span class="icon-bar"></span>
 
      </button>
 
      <img class="navbar-brand" src="{{ url_for('static', filename='images/logo/FVDE_logo_thumbnail.png') }}"></img>
 
      <a class="navbar-brand" href="{{ url_for('root.index') }}">Enn.lu</a>
 
    </div>
 
    <div class="navbar-collapse collapse">
 
      <ul class="nav navbar-nav">
 
        <li class="dropdown">
 
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">About <b class="caret"></b></a>
 
          <ul class="dropdown-menu">
 
            <li><a href="//{{ wiki_url }}/doku.php?id=news" target="blank">News</a></li>
 
            <li class="divider"></li>
 
            <li><a href="{{ url_for('root.about') }}">Organization</a></li>
 
            <li><a href="{{ url_for('root.partners') }}">Partners</a></li>
 
          </ul>
 
        </li>
 
        <li class="dropdown">
 
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Services <b class="caret"></b></a>
 
          <ul class="dropdown-menu">
 
            <li class="dropdown-submenu">
 
              <a>Tor Servers</a>
 
              <ul class="dropdown-menu">
 
                <li><a href="{{ url_for('status.index') }}">All servers</a></li>
 
                <li class="divider"></li>
 
                <li><a href="{{ url_for('status.exit') }}">Exits</a></li>
 
                <li><a href="{{ url_for('status.relay') }}">Relays</a></li>
 
                <li><a href="{{ url_for('status.bridge') }}">Bridges</a></li>
 
              </ul>
 
            <li class="divider"></li>
 
            </li>
 
            <li><a href="{{ url_for('root.mirrors') }}">Mirrors</a></li>
 
            <li><a href="//{{ wiki_url }}">Wiki</a></li>
 
            <li class="divider"></li>
 
            <li><a href="{{ url_for('root.ennstatus') }}">About Ënnstatus</a></li>
 
          </ul>
 
        </li>
 
        <li class="dropdown">
 
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Support <b class="caret"></b></a>
 
          <ul class="dropdown-menu">
 
            <li><a href="{{ url_for('donate.index') }}">Donate</a></li>
 
            <li><a href="{{ url_for('donate.received') }}">Donation history</a></li>
 
            <li><a href="{{ url_for('root.bridgeprogram')}}">Adopt a Bridge</a></li>
 
            <li class="divider"></li>
 
            <li><a href="{{ url_for('root.member') }}">Join Us</a></li>
 
            <li class="dropdown-submenu">
 
            </li>
 
          </ul>
 
        </li>
 
        <li class="dropdown">
 
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Contact <b class="caret"></b></a>
 
          <ul class="dropdown-menu">
 
            <li><a href="{{ url_for('root.contact') }}">General</a></li>
 
            <li><a href="{{ url_for('root.abuse') }}">Abuse</a></li>
 
            <li class="divider"></li>
 
            <li><a href="https://twitter.com/FrennVunDerEnn" target="blank">Twitter</a></li>
 
            <li><a href="http://lists.enn.lu/listinfo/discuss" target="blank">Mailing List</a></li>
 
          </ul>
 
        </li>
 
      </ul>
 
    </div>
 
  </div>
 
  {% endblock %}
 
  <div class="row" id="content">
 
  {% with messages = get_flashed_messages(with_categories=True) %}
 
    {% if messages %}
 
      <div class="col-md-12">
 
        {% for category, message in messages %}
 
          {{ base_macros.display_error(category, message) }}
 
        {% endfor %}
 
      </div>
 
    {% endif %}
 
  {% endwith %}
 
  {% block content %}
 
  {% endblock %}
 
  </div>
 
  <footer>
 
  <footer class="col-md-12">
 
    <hr style="margin-bottom: 0.5%;">
 
    <div class="col-md-12 text-center">
 
      <a class="pull-left" href="https://twitter.com/FrennVunDerEnn" target="blank">@FrennVunDerEnn</a>
 
      <address><strong>Frënn vun der Enn a.s.b.l.</strong>  <em>(R.C.S. Luxembourg F 9.478)</em>
 
      <a class="pull-right" rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US" target="blank">CC-BY-NC-SA</a></address>
 
    <div class="text-center clearfix">
 
      <div class="pull-left">
 
        <a href="https://twitter.com/FrennVunDerEnn" target="blank">@FrennVunDerEnn</a>
 
      </div>
 
      <strong>Frënn vun der Enn a.s.b.l.</strong>  <em>(R.C.S. Luxembourg F 9.478)</em>
 
      <div class="pull-right">
 
        <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.en_US" target="blank">CC-BY-NC-SA</a>
 
      </div>
 
    </div>
 
  </footer>
 
</div>
 

	
 
{% block scripts %}
 
  {{ super() }}
 
{% endblock %}
 

	
 
{% endblock %}
ennstatus/templates/donate/index.html
Show inline comments
 
{% extends "base.html" %}
 

	
 
{% set title = "Donate" %}
 

	
 
{% block styles %}
 
  {{ super() }}
 
  <style>
 
    .bitpay-donate { margin:20px 0;}
 
    .bitpay-donate fieldset {border:0;}
 
    .bitpay-donate input {padding:4px 10px;}
 
    .bitpay-donate select {padding:3px 10px;}
 
    .bitpay-donate ul, .bitpay-donate li {padding:0;margin:0;list-style:none;}
 
    .bitpay-donate li {padding:10px 0;}
 
    .bitpay-donate-field {clear:both;}
 
    .bitpay-donate-field label {float:left;width:100px;}
 
    .bitpay-donate-field div {float:left;}
 
    .bitpay-donate-field-email {width:80%;}
 
    .bitpay-donate-field-price {width:40%;}
 
    .bitpay-donate-field-currency {width:40%;}
 
    .bitpay-donate-button-wrapper {clear:both;margin:auto;text-align:center;}
 
    input.bitpay-donate-error {border:2px solid red;}
 
  </style>
 
{% endblock %}
 

	
 
{% block content %}
 
  <div class="col-md-4 text-center">
 
    <img src="{{ url_for('static', filename='images/Support.png') }}" class="img-rounded" alt="WhoIs" width="160"></img>
 
  <div class="col-md-4">
 
    <img src="{{ url_for('static', filename='images/Support.png') }}" class="img-responsive img-rounded center-block" alt="WhoIs" width="160"></img>
 
    <div class="text-center">
 
    <h2>Support us!</h2>
 
  </div>
 
  </div>
 
  <div class="col-md-8">
 
    <div class="jumbotron">
 
      <h2>Take action for a <strong>#FreeInternet</strong>! Support us today!</h2>
 
      <p>As a non-profit organization we are 100% community funded. Donations from our members and supporters will be used to <strong>power Tor nodes</strong>, <strong>print flyers and posters</strong> or cover administrative charges.</p>
 
      <h3><a href="{{ url_for('donate.received') }}"><span class="label label-info">Donation history</span></a>
 
      <a href="{{ url_for('root.bridgeprogram') }}"><span class="label label-primary">Adopt a Tor Bridge</span></a></h3>
 
      <span class='highlighted-label'><a href="{{ url_for('donate.received') }}"><span class="label label-info">Donation history</span></a></span>
 
      <span class='highlighted-label'><a href="{{ url_for('root.bridgeprogram') }}"><span class="label label-primary">Adopt a Tor Bridge</span></a></span>
 
    </div>
 
  </div>
 
  <div class="col-md-12">
 
    <div class="col-md-4">
 
      <div class="thumbnail">
 
        <center>
 
          <h3>Wire Transfer </h3>
 
        </center>
 
        <div class="well well-sm">
 
          <p>
 
            <strong>Account holder:</strong> Frënn vun der Ënn A.S.B.L.<br>
 
            <strong>BIC/SWIFT:</strong> BCEELULL<br>
 
            <strong>IBAN:</strong> LU65 0019 4055 6782 7000<br>
 
          </p>
 
       </div>
 
       <div class="well well-sm">
 
       <p>
 
         <strong>Account holder:</strong> Chaos Computer Club Lëtzebuerg A.S.B.L.<br>
 
         <strong>BIC/SWIFT:</strong> BCEELULL<br>
 
         <strong>IBAN:</strong> LU29 0019 2855 3890 4000<br>
 
         <strong>Subject:</strong> * to FVDE<br>
 
       </p>
 
       </div>
 
      </div>
 
    </div>
 
    <div class="col-md-4">
 
    <div class="col-md-4 clearfix">
 
      <div class="thumbnail">
 
        <center>
 
          <h3>SnailMail</h3>
 
        </center>
 
        <div class="well well-sm">
 
          <div class="pull-right">
 
            <form class="form-inline" role="form" method="POST" action"{{ url_for('donate.index') }}">
 
              {{ form.hidden_tag() }}
 
              <div class="form-group">
 
                {{ form.country(_class="form-class") }}
 
                {{ form.country(class_='form-control input-sm', onchange='this.form.submit()') }}
 
                <noscript><input type="submit" class="btn btn-enn btn-sm" value="Submit"></noscript>
 
              </div>
 
              <input type="submit" class="btn btn-primary btn-sm" value="Submit">
 
            </form>
 
          </div>
 
          <div class="clearfix"></div>
 
          <address>
 
            <strong>Frënn vun der Ënn, ASBL</strong><br>
 
                    BPM 381892<br>
 
                    {{ address['address'] }}<br>
 
                    {{ address['postal_code'] }}, {{ address['city'] }}<br>
 
                    {{ address['country'] }}
 
          </address>
 
        </div>
 
      </div>
 
    </div>
 
    <div class="col-md-4">
 
      <div>
 
      <div class="thumbnail">
 
        <center>
 
          <h3>Bitcoin</h3>
 
        </center>
 
        <div class="well well-sm">
 
          <p>
 
            <strong>Bitcoin Address:</strong> 1EYZCq2ZL6chWXYYkJoDo7fz39UC7do5cC
 
          </p>
 
        </div>
 
        <form class="bitpay-donate form-horizontal" action="https://bitpay.com/checkout" method="POST" onsubmit="return checkRequiredFields(this);">
 
          <input name="action" type="hidden" value="checkout">
 
          <div class="form-group">
 
            <label class="col-sm-2 control-label">Email:</label>
 
            <div class="col-sm-10">
 
              <input class="bitpay-donate-field-email form-control" name="orderID" type="email" placeholder="Email address (optional)" maxlenght=50 autocapitalize=off autocorrect=off />
 
            </div>
 
          </div>
 
          <div class="form-group">
 
            <label class="col-sm-2 control-label">Amount:</label>
 
            <div class="col-sm-10">
 
              <input class="bitpay-donate-field-price form-control" style="display: inline;" name="price" type="number" value="0.1" placeholder="Amount" maxlenght="10" min="0.000006" step="0.000001" />
 
              <select class="bitpay-donate-field-currency form-control" style="display: inline;" value="" name="currency">
 
                <option selected="selected" value="BTC">BTC</option>
 
                <option value="USD">USD</option>
 
                <option value="EUR">EUR</option>
 
                <option value="GBP">GBP</option>
 
                <option value="AUD">AUD</option>
 
                <option value="BGN">BGN</option>
 
                <option value="BRL">BRL</option>
 
                <option value="CAD">CAD</option>
 
                <option value="CHF">CHF</option>
 
                <option value="CNY">CNY</option>
 
                <option value="CZK">CZK</option>
 
                <option value="DKK">DKK</option>
 
                <option value="HKD">HKD</option>
 
                <option value="HRK">HRK</option>
 
                <option value="HUF">HUF</option>
 
                <option value="IDR">IDR</option>
 
                <option value="ILS">ILS</option>
 
                <option value="INR">INR</option>
 
                <option value="JPY">JPY</option>
 
                <option value="KRW">KRW</option>
 
                <option value="LTL">LTL</option>
 
                <option value="LVL">LVL</option>
 
                <option value="MXN">MXN</option>
 
                <option value="MYR">MYR</option>
 
                <option value="NOK">NOK</option>
 
                <option value="NZD">NZD</option>
 
                <option value="PHP">PHP</option>
 
                <option value="PLN">PLN</option>
 
                <option value="RON">RON</option>
 
                <option value="RUB">RUB</option>
 
                <option value="SEK">SEK</option>
 
                <option value="SGD">SGD</option>
 
                <option value="THB">THB</option>
 
                <option value="TRY">TRY</option>
 
                <option value="ZAR">ZAR</option>
 
              </select>
 
            </div>
 
          </div>
 
          <input type="hidden" name="data" value="k3TZs7wPLcCaurVVZ8iW/MCwDwe94LwJrA22SKBNMwOmVLQ3AAW4TncxqpNFPVNScSCIqoQR+zwgYJSRtFBFciNwQ7Ezcnqb3JptfVNnDubnNy1KVTFCYXZ8m/83aFxFC0p6Lyf07a0HCEWTBMQhmVjFLuQYSa57kYQd+fzlL+lbi5pkBW8ok884l1ELYq6W">
 
          <div class="bitpay-donate-button-wrapper form-group">
 
            <input class="bitpay-donate-button" name="submit" src="https://bitpay.com/img/donate-button.svg" onerror="this.onerror=null; this.src='https://bitpay.com/img/donate-button-md.png'" width="126" height="48" type="image" alt="BitPay, the easy way the easy way to pay with bitcoins." border="0">
 
          </div>
 
        </form>
 
      </div>
 
    </div>
 
  </div>
 
  <div class="col-md-12">
 
    <div class="col-md-4">
 
      <div class="thumbnail">
 
        <center>
 
          <h3>PayPal <small><span class="label label-danger">high fees</span></small></h3>
 
          <p>Use your existing PayPal account or check-out as guest. (Credit cards accepted)</p>
 
        <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
 
    		  <input type="hidden" name="cmd" value="_s-xclick">
 
    		  <input type="hidden" name="hosted_button_id" value="JKNKAGHS65QN4">
 
    		  <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
 
    		  <img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
 
    		</form>
 
      </center>
 
      </div>
 
    </div>
 
    <div class="col-md-4">
 
      <div class="thumbnail">
 
        <center>
 
          <h3>Flattr</h3>
 
          <p>Flattr us!</p>
 
          <a href="https://flattr.com/submit/auto?user_id=FVDE&url=https%3A%2F%2Fenn.lu/donate/flattr" target="_blank">
 
            <img src="https://button.flattr.com/flattr-badge-large.png" alt="Flattr this" title="Flattr this" border="0"></img>
 
          </a>
 
        </center>
 
      </div>
 
    </div>
 
    <div class="col-md-4">
 
      <div class="thumbnail">
 
        <center>
 
          <h3>BPM Points</h3>
 
          <p>For our parcel station and international mail boxes.</p>
 
          <div class="well well-sm">
 
            <p>
 
              Send your BPM voucher code to: <br>
 
              <abbr title="E-Mail"><span class="glyphicon glyphicon-envelope"></span></abbr> : <a href="mailto:info@enn.lu">info@enn.lu</a> <span class="glyphicon glyphicon-lock"></span> GPG: <a href="http://keyserver.cypherpunk.lu:11371/pks/lookup?search=info@enn.lu&op=vindex" target="_blank">0x02225522</a>
 
            </p>
 
          </div>
 
        </center>
 
      </div>
 
    </div>
 
  </div>
 
{% endblock %}
ennstatus/templates/donate/received.html
Show inline comments
 
{% extends "base.html" %}
 
{% import "donate/macros.html" as macros %}
 

	
 
{% set title = "Donate - Received donations" %}
 

	
 
{% block content %}
 
  <div class="col-md-12">
 
    <h2>Received Donations</h2>
 
  </div>
 
  <div class="col-md-12 clearfix">
 
    <div class="pull-left">
 
      {% if csv_file %}
 
        <h3>{{ '-'.join([year, month]) }}</h3>
 
      {% else %}
 
        <h3>Error!</h3>
 
      {% endif %}
 
    </div>
 
    <div class="pull-right">
 
      <form class="form-inline" role="form" method="POST" action="/donate/received">
 
        {{ form.hidden_tag() }}
 
        <div class="form-group">
 
          {{ form.year.label }}
 
          {{ form.year(_class="form-control") }}
 
          {{ form.year(class_='form-control input-sm') }}
 
          {{ form.month.label }}
 
          {{ form.month(_class="form-control") }}
 
          {{ form.month(class_='form-control input-sm') }}
 
          <input type="submit" class="btn btn-enn btn-sm" value="Submit">
 
        </div>
 
        <input type="submit" class="btn btn-primary btn-sm" value="Submit">
 
      </form> 
 
    </div>
 
  </div>
 
  <div class="clearfix"></div>
 
  <div class="col-md-12">
 
    {% if csv_file %}
 
      {{ macros.create_donations_table(csv_file) }}
 
    {% else %}
 
      {% if year and month %}
 
        <p>No donations found for {{ '-'.join([year, month]) }}!</p>
 
      {% else %}
 
        <p>No donations found!</p>
 
      {% endif %}
 
    {% endif %}
 
  </div>
 
{% endblock %}
ennstatus/templates/root/about.html
Show inline comments
 
{% extends "base.html" %}
 

	
 
{% set title = "Who we are" %}
 

	
 
{% block content %}
 
    <!--
 
    <div class="col-md-4 text-center">
 
      <img class="img-rounded" alt="WhoIs" src="{{ url_for('static', filename='images/WhoIs.png') }}" width="160" height="189"></img>
 
      <h3>Who we are</h3>
 
      </div> -->
 

	
 
  <div class="col-md-offset-1 col-md-11">
 
    <h2>Who we are</h2>
 
    <h3>Organization</h3>
 
    <p class="lead">
 
      <i>Frënn vun der Ënn a.s.b.l.</i> is a non-profit organization based in Luxembourg (EU).
 
      It has been founded by members of <i>Chaos Computer Club Lëtzebuerg a.s.b.l.</i> in 2013.
 
    </p>
 
    <p>
 
      As defined in the statutes (see below), the goals of our organization are:
 
      <ul>
 
        <li>defending civil rights, especially on the internet</li>
 
        <li>defending the right to anonymity on the internet by supporting Tor Project Inc.</li>
 
        <li>fighting against censorship and ensuring free access to information</li>
 
        <li>defending the freedom of expression</li>
 
        <li>protecting privacy</li>
 
        <li>promoting free software</li>
 
      </ul>
 
    </p>
 
    <p>
 
      The name <i>Frënn vun der Ënn</i> is Luxembourgish and stands for <i>Friends of the Onion</i>.
 
      The onion is used as a logo by the Tor Project Inc. and many other related organizations.
 
    </p>
 
    <h3>Administrative Council &amp; Staff</h3>
 
    <p>
 
      <dl class="dl-horizontal" >
 
        <dt>President</dt><dd>Sam Grüneisen</dd>
 
        <dt>Secretary</dt><dd>Gilles Hamen</dd>
 
        <dt>Treasurer</dt><dd>Patrick Kahr</dd>
 
        <dt>Developers</dt><dd>Dennis Fink (Ënnstatus Lead Developer), Sam Grüneisen</dd>
 
      </dl>
 
    </p>
 
    <h3>Statutes</h3>
 
    <p>Our statutes can be looked up <a href="//statutes.enn.lu">here</a>!</p>
 
  </div>
 
{% endblock %}
ennstatus/templates/root/abuse.html
Show inline comments
 
{% extends "base.html" %}
 

	
 
{% set title = "Abuse" %}
 

	
 
{% block content %}
 
  <!-- <div class="col-md-4 text-center">
 
    <img src="{{ url_for('static', filename='images/Abuse.png') }}" class="img-rounded" alt="FVDE_Logo_LQ" width="160"></img>
 
    <h2>Report Abuse!</h2>
 
  </div> -->
 
  <div class="col-md-offset-1 col-md-11">
 
    <h2>Abuse handling</h2>
 
    <p class="lead">We take our mission very seriously and carefully examine abuse cases.</p>
 
    <p>If you have any question regarding abusive traffic emanating from one of our Tor Exit nodes, don't hesitate to contact our abuse departement. Please make sure to include the following details in your enquiry:</p>
 
    <ul>
 
      <li>the offending IP address'</li>
 
      <li>the type &amp; address' of the abused service(s)</li>
 
      <li>your contact information</li>
 
    </ul><br>
 
    <p>
 
    For transparency reasons we publish monthly <a href="//{{ wiki_url }}/doku.php?id=abuse_statistics" target="blank"><strong>abuse mail statistics</strong></a>.
 
    </p>
 
    <h3>Abuse contact</h3>
 
    <address>
 
      <abbr title="E-Mail"><span class="glyphicon glyphicon-envelope"></span></abbr> : <a href="mailto:abuse@enn.lu">abuse@enn.lu</a> <span class="glyphicon glyphicon-lock"></span> GPG: <a href="http://keyserver.cypherpunk.lu:11371/pks/lookup?search=info@enn.lu&op=vindex" target="_blank">0x02225522</a>
 
    </address>
 
    <h3>RIPE Contact</h3>
 
    <p>We also have ar <a href="https://apps.db.ripe.net/search/lookup.html?source=ripe&key=FE1862-RIPE&type=PERSON">RIPE entry</a></p>
 
    <h3>Spam &amp; Trolling</h3>
 
    <p>
 
      We are receiving a lot of automatically generated messages from self-proclaimed DMCA-Ninjas. Many of those 'inquiries' don't even include basic contact information or meaningful server logs.
 
      It is not our job to process 'junk mail' or communicate with robots. Our sysadmins will take the appropriate measures to ban such 'abuse spam' from our network.
 
    </p>
 
  </div>
 
{% endblock %}
ennstatus/templates/root/bridgeprogram.html
Show inline comments
 
{% extends "base.html" %}
 

	
 
{% import 'bootstrap/wtf.html' as wtf %}
 

	
 
{% set title = "Bridge Program" %}
 

	
 
{% block content %}
 
  <div class="col-md-offset-1 col-md-10">
 
    <h2>Bridge Program</h2>
 
    <p class="lead">Fight censorship! Our bridge program allows you to support the Tor network by adopting a Tor bridge.</p>
 
    <p> Rather than making a single donation, you can now fund a Tor bridge on your own. Bridges are an important element in the Tor network because they allow people to use the network even if the direct acces to its entry-nodes is blocked in their country. This is mainly the case for people living under oppressive regimes. <a href="https://www.torproject.org/docs/bridges" target="blank"><strong>Read more about Tor bridges</strong></a></p>
 
    <p>With a recurring contribution of 3 EUR/month (duration min. 12 months) you can help us keep such a bridge up and running. The servers for this project are located in Luxembourg.</p>
 
    <p>As a partner in our project you can choose the nickname of your bridge and follow it on <a href="{{ url_for('status.index') }}">Ënnstatus</a>, our self-made information-panel.</p>
 
  </div>
 
  <div class="col-md-1">
 
  </div>
 
  <div class="col-md-offset-1 col-md-6">
 
    <h2>Apply for the bridge program</h2>
 
    <form method="post" class="form form-horizontal" role="form">
 
      {{ form.hidden_tag() }}
 
      {{ wtf.form_field(form.fullname, form_type='horizontal') }}
 
      {{ wtf.form_field(form.email, form_type='horizontal') }}
 
      {{ wtf.form_field(form.bridgename, form_type='horizontal') }}
 
      <div class="form-group {% if form.duration.errors %} has-error {% endif %} required">
 
        {{ form.duration.label(class_='control-label col-lg-2') }}
 
        <div class="col-lg-10">
 
        {% for field in form.duration %}
 
          <div class="radio">
 
            {{ field() }}
 
            <div class="btn-group">
 
              <label class="btn btn-success" for="{{ field.id }}">
 
                <span class="glyphicon glyphicon-plus"></span>
 
                <span class="glyphicon glyphicon-minus"></span>
 
              </label>
 
              <label class="btn btn-default" for="{{ field.id }}">
 
                {{ field.label.text }}
 
              </label>
 
            </div>
 
          </div>
 
        {% endfor %}
 
        </div>
 
        {% if form.duration.errors %}
 
          <div class="col-lg-offset-2 col-lg-10">
 
            {% for error in form.duration.errors %}
 
              <p class="help-block">{{ error }}</p>
 
            {% endfor %}
 
          </div>
 
        {% endif %}
 
      </div>
 
      <div class="form-group {% if form.payment.errors %} has-error {% endif %} required">
 
        {{ form.payment.label(class_='control-label col-lg-2') }}
 
        <div class="col-lg-10">
 
        {% for field in form.payment %}
 
          <div class="radio">
 
            {{ field() }}
 
            <div class="btn-group">
 
              <label class="btn btn-success" for="{{ field.id }}">
 
                <span class="glyphicon glyphicon-plus"></span>
 
                <span class="glyphicon glyphicon-minus"></span>
 
              </label>
 
              <label class="btn btn-default" for="{{ field.id }}">
 
                {{ field.label.text }}
 
              </label>
 
            </div>
 
          </div>
 
        {% endfor %}
 
        </div>
 
        {% if form.payment.errors %}
 
          <div class="col-lg-offset-2 col-lg-10">
 
            {% for error in form.payment.errors %}
 
              <p class="help-block">{{ error }}</p>
 
            {% endfor %}
 
          </div>
 
        {% endif %}
 
      </div>
 
      <div class="form-group">
 
        <div class="col-lg-offset-2 col-lg-10">
 
          {{ form.submit(class_='btn btn-primary') }}
 
          {{ form.submit(class_='btn btn-enn') }}
 
        </div>
 
      </div>
 
    </form>
 
  </div>
 
  <div class="col-md-4">
 
    <h3>More information</h3>
 
    <p>You want to know more about our work?</p>
 
    <p>Our <a href="//wiki.enn.lu/doku.php?id=user:kahpa">bridge operator</a> will give you further information about the project.</p>
 
    <p><strong>Get in touch:</strong> <abbr title="E-Mail"><span class="glyphicon glyphicon-envelope"></span></abbr> : <a href="mailto:bridges@enn.lu">bridges@enn.lu</a> <span class="glyphicon glyphicon-lock"></span> GPG: <a href="http://keyserver.cypherpunk.lu:11371/pks/lookup?op=get&search=0x3F917F479C5D0F3B">0x9C5D0F3B</a></p>
 
  </div>
 
{% endblock %}
ennstatus/templates/root/contact.html
Show inline comments
 
{% extends "base.html" %}
 

	
 
{% set title = "Contact" %}
 

	
 
{% block content %}
 
  <div class="col-md-4 text-center">
 
    <img src="{{ url_for('static', filename='images/Contact.png') }}" class="img-rounded" alt="WhoIs" width="160"></img>
 
  <div class="col-md-4">
 
    <img src="{{ url_for('static', filename='images/Contact.png') }}" class="img-responsive img-rounded center-block" alt="WhoIs" width="160"></img>
 
    <div class="text-center">
 
    <h2>Contact</h2>
 
  </div>
 
  <div class="col-md-8">
 
    <h2>General</h2>
 
  </div>
 
  <div class="col-md-8 clearfix">
 
    <h2 class="pull-left">General</h2>
 
    <div class="pull-right">
 
      <form class="form-inline" role="form" method="POST" action="{{ url_for('root.contact') }}">
 
        {{ form.hidden_tag()}}
 
        <div class="form-group">
 
          {{ form.country.label }}
 
          {{ form.country(_class="form-control") }}
 
          {{ form.country(class_='form-control input-sm', onchange='this.form.submit()') }}
 
          <noscript><input type="submit" class="btn btn-enn btn-sm" value="Submit"></noscript>
 
        </div>
 
        <input type="submit" class="btn btn-primary btn-sm" value="Submit">
 
      </form>
 
    </div>
 
    <div class="clearfix"></div>
 

	
 
  </div>
 
  <div class="col-md-8">
 
    <p>Please mail all general inquiries to:</p>
 
    <address>
 
      <strong>Frënn vun der Ënn, ASBL</strong><br>
 
        BPM 381892<br>
 
        {{ address['address'] }}<br>
 
        {{ address['postal_code'] }}, {{ address['city'] }}<br>
 
        {{ address['country'] }}<br>
 
        <br>
 
      <abbr title="E-Mail"><span class="glyphicon glyphicon-envelope"></span></abbr> : <a href="mailto:info@enn.lu">info@enn.lu</a> <span class="glyphicon glyphicon-lock"></span> GPG: <a href="http://keyserver.cypherpunk.lu:11371/pks/lookup?search=info@enn.lu&op=vindex" target="_blank">0x02225522</a><br>
 
      <abbr title="Website"><span class="glyphicon glyphicon-cloud"></span></abbr> : <a href="//enn.lu/">enn.lu/</a> <strong>or</strong> <a href="//{{ config['ENNSTATUS_ONION_ADDRESS'] }}/" target="_blank">{{ config['ENNSTATUS_ONION_ADDRESS'] }}</a><br>
 
      <abbr title="Phone"><span class="glyphicon glyphicon-earphone"></span></abbr> : +352-691-71-77-44<br>
 
      <abbr title="Fax"><span class="glyphicon glyphicon-phone-alt"></span></abbr> : +352-20-21-18-60
 
    </address>
 

	
 
    <h2>Abuse</h2>
 
    <p>For further details about abuse handling, have a look over <a href="{{ url_for('root.abuse') }}">here</a>.</p>
 
    <address>
 
      <abbr title="E-Mail"><span class="glyphicon glyphicon-envelope"></span></abbr> : <a href="mailto:abuse@enn.lu">abuse@enn.lu</a> <span class="glyphicon glyphicon-lock"></span> GPG: <a href="http://keyserver.cypherpunk.lu:11371/pks/lookup?search=info@enn.lu&op=vindex" target="_blank">0x02225522</a><br>
 
      <abbr title="Phone"><span class="glyphicon glyphicon-earphone"></span></abbr> : </strong>+352-691-71-77-44<br>
 
    </address>
 

	
 
    <h2>Press</h2>
 
    <p>Press related inqueries should go to:</p>
 
    <address>
 
      <abbr title="E-Mail"><span class="glyphicon glyphicon-envelope"></span></abbr> : <a href="mailto:press@enn.lu">press@enn.lu</a> <span class="glyphicon glyphicon-lock"></span> GPG: <a href="http://keyserver.cypherpunk.lu:11371/pks/lookup?search=info@enn.lu&op=vindex" target="_blank">0x02225522</a><br>
 
      <abbr title="Phone"><span class="glyphicon glyphicon-earphone"></span></abbr> : </strong>+352-691-71-77-44<br>
 
    </address>
 

	
 
  </div>
 
{% endblock %}
ennstatus/templates/root/index.html
Show inline comments
 
{% extends "base.html" %}
 

	
 
{% set title = "Index" %}
 

	
 
{% block styles %}
 
  {{ super() }}
 
  <link rel="stylesheet" href="{{ url_for('static', filename='js/video.js/dist/video-js.min.css') }}">
 
{% endblock %}
 

	
 
{% block content %}
 
  <div class="col-md-4 text-center">
 
    <img class="img-rounded" alt="FVDE_Logo" src="{{ url_for('static', filename='images/logo/FVDE_logo_resize.png') }}"></img>
 
  <div class="col-md-4">
 
    <img class="img-rounded center-block" alt="FVDE_Logo" src="{{ url_for('static', filename='images/logo/FVDE_logo_resize.png') }}"></img>
 
  </div>
 
  <div class="col-md-8">
 
    <div class="jumbotron">
 
      <h2>Frënn vun der Ënn A.S.B.L.</h2>
 
	    <p><em>Luxembourg based non-profit organization defending civil rights on the internet.</em></p>
 
      <p>We provide high-bandwidth Tor nodes all over the world to protect <strong>online privacy</strong>, <strong>anonymity</strong>, <strong>freedom of speech</strong> and fight <strong>censorship</strong>!
 
      </p>
 
      <h3><a href="{{ url_for('root.member') }}"><span class="label label-success">Become a Member</span></a> <a href="{{ url_for('donate.index') }}"><span class="label label-primary">Donate</span></a>
 
        <a class="pull-right" href="https://twitter.com/FrennVunDerEnn" target="blank"><span class="label label-info">@FrennVunDerEnn</span></a></h3>
 
      <span class="highlighted-label"><a href="{{ url_for('root.member') }}"><span class="label label-success">Become a Member</span></a></span>
 
      <span class="highlighted-label"><a href="{{ url_for('donate.index') }}"><span class="label label-primary">Donate</span></a></span>
 
      <span class="highlighted-label pull-right"><a href="https://twitter.com/FrennVunDerEnn" target="blank"><span class="label label-info">@FrennVunDerEnn</span></a></span>
 
    </div>
 
  </div>
 
  <div class="col-md-1">
 
  </div>
 
  <div class="col-md-8">
 
    <blockquote>
 
      <p>
 
        <em>I support <abbr title="Frënn vun der Ënn a.s.b.l.">FVDE</abbr> because even small organizations can contribute to protect fundamental civil rights. This noble goal can be pursued by making use of technology and putting knowledge to the service of users who want to maintain their privacy.</em>
 
        <footer>Georges, Teacher</footer>
 
      </p>
 
    </blockquote>
 
  </div>
 
  <div class="col-md-3">
 
    <blockquote>
 
      <a href="https://martianhumorist.me/141015-2/" target="blank"><h2 class="text-center">You have something to hide!</h2></a>
 
      <footer>The Martian Humorist</footer>
 
    </blockquote>
 
  </div>
 
  <div class="col-md-6">
 
    <p>
 
      <video id="tor-animation" width="560" height="315" controls preload="none" class="video-js vjs-default-skin vjs-big-play-centered" data-setup="">
 
    <div class="embed-responsive embed-responsive-16by9">
 
      <video id="tor-animation" width="560" height="315" controls preload="none" class="video-js vjs-default-skin vjs-big-play-centered embed-responsive-item" data-setup="">
 
        <source src="{{ url_for('static', filename='videos/Tor_Animation.webm') }}" type='video/webm' />
 
        <source src="{{ url_for('static', filename='videos/Tor_Animation.mp4') }}" type='video/mp4' />
 

	
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.de.vtt') }}" srclang="de" label="Deutsch">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.en.vtt') }}" srclang="en" label="English">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.fr.vtt') }}" srclang="fr" label="Français">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.ar.vtt') }}" srclang="ar" label="العربية">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.ca.vtt') }}" srclang="ca" label="Català">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.es.vtt') }}" srclang="es" label="Español">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.eu.vtt') }}" srclang="eu" label="Euskal">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.fa.vtt') }}" srclang="fa" label="فارسی">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.fi.vtt') }}" srclang="fi" label="Suomi">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.id.vtt') }}" srclang="id" label="Indonesian">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.it.vtt') }}" srclang="it" label="Italinao">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.lv.vtt') }}" srclang="lv" label="Latvijā">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.pl.vtt') }}" srclang="pl" label="Polskie">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.pt.vtt') }}" srclang="pt" label="Português">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.ru.vtt') }}" srclang="ru" label="русский">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.sq.vtt') }}" srclang="sq" label="Shqiptar">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.sv.vtt') }}" srclang="sv" label="Svenska">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.tl-PH.vtt') }}" srclang="tl-PH" label="Fillipino">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.zh-CN.vtt') }}" srclang="zh-CN" label="Chinese (China)">
 
        <track src="{{ url_for('static', filename='videos/subtitles/Tor_animation.zh-HK.vtt') }}" srclang="zh-HK" label="Chinese (Hongkong)">
 
      </video>
 
    </p>
 
    </div>
 
  </div>
 
  <div class="col-md-6">
 
      <p class=lead>
 
        <br>
 
        Tor is free software and an open network that helps you defend against network surveillance and preserve your personal freedom and privacy on the Internet.
 
      </p>
 
      <p>
 
        By bouncing your communications around a distributed network of relays run by volunteers all around the world, it prevents somebody watching your Internet connection from learning what sites you visit, and it prevents the sites you visit from learning your physical location.
 
      </p>
 
      <h2><a href="http://torproject.lu" target="blank"><span class="label label-info">Learn more about Tor</span></a></h2>
 
      <span class="highlighted-label-big"><a href="http://torproject.lu" target="blank"><span class="label label-info">Learn more about Tor</span></a></span>
 
  </div>
 
{% endblock %}
 

	
 
{% block scripts %}
 
  {{ super() }}
 
  <script src="{{ url_for('static', filename='js/video.js/dist/video.min.js') }}"></script>
 
  <script>
 
    videojs.options.flash.swf = "{{ url_for('static', filename='js/video.js/dist/video-js.swf') }}"
 
  </script>
 
{% endblock %}
ennstatus/templates/root/member.html
Show inline comments
 
{% extends "base.html" %}
 

	
 
{% set title = "Member" %}
 

	
 
{% block content %}
 
  <div class="col-md-4 text-center">
 
    <img src="{{ url_for('static', filename='images/Partners.png') }}" class="img-rounded" alt="Partners" width="160"></img>
 
    <h3>Join</h3>
 
  <div class="col-md-4">
 
    <img src="{{ url_for('static', filename='images/Partners.png') }}" class="img-responsive img-rounded center-block" alt="Partners" width="160"></img>
 
    <div class="text-center">
 
      <h2>Join</h2>
 
    </div>
 
  </div>
 
  <div class="col-md-8">
 
    <h2>Membership</h2>
 
    <p class="lead">Joining our organization has several advantages.</p>
 
    <p>As an active member you get to know the people behind <abbr title="Frënn vun der Enn a.s.b.l.">FVDE</abbr> and you can join us on our weekly meetings (online or AFK).
 
       You'll have the possibility to actively contribute to our projects,
 
       bring in new ideas, and eventually become a part of our core team.</p>
 

	
 
    <p>We are a dynamic group of people with different backgrounds and skills
 
       who constantly learn from each other. Most of us have a broader
 
       knowledge in Tor, network security and FOSS in general,
 
       but our activities aren't limited to technical questions alone.
 
       Regularly we meet to discuss political or philosophical questions or
 
       just have a convivial evening.</p>
 

	
 
    <p>Protecting civil liberties and human rights (such as privacy, freedom of
 
       speech, free access to information,...) is our common conviction!</p>
 

	
 
    <p>If you share our goals and are eager to socialize with like-minded
 
       people, then: Stand up for a free internet! Join us today!</p>
 

	
 
    <h3>How to become a member</h3>
 
    <p>Becoming a member is very simple. Just follow these steps:</p>
 
    <table class="table table-bordered">
 
      <thead>
 
        <tr class="info">
 
          <th>Online subscription</th>
 
          <th>PDF subscription form</th>
 
        </tr>
 
      </thead>
 
      <tbody>
 
        <tr>
 
          <td>Use the <a href="{{ url_for('root.membership') }}">online form</a>.</td>
 
          <td>Download the following <a href="{{ url_for('static', filename='files/MembershipForm.pdf') }}">membership form</a> and fill in the necessary information.</td>
 
        </tr>
 
        <tr>
 
          <td>The form will be automatically submitted. We encrypt your data with GnuPG.</td>
 
          <td>Send the membership form to one of our <a href="{{ url_for('root.contact') }}">email or snailmail</a> addresses.</td>
 
        </tr>
 
        <tr>
 
          <td colspan="2">Pay your annual membership fee. Use one of the payment methods (except <a href="{{ url_for('donate.index') }}">Flattr</a> or <a href="{{ url_for('donate.index') }}">BPM Points</a>)
 
              specified on our <a href="{{ url_for('donate.index') }}">donations</a> page. Try to include your username as a statement if possible!</td>
 
        </tr>
 
        <tr>
 
          <td colspan="2">We will get back in touch with you as soon as the payment has been completed.</td>
 
        </tr>
 
      </tbody>
 
    </table>
 
  </div>
 
{% endblock %}
ennstatus/templates/root/membership.html
Show inline comments
 
{% extends 'base.html' %}
 

	
 
{% import 'bootstrap/wtf.html' as wtf %}
 

	
 
{% set title = 'Membership' %}
 

	
 
{% block content %}
 
  <div class="col-md-12">
 
    <h2>Register as member</h2>
 
    <form method="post" class="form form-horizontal" role="form">
 
      {{ form.hidden_tag() }}
 
      {{ wtf.form_field(form.username, form_type='horizontal') }}
 
      {{ wtf.form_field(form.email, form_type='horizontal') }}
 
      {{ wtf.form_field(form.fullname, form_type='horizontal') }}
 
      {{ wtf.form_field(form.street, form_type='horizontal') }}
 
      {{ wtf.form_field(form.city, form_type='horizontal') }}
 
      {{ wtf.form_field(form.zip, form_type='horizontal') }}
 
      {{ wtf.form_field(form.country, form_type='horizontal') }}
 
      {{ wtf.form_field(form.gpg, form_type='horizontal') }}
 
      <div class="form-group {% if form.membership.errors %} has-error {% endif %} required">
 
        {{ form.membership.label(class_='control-label col-lg-2') }}
 
        <div class="col-lg-10">
 
        {% for field in form.membership %}
 
          <div class="radio">
 
            {{ field() }}
 
            <div class="btn-group">
 
              <label class="btn btn-success" for="{{ field.id }}">
 
                <span class="glyphicon glyphicon-plus"></span>
 
                <span class="glyphicon glyphicon-minus"></span>
 
              </label>
 
              <label class="btn btn-default" for="{{ field.id }}">
 
                {{ field.label.text }}
 
              </label>
 
            </div> 
 
          </div>
 
        {% endfor %}
 
        </div>
 
        {% if form.membership.errors %}
 
          <div class="col-lg-offset-2 col-lg-10">
 
            {% for error in form.membership.errors %}
 
              <p class="help-block">{{ error }}</p>
 
            {% endfor %}
 
          </div>
 
        {% endif %}
 
      </div>
 
      <div class="form-group">
 
        <label class="control-label col-lg-2">Double membership</label>
 
        <div class="col-lg-10">
 
          {{ form.c3l() }}
 
          <div class="btn-group">
 
            <label class="btn btn-success" for="c3l">
 
              <span class="glyphicon glyphicon-plus"></span>
 
              <span class="glyphicon glyphicon-minus"></span>
 
            </label>
 
            <label class="btn btn-default" for="c3l">
 
              {{ form.c3l.label.text|safe }}
 
            </label>
 
          </div>
 
        </div>
 
      </div>
 
      <div class="form-group">
 
        <div class="col-lg-offset-2 col-lg-10">
 
        {{ form.submit(class_='btn btn-primary') }}
 
        {{ form.submit(class_='btn btn-enn') }}
 
        </div>
 
      </div>
 
    </div>
 
    </form>
 
    <p>Field marked with * are required!</p>
 
    <p><sup>1</sup>: If you have decided to apply for the <i>double membership</i>, the membership fees are 150€/year for the regular
 
    membership and 70€/year for the student membership.</p>
 
  </div>
 
{% endblock %}
ennstatus/templates/root/mirrors.html
Show inline comments
 
{% extends "base.html" %}
 

	
 
{% set title = "Partners" %}
 

	
 
{% if '.onion' in request.url_root %}
 
  {% set globe_url = config['ENNSTATUS_GLOBE_ONION_ADDRESS'] %}
 
{% elif '.bit' in request.url_root %}
 
  {% set globe_url = config['ENNSTATUS_GLOBE_BIT_ADDRESS'] %}
 
{% else %}
 
  {% set globe_url = "globe.enn.lu" %}
 
{% endif %}
 

	
 
{% block content %}
 
  <div class="col-md-4 text-center">
 
    <img src="{{ url_for('static', filename='images/Services.png') }}" class="img-rounded" alt="Partners" width="160"></img>
 
    <h3>Mirrors</h3>
 
  <div class="col-md-4">
 
    <img src="{{ url_for('static', filename='images/Services.png') }}" class="img-responsive img-rounded center-block" alt="Partners" width="160"></img>
 
    <div class="text-center">
 
      <h2>Mirrors</h2>
 
    </div>
 
  </div>
 
  <div class="col-md-8">
 
    <h2>Mirrors</h2>
 
    <p class="lead">In addition to our Tor relays we are providing mirrors for some popular services.</p>
 
    <dl>
 
      <dt><a href="http://torproject.lu" target="_blank">torproject.lu</a></dt>
 
      <dd>This is a mirror of the the Tor Project's main website torproject.org</dd>
 
      <br>
 
      <dt><a href="http://tails.c3l.lu/" target="_blank">tails.enn.lu</a></dt>
 
      <dd>A Tails Download mirror. Tails is a live operating system, that you can start on almost any computer from a DVD, USB stick, or SD card. It aims at preserving your privacy and anonymity. <a href="https://tails.boum.org/" target="blank">Learn more about Tails</a></dd>
 
      <br>
 
      <dt><a href="//{{ globe_url }}" target="_blank">globe.enn.lu</a></dt>
 
      <dd>Globe is a Tor relay and bridge explorer.</dd>
 
    </dl>
 
  </div>
 
{% endblock %}
ennstatus/templates/root/partners.html
Show inline comments
 
{% extends "base.html" %}
 

	
 
{% set title = "Partners" %}
 

	
 
{% block content %}
 
  <div class="col-md-4 text-center">
 
    <img src="{{ url_for('static', filename='images/Partners.png') }}" class="img-rounded" alt="Partners" width="160"></img>
 
    <h3>Partners</h3>
 
  <div class="col-md-4">
 
    <img src="{{ url_for('static', filename='images/Partners.png') }}" class="img-responsive img-rounded center-block" alt="Partners" width="160"></img>
 
    <div class="text-center">
 
      <h2>Partners</h2>
 
    </div>
 
  </div>
 
  <div class="col-md-8">
 
    <h2>Partners</h2>
 
    <p class="lead">We are constantly looking for new partners who want join us in our endevaour for a free Internet. At the moment we are beeing supported by the following organizations:</p>
 
    <dl>
 
      <dt><a href="https://torservers.net/" target="_blank">TorServers.net</a></dt>
 
      <dd>Central information point for the international Tor operators community.</dd>
 
      <br>
 
      <dt><a href="http://c3l.lu/" target="_blank">Chaos Computer Club Lëtzebuerg</a></dt>
 
      <dd>NPO with strong interests in IT-Security, citizen rights and pivacy. Our mother organization.</dd>
 
      <br>
 
      <dt><a href="http://piratepartei.lu/" target="_blank">Piratepartei Lëtzebuerg</a></dt>
 
      <dd>The Luxembourg Pirate Party.</dd>
 
    </dl>
 

	
 
    <h3>Becoming a Partner?</h3>
 
    <p>We'd be glad to see you or your organization/company as our partner. If you are interested in supporting us by one of the following means, don't hesitate to <a href="{{ url_for('root.contact') }}">contact</a> us.
 
       <ul>
 
         <li>Traditional donations to run Tor exit nodes</li>
 
         <li>Sponsoring Servers, Bandwidth or equipment</li>
 
         <li>Helping us to spread the word about Tor and Internet privacy</li>
 
       </ul>
 
    </p>
 
  </div>
 
{% endblock %}
ennstatus/templates/root/services.html
Show inline comments
 
deleted file
ennstatus/templates/statistics/worldmap.html
Show inline comments
 
{% extends "base.html"%}
 

	
 
{% set title = "index" %}
 

	
 
{% block styles %}
 
  {{ super() }}
 
  <link rel="stylesheet" href="{{ url_for('static', filename='css/map.css') }}" />
 
{% endblock %}
 

	
 
{% block content %}
 
  <div class="col-md-12">
 
    <div id="chart">
 
    </div>
 
  </div>
 
{% endblock %}
 

	
 
{% block scripts %}
 
  {{ super() }}
 
  <script src="{{ url_for('static', filename="js/d3/d3.min.js") }}"></script>
 
  <script src="{{ url_for('static', filename="js/topojson/topojson.js") }}"></script>
 
  <script src="{{ url_for('static', filename="js/worldmap.js") }}"></script>
 
  <script src="{{ url_for('static', filename='js/d3/d3.min.js') }}"></script>
 
  <script src="{{ url_for('static', filename='js/topojson/topojson.js') }}"></script>
 
  <script src="{{ url_for('static', filename='js/worldmap.js') }}"></script>
 
{% endblock %}
ennstatus/templates/status/about.html
Show inline comments
 
deleted file
ennstatus/templates/status/macros.html
Show inline comments
 
{% macro colorize_status(status) %}
 
  {% if status %}
 
    {% set color = "text-success" %}
 
  {% elif status is none %}
 
    {% set color = "text-warning" %}
 
  {% else %}
 
    {% set color = "text-danger" %}
 
  {% endif %}
 
  <p class={{ color }}>{{ status }}</p>
 
{% endmacro %}
 

	
 
{% macro colorize_obfs(obfs) %}
 
  {% if obfs %}
 
    {% set color = "text-success" %}
 
  {% else %}
 
    {% set color = "text-danger" %}
 
  {% endif %}
 
  <p class={{ color }}>{{ obfs }}</p>
 
{% endmacro %}
 

	
 
{% macro create_country(country) %}
 
  {% set country_class = "flag-" + country|lower|replace(' ', '-') %}
 
  <i class={{ country_class }}></i> {{ country|title }}
 
{% endmacro %}
 

	
 
{% macro create_fingerprint(fingerprint, server_type) %}
 
  {% if server_type in ('exit', 'relay') %}
 
    {% set url_type = 'relay' %}
 
  {% else %}
 
    {% set url_type = 'bridge' %}
 
  {% endif %}
 
  {% if '.onion' in request.url_root %}
 
    {% set url_root = '//%s' % config['ENNSTATUS_GLOBE_ONION_ADDRESS'] %}
 
  {% elif '.bit' in request.url_root %}
 
    {% set url_root = '//%s' % config['ENNSTATUS_GLOBE_BIT_ADDRESS'] %}
 
  {% else %}
 
    {% set url_root = '//globe.enn.lu' %}
 
  {% endif %}
 
  <a href="{{ url_root }}/#/{{ url_type }}/{{ fingerprint }}">{{ fingerprint|upper}}</a>
 
{% endmacro %}
 

	
 
{% macro create_name(name) %}
 
  <a href="http://{{ name|lower }}.enn.lu">{{ name }}</a>
 
{% endmacro %}
 

	
 
{% macro create_date(date) %}
 
  {{ moment(date).format(config['ENNSTATUS_MOMENTJS_FORMAT']) }}
 
  <noscript>{{ date.strftime(config['ENNSTATUS_STRFTIME_FORMAT']) }}</noscript>
 
{% endmacro %}
 

	
 
{% macro create_server_table(server_type, servers) %}
 
  {% if server_type in ('exit', 'relay') %}
 
    {% set headers = ('#', 'Name', 'IP', 'IP6', 'Tor Status', 'Country', 'Fingerprint', 'Last Updated <noscript>(UTC)</noscript>') %}
 
  {% else %}
 
    {% set headers = ('#', 'Name', 'Tor Status', 'Country', 'Fingerprint', 'OBFS', 'FTEProxy', 'Flashproxy', 'meek', 'Last Updated <noscript>(UTC)</noscript>') %}
 
  {% endif %}
 
  <h2>{{ server_type|title }}</h2>
 
  <div class="table-responsive">
 
  <table class="table table-bordered table-striped sortable">
 
    <thead>
 
      <tr>
 
        {% for name in headers %}
 
          <th>{{ name|safe }}</th>
 
        {% endfor %}
 
      </tr>
 
    </thead>
 
    <tbody>
 
      {% for server in servers|sort(attribute='name')|sort(attribute='country') %}
 
      <tr {% if server.name in config['ENNSTATUS_BRIDGE_PROGRAM'] %}class="info"{% endif %}>
 
          <td>{{ loop.index }}</td>
 
          {% if server_type in ('exit', 'relay') %}
 
            <td>{{ create_name(server.name) }}</td>
 
            <td>{{ server.ip }}</td>
 
            <td>{{ server.ip6 or 'N/A' }}</td>
 
          {% else %}
 
            <td>
 
              {% if server.name in config['ENNSTATUS_BRIDGE_PROGRAM'] %}
 
                <a href="{{ url_for('root.bridgeprogram') }}">{{ server.name }}</a>
 
              {% else %}
 
                {{ server.name }}
 
              {% endif %}
 
            </td>
 
          {% endif %}
 
          <td>{{ colorize_status(server.status) }}</td>
 
          <td>{{ create_country(server.country) }}</td>
 
          <td>{{ create_fingerprint(server.fingerprint, server.type) }}</td>
 
          {% if server_type == 'bridge' %}
 
            <td>{{ colorize_obfs(server.obfs) }}</td>
 
            <td>{{ colorize_obfs(server.fteproxy) }}</td>
 
            <td>{{ colorize_obfs(server.flashproxy) }}</td>
 
            <td>{{ colorize_obfs(server.meek) }}</td>
 
          {% endif %}
 
          <td>{{ create_date(server.last_updated) }}
 
          </td>
 
        </tr>
 
      {% endfor %}
 
    </tbody>
 
  </table>
 
  </div>
 
  {% if server_type == 'bridge' %}
 
    <div class="alert alert-info alert-dismissible" role="alert">
 
      <button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
 
      <p>See our <a class="alert-link" href="{{ url_for('root.bridgeprogram') }}">bridge program</a>, if you want to fund some bridges!</p>
 
    </div>
 
  {% endif %}
 
{% endmacro %}
setup.py
Show inline comments
 
from setuptools import setup, find_packages
 

	
 

	
 
def _get_requirements():
 

	
 
    with open('requirements.in', encoding='utf-8') as f:
 
        lines = f.readlines()
 

	
 
    lines = [line[:-1] for line in lines if not line.startswith('#')]
 
    return lines
 

	
 

	
 
setup(name='Ennstatus',
 
      version='5.0.3',
 
      version='5.0.3-dev',
 
      description=('Ennstatus provides the user with vital information about '
 
                   'the status of the organizations Tor servers.'),
 
      author='Frënn vun der Ënn',
 
      author_email='info@enn.lu',
 
      url='https://bitbucket.org/fvde/ennstatus',
 
      license='GPLv3+',
 
      packages=find_packages(),
 
      install_requires=_get_requirements(),
 
      include_package_data=True,
 
      entry_points={
 
          'console_scripts': [
 
              'ennstatuscli = ennstatus.cli:cli',
 
          ]
 
      },
 
      classifiers=['Development Status :: 5 - Production/Stable',
 
                   'Environment :: Web Environment',
 
                   'Operating System :: POSIX',
 
                   'Programming Language :: Python',
 
                   'Programming Language :: Python :: 3',
 
                   'Programming Language :: Python :: 3.3',
 
                   'Topic :: Internet',
 
                   'Topic :: Internet :: WWW/HTTP',
 
                   'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
 
                   'Topic :: Internet :: WWW/HTTP :: WSGI',
 
                   'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
 
                   ('License :: OSI Approved :: '
 
                    'GNU General Public License v3 or later (GPLv3+)'),
 
                   ]
 
      )
0 comments (0 inline, 0 general)