You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
11 KiB
309 lines
11 KiB
# all the imports |
|
import os |
|
import sqlite3 |
|
from flask import Flask, request, g, redirect, url_for, abort, \ |
|
render_template, flash, session |
|
import random |
|
from datetime import datetime, timedelta |
|
|
|
# create our little application :) |
|
app = Flask(__name__) |
|
app.config.from_object(__name__) |
|
|
|
# Load default config and override config from an environment variable |
|
app.config.update(dict( |
|
DATABASE = os.path.join(app.root_path, 'nfgame.db'), |
|
TAGS = {'taghash1': 'tagname1', |
|
'taghash2': 'tagname2', |
|
'taghash3': 'tagname3', |
|
'taghash4': 'tagname4' |
|
}, |
|
START_KEY = 'None', |
|
MAX_TIME = '3600', |
|
SHOW_TIME = '120', |
|
REFRESH_TIME = '10', |
|
SHORT_VIEW = 'false', |
|
SECRET_KEY = 'Very secret key!', |
|
ADMIN_PASSWORD = 'changeme!' |
|
)) |
|
app.config.from_envvar('NFGAME_SETTINGS', silent=True) |
|
app.secret_key = app.config['SECRET_KEY'] |
|
|
|
def connect_db(): |
|
"""Connects to the database.""" |
|
rv = sqlite3.connect(app.config['DATABASE']) |
|
rv.row_factory = sqlite3.Row |
|
return rv |
|
|
|
def init_db(): |
|
db = get_db() |
|
with app.open_resource('schema.sql', mode='r') as f: |
|
db.cursor().executescript(f.read()) |
|
db.commit() |
|
|
|
@app.cli.command('initdb') |
|
def initdb_command(): |
|
"""Initializes the database.""" |
|
init_db() |
|
print 'Initialized the database.' |
|
|
|
def get_db(): |
|
"""Opens a new database connection if there is none yet for the |
|
current application context. |
|
""" |
|
if not hasattr(g, 'sqlite_db'): |
|
g.sqlite_db = connect_db() |
|
return g.sqlite_db |
|
|
|
@app.teardown_appcontext |
|
def close_db(error): |
|
"""Closes the database again at the end of the request.""" |
|
if hasattr(g, 'sqlite_db'): |
|
g.sqlite_db.close() |
|
|
|
@app.route('/') |
|
def index(): |
|
'''Check if user is returning''' |
|
if not 'board' in session: |
|
session['board'] = 'scoreboard' |
|
|
|
if session['board'] == 'scoreboard': |
|
session['board'] = 'highscores' |
|
return scoreboard() |
|
elif session['board'] == 'highscores': |
|
session['board'] = 'scoreboard' |
|
return highscores() |
|
|
|
@app.route('/scoreboard') |
|
def scoreboard(): |
|
"""Calculate starttime""" |
|
now = datetime.now() - timedelta(seconds=int(app.config['MAX_TIME'])) - timedelta(seconds=int(app.config['SHOW_TIME'])) |
|
maxstarttime = datetime.strptime((str(now.year)+"-"+str(now.month)+"-"+str(now.day)+" "+str(now.hour)+":"+str(now.minute)+":"+str(now.second)), "%Y-%m-%d %H:%M:%S") |
|
|
|
db = get_db() |
|
cur = db.execute('select * from score where starttime > ? order by duration asc', [maxstarttime]) |
|
entries = cur.fetchall() |
|
|
|
user = {} |
|
tags = app.config['TAGS'] |
|
timeremaining = {} |
|
tagcount = {} |
|
tagcount['total'] = len(tags) |
|
|
|
for entry in entries: |
|
if entry['tags'] == None: |
|
found_tags = [] |
|
else: |
|
found_tags = entry['tags'].split(',') |
|
|
|
user[entry['id']] = {} |
|
counter = 0 |
|
|
|
for tag in tags: |
|
user[entry['id']][tag] = 'Not' |
|
for found_tag in found_tags: |
|
if found_tag == tag: |
|
user[entry['id']][tag] = 'Found' |
|
counter = counter + 1 |
|
|
|
tagcount[entry['id']] = counter |
|
|
|
'''Calculate time remaining''' |
|
starttime = datetime.strptime(entry['starttime'], "%Y-%m-%d %H:%M:%S") |
|
endtime = starttime + timedelta(seconds=int(app.config['MAX_TIME'])) |
|
playtime = endtime - datetime.now() |
|
if datetime.now() > endtime: |
|
timeremaining[entry['id']] = "Time's up" |
|
else: |
|
hours = playtime.seconds / 3600 |
|
minutes = (playtime.seconds - (hours * 3600)) / 60 |
|
seconds = playtime.seconds - (minutes * 60) |
|
if len(str(minutes)) == 1: |
|
minutes = '0' + str(minutes) |
|
if len(str(seconds)) == 1: |
|
seconds = '0' + str(seconds) |
|
timeremaining[entry['id']] = str(hours) + ":" + str(minutes) + ":" + str(seconds) |
|
|
|
return render_template('overview.html', entries=entries, tags=app.config['TAGS'], user=user, type='Current players', refresh=app.config['REFRESH_TIME'], timeremaining=timeremaining, shortview=app.config['SHORT_VIEW'], tagcount=tagcount) |
|
|
|
@app.route('/highscores') |
|
def highscores(): |
|
tagquery = "" |
|
for tag in app.config['TAGS']: |
|
if tagquery == "": |
|
tagquery = 'where tags like "%' + tag + '%"' |
|
else: |
|
tagquery = tagquery + ' and tags like "%' + tag + '%"' |
|
|
|
db = get_db() |
|
cur = db.execute('select * from score ' + tagquery + ' order by duration asc') |
|
entries = cur.fetchall() |
|
|
|
user = {} |
|
tags = app.config['TAGS'] |
|
|
|
for entry in entries: |
|
if entry['tags'] == None: |
|
found_tags = [] |
|
else: |
|
found_tags = entry['tags'].split(',') |
|
|
|
user[entry['id']] = {} |
|
|
|
for tag in tags: |
|
user[entry['id']][tag] = 'Not' |
|
for found_tag in found_tags: |
|
if found_tag == tag: |
|
user[entry['id']][tag] = 'Found' |
|
|
|
return render_template('highscores.html', entries=entries, tags=app.config['TAGS'], user=user, type='Highscores', refresh=app.config['REFRESH_TIME']) |
|
|
|
@app.route('/newuser/', methods=['GET', 'POST']) |
|
@app.route('/newuser/<string:newhash>/', methods=['GET', 'POST']) |
|
def new_user(newhash='None'): |
|
"""Check if there is a key to the new user""" |
|
if not app.config['START_KEY'] == 'None': |
|
if not newhash == app.config['START_KEY']: |
|
return redirect(url_for('index')) |
|
|
|
"""If it's a GET request, no new user should be made""" |
|
if request.method == 'GET': |
|
return render_template('newuser.html', newhash=newhash) |
|
|
|
"""Now we got a POST request""" |
|
|
|
now = datetime.now() |
|
time = datetime.strptime((str(now.year)+"-"+str(now.month)+"-"+str(now.day)+" "+str(now.hour)+":"+str(now.minute)+":"+str(now.second)), "%Y-%m-%d %H:%M:%S") |
|
|
|
"""Check for unique username""" |
|
db = get_db() |
|
cur = db.execute('select count(username) as count from score where username = ? COLLATE NOCASE', [request.form['username']]) |
|
usercount = cur.fetchone() |
|
|
|
if not usercount['count'] == 0: |
|
return render_template('newuser.html', newhash=newhash, msg='Username already taken!') |
|
|
|
db = get_db() |
|
cur = db.execute("insert into score (username,starttime,duration) values (?, ?, ?)", [request.form['username'], time, '99:99:99']) |
|
db.commit() |
|
session['username'] = request.form['username'] |
|
|
|
db = get_db() |
|
cur = db.execute('select * from score where username = ?', [session['username']]) |
|
entries = cur.fetchall() |
|
session['id'] = entries[0]['id'] |
|
|
|
if not 'tag' in session: |
|
return render_template('newuser_done.html') |
|
else: |
|
return redirect(url_for('tag_found', taghash=session['tag'])) |
|
|
|
@app.route('/tag/<string:taghash>') |
|
def tag_found(taghash): |
|
session.pop('tag', None) |
|
|
|
if not 'id' in session: |
|
'''If a user does not require central registration show new user form''' |
|
if app.config['START_KEY'] == 'None': |
|
session['tag'] = taghash |
|
return redirect(url_for('new_user')) |
|
else: |
|
return render_template('gotoregistration.html', registration=app.config['REGISTRATION_DESK'], color='#FF9999') |
|
|
|
tags = app.config['TAGS'] |
|
|
|
if not tags.has_key(taghash): |
|
return render_template('tagnotfound.html', color='#FF9999') |
|
|
|
db = get_db() |
|
cur = db.execute('select * from score where id = ?', [session['id']]) |
|
entries = cur.fetchall() |
|
|
|
if not entries: |
|
session['tag'] = taghash |
|
return redirect(url_for('new_user')) |
|
|
|
'''Calculate duration''' |
|
starttime = datetime.strptime(entries[0]['starttime'], "%Y-%m-%d %H:%M:%S") |
|
now = datetime.now() |
|
lasttime = datetime.strptime((str(now.year)+"-"+str(now.month)+"-"+str(now.day)+" "+str(now.hour)+":"+str(now.minute)+":"+str(now.second)), "%Y-%m-%d %H:%M:%S") |
|
|
|
timediff = lasttime - starttime |
|
hours = timediff.seconds / 3600 |
|
minutes = (timediff.seconds - (hours * 3600)) / 60 |
|
seconds = timediff.seconds - (minutes * 60) |
|
if len(str(minutes)) == 1: |
|
minutes = '0' + str(minutes) |
|
if len(str(seconds)) == 1: |
|
seconds = '0' + str(seconds) |
|
time = str(hours) + ":" + str(minutes) + ":" + str(seconds) |
|
|
|
if int(timediff.seconds) > int(app.config['MAX_TIME']): |
|
return render_template('timeout.html', color='#FF9999') |
|
|
|
'''Calculate time remaining''' |
|
endtime = starttime + timedelta(seconds=int(app.config['MAX_TIME'])) |
|
playtime = endtime - now |
|
hours = playtime.seconds / 3600 |
|
minutes = (playtime.seconds - (hours * 3600)) / 60 |
|
seconds = playtime.seconds - (minutes * 60) |
|
if len(str(minutes)) == 1: |
|
minutes = '0' + str(minutes) |
|
if len(str(seconds)) == 1: |
|
seconds = '0' + str(seconds) |
|
timeremaining = str(hours) + ":" + str(minutes) + ":" + str(seconds) |
|
|
|
cur_score = entries[0]['tags'] |
|
if cur_score == None: |
|
cur_score = taghash |
|
else: |
|
found_tags = cur_score.split(',') |
|
for found_tag in found_tags: |
|
if taghash == found_tag: |
|
return render_template('tagalreadyfound.html', tagname=tags.get(taghash), color='#FFFF80', time=timeremaining) |
|
break |
|
|
|
cur_score = cur_score + "," + taghash |
|
|
|
db = get_db() |
|
cur = db.execute('update score set tags = ?, lasttime = datetime(), duration = ? where id = ?', [cur_score, time, session['id']]) |
|
db.commit() |
|
|
|
'''Check if this was the user his last item''' |
|
tagquery = "" |
|
for tag in app.config['TAGS']: |
|
if tagquery == "": |
|
tagquery = 'where tags like "%' + tag + '%"' |
|
else: |
|
tagquery = tagquery + ' and tags like "%' + tag + '%"' |
|
|
|
db = get_db() |
|
cur = db.execute('select * from score ' + tagquery + ' and id = ?', [session['id']]) |
|
entries = cur.fetchall() |
|
|
|
if entries: |
|
return render_template('tagfound.html', tagname=tags.get(taghash), color='#00FF00', time=timeremaining, endgame='yes') |
|
else: |
|
return render_template('tagfound.html', tagname=tags.get(taghash), color='#00FF00', time=timeremaining, endgame='no') |
|
|
|
@app.route('/admin/<string:password>') |
|
def admin_page(password): |
|
if password == app.config['ADMIN_PASSWORD']: |
|
session['admin'] = 'true' |
|
return render_template('admin_page.html') |
|
else: |
|
return redirect(url_for('index')) |
|
|
|
@app.route('/deletescore') |
|
def delete_score(): |
|
if 'admin' in session and session['admin'] == 'true': |
|
db = get_db() |
|
cur = db.execute("delete from score") |
|
db.commit() |
|
|
|
return render_template('admin_page.html') |
|
else: |
|
return redirect(url_for('index')) |
|
|
|
if __name__ == '__main__': |
|
app.run(threaded=True)
|
|
|