Changeset - 89496c406287
[Not reviewed]
Merge v5.4.0 default
0 9 2
Dennis Fink - 9 years ago 2016-03-01 23:18:21
dennis.fink@c3l.lu
Merged dev
11 files changed with 190 insertions and 111 deletions:
0 comments (0 inline, 0 general)
README.rst
Show inline comments
 
@@ -33,49 +33,49 @@ TOC
 
Contibute
 
=========
 

	
 
Versioning
 
----------
 

	
 
This project uses the `Semantic Versioning`_ system.
 

	
 
.. _Repository:
 

	
 
Repository
 
----------
 

	
 
.. _Branch Structure:
 

	
 
Branch Structure
 
++++++++++++++++
 

	
 
The branch structure of this project is very similiar to the `git-flow`_
 
branching model, but with some modifications (we don't have release branches).
 

	
 
Description of the branches:
 

	
 
- **default**: This is the stable branch.
 
- **stable**: This is the main development branch.
 
- **dev**: This is the main development branch.
 
- **hotfix-***: These branches branch off from the default branch and are used to
 
  fix bugs which are in the stable version. They will be merged back into
 
  *default* and *dev*. After the bug is fixed, the *PATCH* number must be
 
  increased!
 
- **feature-***: In these branches, we will implement new features. These will
 
  branch off from the *dev* branch and merged back into the *dev* branch, if
 
  the feature is completed!
 

	
 
.. _Semantic Versioning: http://semver.org/
 
.. _git-flow: http://nvie.com/posts/a-successful-git-branching-model/
 

	
 
.. _Feature Requests:
 

	
 
Feature Requests
 
++++++++++++++++
 

	
 
We welcome feature requests. Please make sure they are within scope of Ënnstatus
 
goals and submit them in `Bitbucket Issues`_ with the *proposal* kind selected.
 
The more complete and compelling the request, the more likely it will be
 
implemented. Gathering community support will help as well!
 

	
 
.. _Pull Requests:
 

	
 
Pull Requests
ennstatus/__init__.py
Show inline comments
 
@@ -61,41 +61,44 @@ def create_app():
 
    app.config.from_json(config_file)
 

	
 
    app.wsgi_app = ProxyFix(app.wsgi_app)
 

	
 
    bootstrap.init_app(app)
 
    csrf.init_app(app)
 
    moment.init_app(app)
 

	
 
    from .status.functions import mail
 
    mail.init_app(app)
 

	
 
    from .root.views import root_page
 
    app.register_blueprint(root_page)
 

	
 
    from .api.views import api_page
 
    app.register_blueprint(api_page, url_prefix='/api')
 

	
 
    from .donate.views import donate_page
 
    app.register_blueprint(donate_page, url_prefix='/donate')
 

	
 
    from .status.views import status_page
 
    app.register_blueprint(status_page, url_prefix='/status')
 

	
 
    from .statistics.views import statistics_page
 
    app.register_blueprint(statistics_page, url_prefix='/stats')
 
    app.register_blueprint(statistics_page, url_prefix='/statistics')
 

	
 
    from .data.views import data_page
 
    app.register_blueprint(data_page, url_prefix='/data')
 

	
 
    from .log import init_logging
 
    init_logging(app)
 

	
 
    if 'ENNSTATUS_GPG_HOME' in app.config:
 
        gpg = gnupg.GPG(gnupghome=app.config['ENNSTATUS_GPG_HOME'])
 
        gpg.encoding = 'utf-8'
 
        app.extensions['gnupg'] = gpg
 
    else:
 
        app.extensions['gnupg'] = False
 

	
 
    @app.errorhandler(404)
 
    def page_not_found(e):
 
        return render_template('errorpages/404.html')
 

	
 
    return app
ennstatus/data/__init__.py
Show inline comments
 
new file 100644
 
# Ë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/data/views.py
Show inline comments
 
new file 100644
 
# Ë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, jsonify
 

	
 
from ennstatus.status.functions import split_all_servers_to_types
 

	
 
data_page = Blueprint('data', __name__)
 

	
 

	
 
@data_page.route('/worldmap')
 
def worldmap():
 
    servers = split_all_servers_to_types()
 
    countries = {}
 

	
 
    for key, value in servers.items():
 
        for server in value:
 
            if server.country not in countries:
 
                countries[server.country] = defaultdict(int)
 
            countries[server.country][server.type] += 1
 
            countries[server.country]['total'] += 1
 

	
 
    maximum = max(i['total'] for i in countries.values())
 

	
 
    countries['max'] = maximum
 

	
 
    return jsonify(countries)
ennstatus/static/css/map.css
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/>.
 
*/
 

	
 
.country {
 
	stroke: #000;
 
	stroke-linejoin: round;
 
	stroke-width: 0.1px;
 
}
 

	
 
.tooltip {
 
    color: #222;
 
    background: #fff;
 
    padding: .5em;
 
    text-shadow: #f5f5f5 0 1px 0;
 
    border-radius: 2px;
 
    box-shadow: 0px 0px 2px 0px #a6a6a6;
 
    opacity: 0.9;
 
    position: absolute;
 
}
ennstatus/static/js/worldmap.js
Show inline comments
 
@@ -14,121 +14,137 @@
 
   You should have received a copy of the GNU General Public License
 
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 

	
 

	
 
d3.select(window).on("resize", throttle);
 
	
 
var zoom = d3.behavior.zoom()
 
	.scaleExtent([1, 9])
 
	.on("zoom", move);
 

	
 
var width = document.getElementById('chart').offsetWidth;
 
var height = width / 2;
 

	
 
var topo, projection, path, svg, g;
 

	
 
var graticule = d3.geo.graticule();
 

	
 
var tooltip = d3.select("#chart").append("div").attr("class", "tooltip hidden");
 

	
 
setup(width, height);
 

	
 
function setup(width, height) {
 
	projection = d3.geo.mercator()
 
		.translate([(width / 2), (height / 2)])
 
		.scale(width / 2 / Math.PI)
 

	
 
	 	.translate([(width / 2), (height / 2)])
 
	 	.scale(width / 2 / Math.PI)
 
	
 
	path = d3.geo.path().projection(projection);
 

	
 
	svg = d3.select("#chart").append("svg")
 
		.attr("width", width)
 
		.attr("height", height)
 
		.call(zoom)
 
		.append("g");
 

	
 
	g = svg.append("g")
 
		.on("click", click);
 
}
 

	
 
d3.json("/static/data/world-topo-min.json", function(error, world) {
 
	var countries = topojson.feature(world, world.objects.countries).features;
 

	
 
	topo = countries;
 
	draw(topo);
 
});
 

	
 
function draw(topo) {
 

	
 
	svg.append("path")
 
		.datum(graticule)
 
		.attr("class", "graticule")
 
		.attr("d", path);
 

	
 
	g.append("path")
 
		.datum({type: "LineString", coordinates: [[-180, 0], [-90, 0], [0, 0], [90, 0], [180, 0]]})
 
		.attr("class", "equator")
 
		.attr("d", path);
 

	
 
	var country = g.selectAll(".country").data(topo);
 
	d3.json("/stats/data/worldmap", function(err, data) {
 
	d3.json("/data/worldmap", function(err, data) {
 

	
 

	
 
		var colorscale = d3.scale.threshold().domain([2, 4, 8, 16, 32, 48]).range(["#f2f0f7", "#dadaeb", "#bcbddc", "#9e9ac8", "#756bb1", "#54278f"])
 
		var colorscale = d3.scale.threshold().domain(d3.range(1, (data.max+1)/3).map(function(n) { var a=1, b=1, f=1; for(var i = 2; i <= n; i++) { f = a+b; a=b; b=f } return f;})).range([
 
			"#aeffb9",
 
			"#87ff97",
 
			"#60ff76",
 
			"#38ff54",
 
			"#11ff32",
 
			"#00e920",
 
			"#00c21b",
 
			"#009a15",
 
			"#008713",
 
			"#007310",
 
			"#00600d",
 
			"#004c0a"
 
		])
 

	
 
		country.enter().insert("path")
 
			.attr("class", "country")
 
			.attr("d", path)
 
			.attr("id", function(d, i) { return d.id; })
 
			.attr("title", function(d, i) { 
 
				if (d.properties.name in data) {
 
					return "<p>" + d.properties.name + "</p>" + data[d.properties.name];
 
				} else {
 
					return d.properties.name;
 
				}
 
			})
 
			.style("fill", function(d, i) { 
 
				if (d.properties.name in data) {
 
					return colorscale(data[d.properties.name]);
 
					return colorscale(data[d.properties.name]['total']);
 
				} else {
 
					return "#fdf6e3";
 
				}
 
			});
 

	
 
		var offsetL = document.getElementById('chart').offsetLet+20;
 
		var offsetT = document.getElementById('chart').offsetTop+10;
 
		var tooltip = d3.select('#chart').append('div')
 
			.attr('class', 'tooltip')
 

	
 
		country.on("mousemove", function(d, i) {
 
	
 
			var mouse = d3.mouse(svg.node()).map(function(d) { return parseInt(d); });
 

	
 
			tooltip.classed("hidden", false)
 
				.attr("style", "left:"+(mouse[0]+offsetL)+"px;top:"+(mouse[1]+offsetT)+"px")
 
				.html(function(d, i) {
 
				.attr("style", "left:"+(mouse[0]+40)+"px;top:"+mouse[1]+"px")
 
				.html(function() {
 
					if (d.properties.name in data) {
 
						return d.properties.name + " " + data[d.properties.name];
 
						var text = "<b>" + d.properties.name + "</b>" + "<br>Total servers: " + data[d.properties.name]['total']
 
						if ('bridge' in data[d.properties.name]) {
 
							text = text + "<br>Bridge servers: " + data[d.properties.name]['bridge']
 
						}
 
						if ('exit' in data[d.properties.name]) {
 
							text = text + "<br>Exit servers: " + data[d.properties.name]['exit']
 
						}
 
						if ('relay' in data[d.properties.name]) {
 
							text = text + "<br>Relay server: " + data[d.properties.name]['relay']
 
						}
 
						return text
 
					} else {
 
						return d.properties.name;
 
						return "<b>" + d.properties.name + "</b>"
 
					}
 
				})
 
		})
 
		.on("mouseout", function(d, i) {
 
			tooltip.classed("hidden", true);
 
		});
 

	
 

	
 
	});
 
};
 

	
 

	
 
function redraw() {
 
  width = document.getElementById('chart').offsetWidth;
 
  height = width / 2;
 
  d3.select('svg').remove();
 
  setup(width,height);
 
  draw(topo);
 
}
 

	
 

	
 
function move() {
 

	
 
  var t = d3.event.translate;
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
 
from flask import Blueprint, render_template
 

	
 
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/templates/base.html
Show inline comments
 
@@ -87,48 +87,54 @@
 
          </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>
 
        <li class="dropdown">
 
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Statistics <b class="caret"></b></a>
 
          <ul class="dropdown-menu">
 
            <li><a href="{{ url_for('statistics.worldmap') }}">Worldmap</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 class="col-md-12">
 
    <hr style="margin-bottom: 0.5%;">
 
    <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>
ennstatus/templates/donate/index.html
Show inline comments
 
@@ -90,126 +90,130 @@
 
                {{ form.country(class_='form-control input-sm', onchange='this.form.submit()') }}
 
                <noscript>{{ form.submit(class_='btn btn-enn btn-sm') }}</noscript>
 
              </div>
 
            </form>
 
          </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 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 />
 
          <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>
 
          <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 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>
 
          </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>
 
            <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>
 
  <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 class="well well-sm">
 
            <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>
 
          </div>
 
        </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>
 
          <div class="well well-sm">
 
            <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>
 
          </div>
 
        </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>For our parcel station and international mail boxes.</p>
 
            <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/statistics/worldmap.html
Show inline comments
 
@@ -5,35 +5,36 @@
 
   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/>.
 
#}
 

	
 
{% 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">
 
    <h2>Worldmap</h2>
 
    <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>
 
{% endblock %}
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.3.1',
 
      version='5.4.0',
 
      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',
0 comments (0 inline, 0 general)