From 3ed8146b6ffc580c9b35d7bc1c31798b4669b065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Phillip=20K=C3=BChne?= Date: Sun, 18 Aug 2019 23:55:59 +0200 Subject: [PATCH] Use bootstrap-table for fancy ajax tables. --- .vscode/launch.json | 34 +++++----- app/data_adapters.py | 8 +++ app/database.py | 15 +++++ app/helpers.py | 2 +- app/main.py | 24 ++++++- app/static/css/style.css | 4 -- app/templates/base.html | 7 ++- app/templates/main.html | 27 +++----- app/templates/main_admin.html | 111 ++++++++++++++++----------------- app/templates/played_list.html | 36 ++++++++--- app/templates/songlist.html | 10 --- 11 files changed, 161 insertions(+), 117 deletions(-) create mode 100644 app/data_adapters.py diff --git a/.vscode/launch.json b/.vscode/launch.json index ea16cbd..971d828 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,6 +6,7 @@ "configurations": [ + {"name":"Python: Flask","type":"python","request":"launch","module":"flask","env":{"FLASK_APP":"app/main.py","FLASK_ENV":"development","FLASK_DEBUG":"1"},"args":["run","--no-debugger","--no-reload"],"jinja":true}, {"name":"Python: Flask (with reload)","type":"python","request":"launch","module":"flask","env":{"FLASK_APP":"app/main.py","FLASK_ENV":"development","FLASK_DEBUG":"1"},"args":["run","--no-debugger"],"jinja":true}, { @@ -25,6 +26,24 @@ ], "jinja": true }, + { + "name": "Python: Flask (externally reachable)", + "type": "python", + "request": "launch", + "module": "flask", + "env": { + "FLASK_APP": "app/main.py", + "FLASK_ENV": "development", + "FLASK_DEBUG": "1" + }, + "args": [ + "run", + "--no-debugger", + "--no-reload", + "--host='0.0.0.0'" + ], + "jinja": true + }, { "name": "Python: Current File (Integrated Terminal)", "type": "python", @@ -65,21 +84,6 @@ ], "django": true }, - { - "name": "Python: Flask", - "type": "python", - "request": "launch", - "module": "flask", - "env": { - "FLASK_APP": "app.py" - }, - "args": [ - "run", - "--no-debugger", - "--no-reload" - ], - "jinja": true - }, { "name": "Python: Current File (External Terminal)", "type": "python", diff --git a/app/data_adapters.py b/app/data_adapters.py new file mode 100644 index 0000000..e3437bc --- /dev/null +++ b/app/data_adapters.py @@ -0,0 +1,8 @@ +def dict_from_row(row): + return dict(zip(row.keys(), row)) + +def dict_from_rows(rows): + outlist=[] + for row in rows: + outlist.append(dict_from_row(row)) + return outlist \ No newline at end of file diff --git a/app/database.py b/app/database.py index d7fd7b0..8657003 100644 --- a/app/database.py +++ b/app/database.py @@ -74,6 +74,7 @@ def create_done_song_view(): def get_list(): conn = open_db() + conn.row_factory = sqlite3.Row cur = conn.cursor() cur.execute("SELECT * FROM Liste") return cur.fetchall() @@ -141,6 +142,20 @@ def delete_entry(id): return True +def delete_entries(ids): + idlist = [] + for x in ids: + idlist.append( (x,) ) + try: + conn = open_db() + cur = conn.cursor() + cur.executemany("DELETE FROM entries WHERE id=?", idlist) + conn.commit() + conn.close() + return cur.rowcount + except sqlite3.Error as error: + return -1 + def delete_all_entries(): conn = open_db() cur = conn.cursor() diff --git a/app/helpers.py b/app/helpers.py index 5ac2a0d..aa06fa6 100644 --- a/app/helpers.py +++ b/app/helpers.py @@ -36,4 +36,4 @@ def setup_config(app): 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'] + app.config['BASIC_AUTH_PASSWORD'] = config['password'] \ No newline at end of file diff --git a/app/main.py b/app/main.py index 259ed3e..dd7e1c9 100644 --- a/app/main.py +++ b/app/main.py @@ -1,6 +1,7 @@ from flask import Flask, render_template, Response, abort, request, redirect -import helpers -import database +import app.helpers as helpers +import app.database as database +import app.data_adapters as data_adapters import os, errno import json from flask_basicauth import BasicAuth @@ -29,6 +30,11 @@ def enqueue(): def songlist(): return render_template('songlist.html', list=database.get_song_list(), auth=basic_auth.authenticate()) +@app.route("/api/queue") +def queue_json(): + list = data_adapters.dict_from_rows(database.get_list()) + return Response(json.dumps(list, ensure_ascii=False).encode('utf-8'), mimetype='text/json') + @app.route("/plays") @basic_auth.required def played_list(): @@ -69,6 +75,20 @@ def delete_entry(entry_id): return Response('{"status": "FAIL"}', mimetype='text/json') +@app.route("/api/entries/delete", methods=['POST']) +@basic_auth.required +def delete_entries(): + if not request.json: + print(request.data) + abort(400) + return + updates = database.delete_entries(request.json) + if updates >= 0: + return Response('{"status": "OK", "updates": '+str(updates)+'}', mimetype='text/json') + else: + return Response('{"status": "FAIL"}', mimetype='text/json', status=400) + + @app.route("/api/entries/mark_sung/") @basic_auth.required def mark_sung(entry_id): diff --git a/app/static/css/style.css b/app/static/css/style.css index 80c8a73..ae2ad70 100644 --- a/app/static/css/style.css +++ b/app/static/css/style.css @@ -26,15 +26,11 @@ main { .topbutton { width: 100%; - margin-right: auto; - margin-bottom: 1rem; } @media (min-width: 768px) { .topbutton { width: auto; - margin-right: 1rem; - margin-bottom: auto; } } diff --git a/app/templates/base.html b/app/templates/base.html index a22b152..15fe1b1 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -11,6 +11,9 @@ {% block title %}{% endblock %} - KaraoQueue + + + @@ -18,9 +21,10 @@ - + + @@ -88,6 +92,7 @@ + {% block extrajs %}{% endblock %} {% endblock %} \ No newline at end of file diff --git a/app/templates/played_list.html b/app/templates/played_list.html index 3c7c563..8383008 100644 --- a/app/templates/played_list.html +++ b/app/templates/played_list.html @@ -1,15 +1,23 @@ {% extends 'base.html' %} {% block title %}Abspielliste{% endblock %} {% block content %} -
-
- - - -
+
+ + +
- +
@@ -67,7 +75,8 @@ function exportPDF() { var doc = new jsPDF(); doc.autoTable({ - html: '#table', + head: [["Song","Wiedergaben"]], + body: createTableArray(), theme: 'grid' }); doc.save('Abspielliste.pdf'); @@ -76,11 +85,18 @@ function printPDF() { var doc = new jsPDF(); doc.autoTable({ - html: '#table', + head: [["Song","Wiedergaben"]], + body: createTableArray(), theme: 'grid' }); doc.autoPrint(); doc.output('dataurlnewwindow'); } + + function createTableArray() { + var data = $("#table").bootstrapTable('getData') + out = data.map(x => [x["0"],x["1"]]) + return out; + } {% endblock %} \ No newline at end of file diff --git a/app/templates/songlist.html b/app/templates/songlist.html index 93c114c..18b91f0 100644 --- a/app/templates/songlist.html +++ b/app/templates/songlist.html @@ -4,16 +4,6 @@
Song
-