diff --git a/app.py b/app.py index 0726ef9..2e5a7f6 100644 --- a/app.py +++ b/app.py @@ -1,9 +1,12 @@ #!/usr/bin/env python3 +import base64 import bcrypt +import hashlib import config import json import re +import requests import schema import os @@ -28,10 +31,34 @@ db = client[config.MONGO['database']] db.users.create_index('username', unique=True) db.songs.create_index('id', unique=True) + +class HashException(Exception): + pass + + def api_error(message): return jsonify({'status': 'error', 'message': message}) +def generate_hash(id, form): + md5 = hashlib.md5() + if form['type'] == 'tja': + urls = ['%s%s/main.tja' % (config.SONGS_BASEURL, id)] + else: + urls = [] + for diff in ['easy', 'normal', 'hard', 'oni', 'ura']: + if form['course_' + diff]: + urls.append('%s%s/%s.osu' % (config.SONGS_BASEURL, id, diff)) + + for url in urls: + resp = requests.get(url) + if resp.status_code != 200: + raise Exception('Invalid response from %s (status code %s)' % (resp.url, resp.status_code)) + md5.update(resp.content) + + return base64.b64encode(md5.digest())[:-2].decode('utf-8') + + def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): @@ -69,7 +96,8 @@ def get_config(): 'songs_baseurl': config.SONGS_BASEURL, 'assets_baseurl': config.ASSETS_BASEURL, 'email': config.EMAIL, - 'accounts': config.ACCOUNTS + 'accounts': config.ACCOUNTS, + 'custom_js': config.CUSTOM_JS } if not config_out.get('songs_baseurl'): @@ -218,6 +246,14 @@ def route_admin_songs_id_post(id): output['preview'] = float(request.form.get('preview')) or None output['volume'] = float(request.form.get('volume')) or None output['maker_id'] = int(request.form.get('maker_id')) or None + output['hash'] = request.form.get('hash') + + if request.form.get('gen_hash'): + try: + output['hash'] = generate_hash(id, request.form) + except HashException as e: + flash('An error occurred: %s' % str(e), 'error') + return redirect('/admin/songs/%s' % id) db.songs.update_one({'id': id}, {'$set': output}) flash('Changes saved.') diff --git a/config.example.py b/config.example.py index 1fa4fc7..478aa77 100644 --- a/config.example.py +++ b/config.example.py @@ -10,9 +10,12 @@ EMAIL = 'taiko@example.com' # Whether to use the user account system. ACCOUNTS = True +# Custom JavaScript file to load with the simulator. +CUSTOM_JS = '' + # MongoDB server settings. MONGO = { - 'host': ['localhost:27017'], + 'host': ['127.0.0.1:27017'], 'database': 'taiko' } diff --git a/public/src/css/admin.css b/public/src/css/admin.css index 69bb27c..033bb42 100644 --- a/public/src/css/admin.css +++ b/public/src/css/admin.css @@ -131,6 +131,10 @@ h1 small { color: white; } +.message-error { + background: #b92222; +} + .save-song { font-size: 22pt; width: 120px; diff --git a/templates/admin.html b/templates/admin.html index e92ff9a..6080e06 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -13,7 +13,7 @@ Songs - +
{% block content %}{% endblock %} diff --git a/templates/admin_song_detail.html b/templates/admin_song_detail.html index 27132f3..9c860ae 100644 --- a/templates/admin_song_detail.html +++ b/templates/admin_song_detail.html @@ -1,8 +1,8 @@ {% extends 'admin.html' %} {% block content %}

{{ song.title }} (ID: {{ song.id }})

-{% for message in get_flashed_messages() %} -
{{ message }}
+{% for cat, message in get_flashed_messages(with_categories=true) %} +
{{ message }}
{% endfor %}
@@ -115,6 +115,11 @@
+
+

+ +
+ {% if admin.user_level >= 100 %} @@ -124,3 +129,4 @@ {% endif %}
{% endblock %} +