diff --git a/mirror.i2p2/app.py b/mirror.i2p2/app.py index 7c7a9e7aa75d6a5677b6bacda9d20898e33e6aae..6672ce0e5c1fc10a570282d53c356d4f7ce46076 100644 --- a/mirror.i2p2/app.py +++ b/mirror.i2p2/app.py @@ -1,33 +1,77 @@ -from werkzeug import BaseRequest, BaseResponse, run_simple -from werkzeug.exceptions import HTTPException -from werkzeug.routing import RequestRedirect +from flask import Flask, redirect, request, render_template, abort from random import randint +from sys import argv +import json -class Request(BaseRequest): - """Useful subclass of the default request that knows how to build urls.""" +# try to create an memcache client +if len(argv[3:]) > 0: + try: + try: + from cmemcache import Client + except ImportError: + from memcache import Client + client=Client(argv[3:]) + except ImportError: + client=None - def __init__(self, environ): - BaseRequest.__init__(self, environ) +# create application +app=Flask(__name__) +# extract domain +domain=argv[1] -class Response(BaseResponse): - """Subclass of base response that has a default mimetype of text/html.""" - default_mimetype = 'text/html' +# extract port +port=int(argv[2]) def read_mirrors(): file = open('mirrors', 'r') dat = file.read() file.close() - return dat.split('\n') + lines=dat.split('\n') + ret={} + for line in lines: + try: + obj=json.loads(line) + except ValueError: + pass + if 'protocol' not in obj: + continue + protocol=obj['protocol'] + if protocol not in ret: + ret[protocol]=[] + ret[protocol].append(obj) + return ret -def app(environ, start_response): - """The WSGI application that connects all together.""" - req = Request(environ) - mirrors = read_mirrors() - mirror = mirrors[randint(0, len(mirrors) - 1)] - resp = RequestRedirect(mirror % req.path) - return resp(environ, start_response) +@app.route('/') +def index(): + return redirect('http://www.%s/download' % domain) + +@app.route('/select/<path:f>') +def select(f): + mirrors=read_mirrors() + obj=[] + for protocol in mirrors.keys(): + a={} + a['name']=protocol.upper() + a['mirrors']=mirrors[protocol] + for mirror in a['mirrors']: + mirror['url']=mirror['url'] % f + obj.append(a) + return render_template('select.html', mirrors=obj, file=f, domain=domain) + +@app.route('/<protocol>/<path:f>') +def get(protocol, f): + mirrors=read_mirrors() + if not protocol in mirrors: + abort(404) + mirrors=mirrors[protocol] + return redirect(mirrors.keys()[randint(0, len(mirrors.keys()) - 1)] % f) + +@app.route('/<f>') +def old_get(f): + return redirect('http://i2p.googlecode.com/files/%s' % f) if __name__ == '__main__': - run_simple('localhost', 5008, app) + app.debug=True + app.run(port=port) diff --git a/mirror.i2p2/mirror.god b/mirror.i2p2/mirror.god new file mode 100644 index 0000000000000000000000000000000000000000..35db886a59cef1759f54b680c89917b2b01c09ae --- /dev/null +++ b/mirror.i2p2/mirror.god @@ -0,0 +1,40 @@ + +DOMAINS.keys.each do |domain| + God.watch do |w| + w.name="i2p-mirror-#{domain}" + w.interval=30.seconds + w.start="/usr/bin/env python app.py #{domain} #{DOMAINS[domain][:port]}" + w.start_grace=10.seconds + w.restart_grace=10.seconds + w.dir=WDIR + + w.start_if do |start| + start.condition(:process_running) do |c| + c.interval=5.seconds + c.running=false + end + end + w.restart_if do |restart| + restart.condition(:memory_usage) do |c| + c.above=210.megabytes + c.times=[3,5] # 3 out of 5 intervals + end + restart.condition(:cpu_usage) do |c| + c.above=90.percent + c.times=7 + end + end + + w.lifecycle do |on| + on.condition(:flapping) do |c| + c.to_state = [:start, :restart] + c.times=5 + c.within=5.minute + c.transition=:unmonitored + c.retry_in=10.minutes + c.retry_times=5 + c.retry_within=2.hours + end + end + end +end diff --git a/mirror.i2p2/mirrors b/mirror.i2p2/mirrors index 9229e880311703cd86d16fefd9452f6a1d50e50e..5afeaf675e90ca7c730fa7c7937e7a075555244d 100644 --- a/mirror.i2p2/mirrors +++ b/mirror.i2p2/mirrors @@ -1 +1,2 @@ -http://i2p.googlecode.com/files%s \ No newline at end of file +{"url": "http://golden.mtveurope.org/~yang/i2p_mirror/%s", "org": "VServer.si", "org_url": "http://www.vserver.si", "protocol": "http", "country": "lu"} +{"url": "http://a.mirror.geti2p.net/releases/current/%s", "org": "welterde", "protocol": "http", "country": "de"} \ No newline at end of file diff --git a/mirror.i2p2/static/images/i2plogo.png b/mirror.i2p2/static/images/i2plogo.png new file mode 100644 index 0000000000000000000000000000000000000000..f7beff26bac365f3b7a6fd6e2bbbe52ed5d61c32 Binary files /dev/null and b/mirror.i2p2/static/images/i2plogo.png differ diff --git a/mirror.i2p2/templates/select.html b/mirror.i2p2/templates/select.html new file mode 100644 index 0000000000000000000000000000000000000000..fc031ca1c10399e5e642c5432e7d20f8ad47d0f9 --- /dev/null +++ b/mirror.i2p2/templates/select.html @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" + "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" > + <head> + <title>I2P - Mirror selection - /{{ file }}</title> + <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}" type="text/css"> + </head> + <body> + <div class="logo"> + <a href="{{ domain }}" class="fade"><img src="{{ url_for('static', filename='images/i2plogo.png') }}" alt="I2P Logo" title="Invisible Internet Project (I2P)" /></a> + </div> + <div class="header"> + <h1>Mirror selection</h1> + <h2>File: /{{ file }}</h2> + </div> + {% for protocol in mirrors -%} + <div class="protocol"> + <h3>{{ protocol.name }}</h3> + <ul> + {% for mirror in protocol.mirrors -%} + <li><a href="{{ mirror.url }}">{{ mirror.url }}</a> {% if mirror.org_url %}<a href="{{ mirror.org_url }}">{% endif %}{{ mirror.org }}{% if mirror.org_url %}</a>{% endif %}</li> + {% endfor %} + </ul> + </div> + {%- endfor %} + </body> +</html> + diff --git a/run.god.example b/run.god.example new file mode 100644 index 0000000000000000000000000000000000000000..ba161c1296a054bca345b1b3c13c290d52e83d0b --- /dev/null +++ b/run.god.example @@ -0,0 +1,5 @@ +God.pid_file_directory='/home/i2p/pids' +DOMAINS={ + 'i2p2.de' => {:port => 8090}, + 'geti2p.net' => {:port => 8091}, + 'i2project.