""" pypsyc.server.webif ~~~~~~~~~~~~~~~~~~~ :copyright: 2010 by Manuel Jacob :license: MIT """ from collections import MutableMapping from logging import getLogger from os import urandom from sqlite3 import IntegrityError from flask import Flask, request, flash, url_for, redirect, render_template from greenlet import greenlet from twisted.internet import reactor from twisted.web.server import Site from twisted.web.wsgi import WSGIResource log = getLogger(__name__) app = Flask(__name__) app.jinja_env.trim_blocks = True @app.route('/') def index(): return render_template('index.html') @app.route('/register', methods=['GET', 'POST']) def register(): error = None if request.method == 'POST': username = request.form.get('username') password = request.form.get('password') password2 = request.form.get('password2') if not username: error = 'please specify a valid username' elif '~' + username in server.root.children: error = 'username already in use' elif not password or len(password) < 6: error = 'your password must have at least 6 characters' elif password != password2: error = 'the two passwords do not match' else: server.register_person(username, password) flash("you were registered") return redirect(url_for('index')) return render_template('register.html', error=error) class PersistentStore(MutableMapping): def __init__(self): server.database.execute('CREATE TABLE IF NOT EXISTS webif_store (' 'key TEXT, value BLOB, PRIMARY KEY (key))') def __getitem__(self, key): sql = 'SELECT value FROM webif_store WHERE key = ?' ret = server.database.fetch(sql, key) if not ret: raise KeyError return ret[0][0] def __setitem__(self, key, value): try: sql = 'INSERT INTO webif_store VALUES (?, ?)' server.database.execute(sql, key, value) except IntegrityError: sql = 'UPDATE webif_store SET value = ? WHERE key = ?' server.database.execute(sql, value, key) def __delitem__(self, key): server.database.execute('DELETE FROM webif_store WHERE key = ?', key) def __iter__(self): sql = 'SELECT key FROM webif_store' return (ret[0] for ret in server.database.fetch(sql)) def __len__(self): return server.database.fetch('SELECT count(*) FROM webif_store')[0][0] class _Reactor(object): def callFromThread(self, f, *args, **kwds): f(*args, **kwds) class _Threadpool(object): def callInThread(self, f, *args, **kwds): greenlet(f).switch(*args, **kwds) def run_webif(server_, interface, port, context_factory): global server server = server_ global store store = PersistentStore() try: app.secret_key = store['secret_key'] except: app.secret_key = store['secret_key'] = urandom(20) assert len(app.secret_key) == 20 site = Site(WSGIResource(_Reactor(), _Threadpool(), app.wsgi_app)) if context_factory is None: log.warning("listening on localhost because ssl is disabled") reactor.listenTCP(port, site, interface='localhost') else: reactor.listenSSL(port, site, context_factory, interface=interface) if __name__ == '__main__': # pragma: no cover from minimock import Mock server = Mock('server') server.root.children = {} app.debug = True app.secret_key='debug key' app.run(port=8080)