diff --git a/backend/app/database.py b/backend/app/database.py index a6d36f8..4cae8a2 100644 --- a/backend/app/database.py +++ b/backend/app/database.py @@ -4,16 +4,18 @@ import sqlite3 import pandas from io import StringIO -song_table = "songs" +song_table = "songs" entry_table = "entries" index_label = "Id" -done_table = "done_songs" +done_table = "done_songs" + def open_db(): conn = sqlite3.connect("/tmp/karaoqueue.db") conn.execute('PRAGMA encoding = "UTF-8";') return conn + def import_songs(song_csv): print("Start importing Songs...") df = pandas.read_csv(StringIO(song_csv), sep=';') @@ -25,12 +27,13 @@ def import_songs(song_csv): num_songs = cur.fetchone()[0] conn.close() print("Imported songs ({} in Database)".format(num_songs)) - return("Imported songs ({} in Database)".format(num_songs)) + return("Imported songs ({} in Database)".format(num_songs)) + def create_entry_table(): conn = open_db() conn.execute('CREATE TABLE IF NOT EXISTS '+entry_table + - ' (ID INTEGER PRIMARY KEY NOT NULL, Song_Id INTEGER NOT NULL, Name VARCHAR(255))') + ' (ID INTEGER PRIMARY KEY NOT NULL, Song_Id INTEGER NOT NULL, Name VARCHAR(255), Client_Id VARCHAR(36))') conn.close() @@ -40,6 +43,7 @@ def create_done_song_table(): ' (Song_Id INTEGER PRIMARY KEY NOT NULL, Plays INTEGER)') conn.close() + def create_song_table(): conn = open_db() conn.execute("CREATE TABLE IF NOT EXISTS \""+song_table+"""\" ( @@ -55,6 +59,7 @@ def create_song_table(): )""") conn.close() + def create_list_view(): conn = open_db() conn.execute("""CREATE VIEW IF NOT EXISTS [Liste] AS @@ -72,6 +77,7 @@ def create_done_song_view(): WHERE done_songs.Song_Id=songs.Id""") conn.close() + def get_list(): conn = open_db() conn.row_factory = sqlite3.Row @@ -86,35 +92,40 @@ def get_played_list(): cur.execute("SELECT * FROM Abspielliste") return cur.fetchall() + def get_song_list(): - conn =open_db() + conn = open_db() cur = conn.cursor() cur.execute("SELECT Artist || \" - \" || Title AS Song, Id FROM songs;") return cur.fetchall() + def get_song_completions(input_string): conn = open_db() cur = conn.cursor() # Don't look, it burns... - prepared_string = "%{0}%".format(input_string).upper() # "Test" -> "%TEST%" + prepared_string = "%{0}%".format( + input_string).upper() # "Test" -> "%TEST%" print(prepared_string) cur.execute( "SELECT Title || \" - \" || Artist AS Song, Id FROM songs WHERE REPLACE(REPLACE(REPLACE(REPLACE(UPPER( SONG ),'ö','Ö'),'ü','Ü'),'ä','Ä'),'ß','ẞ') LIKE (?) LIMIT 20;", (prepared_string,)) return cur.fetchall() -def add_entry(name,song_id): + +def add_entry(name, song_id, client_id): conn = open_db() cur = conn.cursor() cur.execute( - "INSERT INTO entries (Song_Id,Name) VALUES(?,?);", (song_id,name)) + "INSERT INTO entries (Song_Id,Name,Client_Id) VALUES(?,?,?);", (song_id, name, client_id)) conn.commit() conn.close() return + def add_sung_song(entry_id): conn = open_db() cur = conn.cursor() - cur.execute("""SELECT Song_Id FROM entries WHERE Id=?""",(entry_id,)) + cur.execute("""SELECT Song_Id FROM entries WHERE Id=?""", (entry_id,)) song_id = cur.fetchone()[0] cur.execute("""INSERT OR REPLACE INTO done_songs (Song_Id, Plays) VALUES("""+str(song_id)+""", @@ -127,6 +138,19 @@ def add_sung_song(entry_id): conn.close() return True + +def check_entry_quota(client_id): + conn = open_db() + cur = conn.cursor() + cur.execute("SELECT Count(*) FROM entries WHERE entries.Client_Id = ?", (client_id,)) + return cur.fetchall()[0][0] + +def check_queue_length(): + conn = open_db() + cur = conn.cursor() + cur.execute("SELECT Count(*) FROM entries") + return cur.fetchall()[0][0] + def clear_played_songs(): conn = open_db() cur = conn.cursor() @@ -135,10 +159,11 @@ def clear_played_songs(): conn.close() return True + def delete_entry(id): conn = open_db() cur = conn.cursor() - cur.execute("DELETE FROM entries WHERE id=?",(id,)) + cur.execute("DELETE FROM entries WHERE id=?", (id,)) conn.commit() conn.close() return True @@ -147,7 +172,7 @@ def delete_entry(id): def delete_entries(ids): idlist = [] for x in ids: - idlist.append( (x,) ) + idlist.append((x,)) try: conn = open_db() cur = conn.cursor() @@ -158,6 +183,7 @@ def delete_entries(ids): except sqlite3.Error as error: return -1 + def delete_all_entries(): conn = open_db() cur = conn.cursor() diff --git a/backend/app/helpers.py b/backend/app/helpers.py index fe932fb..4261d17 100644 --- a/backend/app/helpers.py +++ b/backend/app/helpers.py @@ -2,6 +2,7 @@ import requests from bs4 import BeautifulSoup import json import os +import uuid data_directory = "data" config_file = data_directory+"/config.json" @@ -21,6 +22,13 @@ def get_songs(url): r = requests.get(url) return r.text +def is_valid_uuid(val): + try: + uuid.UUID(str(val)) + return True + except ValueError: + return False + def check_config_exists(): return os.path.isfile(config_file) @@ -31,9 +39,11 @@ def setup_config(app): config = json.load(handle) print("Loaded existing config") else: - config = {'username': 'admin', 'password': 'changeme'} + config = {'username': 'admin', 'password': 'changeme', 'entryquota': 3, 'maxqueue': 20} with open(config_file, 'w') as handle: json.dump(config, handle, indent=4, sort_keys=True) print("Wrote new config") app.config['BASIC_AUTH_USERNAME'] = config['username'] - app.config['BASIC_AUTH_PASSWORD'] = config['password'] \ No newline at end of file + app.config['BASIC_AUTH_PASSWORD'] = config['password'] + app.config['ENTRY_QUOTA'] = config['entryquota'] + app.config['MAX_QUEUE'] = config['maxqueue'] \ No newline at end of file diff --git a/backend/app/main.py b/backend/app/main.py index cad59ac..b184138 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -19,16 +19,39 @@ def home(): @app.route('/api/enqueue', methods=['POST']) def enqueue(): - if accept_entries: - if not request.json: - print(request.data) - abort(400) - name = request.json['name'] - song_id = request.json['id'] - database.add_entry(name, song_id) - return Response('{"status":"OK"}', mimetype='text/json') + if not request.json: + print(request.data) + abort(400) + client_id = request.json['client_id'] + if not helpers.is_valid_uuid(client_id): + print(request.data) + abort(400) + name = request.json['name'] + song_id = request.json['id'] + if request.authorization: + database.add_entry(name, song_id, client_id) + return Response('{"status":"OK"}', mimetype='text/json') else: - return Response('{"status":"Currently not accepting entries"}', mimetype='text/json',status=423) + if accept_entries: + if not request.json: + print(request.data) + abort(400) + client_id = request.json['client_id'] + if not helpers.is_valid_uuid(client_id): + print(request.data) + abort(400) + name = request.json['name'] + song_id = request.json['id'] + if database.check_queue_length() < app.config['MAX_QUEUE']: + if database.check_entry_quota(client_id) < app.config['ENTRY_QUOTA']: + database.add_entry(name, song_id, client_id) + return Response('{"status":"OK"}', mimetype='text/json') + else: + return Response('{"status":"Too many queued entries from this client"}', mimetype='text/json',status=423) + else: + return Response('{"status":"Queue full"}', mimetype='text/json',status=423) + else: + return Response('{"status":"Currently not accepting entries"}', mimetype='text/json',status=423) @app.route("/list") diff --git a/backend/app/templates/base.html b/backend/app/templates/base.html index b51155c..0b454cd 100644 --- a/backend/app/templates/base.html +++ b/backend/app/templates/base.html @@ -10,7 +10,7 @@