pypsyc/mjacob2/pypsyc/server/webif/__init__.py

118 lines
3.5 KiB
Python

"""
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)