140 lines
4.1 KiB
Python
Executable File
140 lines
4.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import random
|
|
import urllib
|
|
import uuid
|
|
|
|
import flask
|
|
import pony
|
|
from pony.flask import Pony
|
|
|
|
word_file = "/usr/share/dict/words"
|
|
WORDS = open(word_file).read().splitlines()
|
|
|
|
app = flask.Flask(__name__)
|
|
db = None
|
|
|
|
@app.route('/')
|
|
@pony.orm.db_session
|
|
def index():
|
|
r = flask.Response()
|
|
uid, user = get_uid(r)
|
|
negotiations = pony.orm.select(n for n in Negotiation if n.owner == user)
|
|
suggestion = suggest_unused_name()
|
|
r.data = render_page('index.html', {
|
|
'negotiations': list(negotiations),
|
|
'suggestion': suggestion,
|
|
})
|
|
return r
|
|
|
|
@pony.orm.db_session
|
|
def get_uid(r, create = True):
|
|
"""
|
|
Returns a tuple (uid, created) where created is true
|
|
if the user was new.
|
|
|
|
r is the flask response, so that the cookie uid may be set if necessary.
|
|
"""
|
|
uid = flask.request.cookies.get('uid')
|
|
if not uid:
|
|
if create:
|
|
uid = generate_uid()
|
|
r.set_cookie('uid', uid)
|
|
else:
|
|
return None, None
|
|
user = pony.orm.select(u for u in User if u.uid == uid).first()
|
|
if not user:
|
|
# Recreate the database user if it doesn't exist
|
|
user = User(uid = uid)
|
|
return uid, user
|
|
|
|
@app.route('/negotiation/create', methods = ['POST'])
|
|
@pony.orm.db_session
|
|
def negotiation_create():
|
|
n = flask.request.form.get('negotiation')
|
|
uid, user = get_uid(None, False)
|
|
if not uid or not user:
|
|
return flask.redirect('/') # @TODO Signal error to user. They don't have a uid cookie
|
|
if len(n) > 128:
|
|
return flask.redirect('/') # @TODO Signal error to user. Request too Large
|
|
if pony.orm.exists(nego for nego in Negotiation if nego.name == n):
|
|
# @TODO Signal to the user that the negotiation already exists and they
|
|
# are being sent to it instead.
|
|
return flask.redirect('/negotiations/{}'.format(n))
|
|
nego = Negotiation(name = n, owner = user.id)
|
|
pony.orm.commit()
|
|
return flask.redirect('/negotiations/{}'.format(n))
|
|
|
|
@app.route('/negotiations/')
|
|
def negotiation_redir():
|
|
return flask.redirect('/')
|
|
|
|
@app.route('/negotiations/<negotiation>')
|
|
def negotiation(negotiation):
|
|
r = flask.Response()
|
|
uid = get_uid(r)
|
|
return "{}".format(negotiation)
|
|
|
|
@pony.orm.db_session
|
|
def generate_uid():
|
|
while True:
|
|
uid = str(uuid.uuid4())
|
|
if pony.orm.exists(u for u in User if u.uid == uid):
|
|
continue
|
|
u = User(uid = uid)
|
|
pony.orm.commit()
|
|
return uid
|
|
|
|
@pony.orm.db_session
|
|
def suggest_unused_name():
|
|
tries = 0;
|
|
while True:
|
|
tries += 1
|
|
w = "{}{}{}{}".format(
|
|
random.choice(WORDS).title(),
|
|
random.choice(WORDS).title(),
|
|
random.choice(WORDS).title(),
|
|
random.choice(WORDS).title()
|
|
)
|
|
if not w.isalpha():
|
|
continue
|
|
if pony.orm.exists(n.name for n in Negotiation if n.name == w):
|
|
continue
|
|
app.logger.info('Took {} tries to generate a room suggestion'.format(tries))
|
|
return w
|
|
|
|
def render_page(template, context):
|
|
app_context = {
|
|
'LANGUAGE': flask.request.cookies.get('language')
|
|
if flask.request.cookies.get('language') else app.config['DEFAULT_LANGUAGE'],
|
|
}
|
|
context = {**context, **app_context}
|
|
return flask.render_template(template, **context)
|
|
|
|
if __name__ == '__main__':
|
|
port = os.environ.get('APP_PORT', 5000)
|
|
appkey = os.environ.get('APP_KEY', 'test')
|
|
bindaddr = os.environ.get('APP_BINDADDRESS', '127.0.0.1')
|
|
app.secret_key = appkey
|
|
app.config.update(dict(
|
|
PONY = {
|
|
'provider': 'sqlite',
|
|
'filename': 'negotiation.db',
|
|
'create_db': True,
|
|
},
|
|
DEFAULT_LANGUAGE = 'en',
|
|
))
|
|
db = pony.orm.Database()
|
|
class User(db.Entity):
|
|
uid = pony.orm.Required(str)
|
|
display_name = pony.orm.Optional(str)
|
|
negotiations = pony.orm.Set('Negotiation')
|
|
class Negotiation(db.Entity):
|
|
name = pony.orm.PrimaryKey(str)
|
|
owner = pony.orm.Required(User)
|
|
db.bind(**app.config['PONY'])
|
|
db.generate_mapping(create_tables=True)
|
|
Pony(app)
|
|
app.run(host = bindaddr, port = port)
|