mirror of
https://github.com/PhoenixTwoFive/karaoqueue.git
synced 2025-05-19 11:01:47 +02:00
Implement EventID to scope ClientIDs and Entry IDs
Implement an EventID saved in settings. Currently this is used to scope clientIDs and entryIDs to an event. The client checks the event currently going on on the server, and discards its localstorage (containing the clientID) if it has changed
This commit is contained in:
parent
adebf35d08
commit
865df5d588
@ -138,6 +138,7 @@ def songs():
|
|||||||
@basic_auth.required
|
@basic_auth.required
|
||||||
def update_songs():
|
def update_songs():
|
||||||
database.delete_all_entries()
|
database.delete_all_entries()
|
||||||
|
helpers.reset_current_event_id(app)
|
||||||
status = database.import_songs(
|
status = database.import_songs(
|
||||||
helpers.get_songs(helpers.get_catalog_url()))
|
helpers.get_songs(helpers.get_catalog_url()))
|
||||||
print(status)
|
print(status)
|
||||||
@ -149,7 +150,6 @@ def update_songs():
|
|||||||
def get_song_completions(input_string=""):
|
def get_song_completions(input_string=""):
|
||||||
input_string = request.args.get('search', input_string)
|
input_string = request.args.get('search', input_string)
|
||||||
if input_string != "":
|
if input_string != "":
|
||||||
print(input_string)
|
|
||||||
result = [list(x) for x in database.get_song_completions(input_string=input_string)]
|
result = [list(x) for x in database.get_song_completions(input_string=input_string)]
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
||||||
@ -157,10 +157,29 @@ def get_song_completions(input_string=""):
|
|||||||
return 400
|
return 400
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/entries/delete/<entry_id>")
|
@app.route("/api/entries/delete/<entry_id>", methods=['GET'])
|
||||||
@nocache
|
@nocache
|
||||||
@basic_auth.required
|
@basic_auth.required
|
||||||
def delete_entry(entry_id):
|
def delete_entry_admin(entry_id):
|
||||||
|
if database.delete_entry(entry_id):
|
||||||
|
return Response('{"status": "OK"}', mimetype='text/json')
|
||||||
|
else:
|
||||||
|
return Response('{"status": "FAIL"}', mimetype='text/json')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/api/entries/delete/<entry_id>", methods=['POST'])
|
||||||
|
@nocache
|
||||||
|
def delete_entry_user(entry_id):
|
||||||
|
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)
|
||||||
|
if database.get_raw_entry(entry_id)['client_id'] != client_id: # type: ignore
|
||||||
|
print(request.data)
|
||||||
|
abort(403)
|
||||||
if database.delete_entry(entry_id):
|
if database.delete_entry(entry_id):
|
||||||
return Response('{"status": "OK"}', mimetype='text/json')
|
return Response('{"status": "OK"}', mimetype='text/json')
|
||||||
else:
|
else:
|
||||||
@ -235,6 +254,7 @@ def clear_played_songs():
|
|||||||
@basic_auth.required
|
@basic_auth.required
|
||||||
def delete_all_entries():
|
def delete_all_entries():
|
||||||
if database.delete_all_entries():
|
if database.delete_all_entries():
|
||||||
|
helpers.reset_current_event_id(app)
|
||||||
return Response('{"status": "OK"}', mimetype='text/json')
|
return Response('{"status": "OK"}', mimetype='text/json')
|
||||||
else:
|
else:
|
||||||
return Response('{"status": "FAIL"}', mimetype='text/json')
|
return Response('{"status": "FAIL"}', mimetype='text/json')
|
||||||
@ -246,6 +266,12 @@ def admin():
|
|||||||
return redirect("/", code=303)
|
return redirect("/", code=303)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/api/events/current")
|
||||||
|
@nocache
|
||||||
|
def get_current_event():
|
||||||
|
return Response('{"status": "OK", "event": "' + helpers.get_current_event_id(app) + '"}', mimetype='text/json')
|
||||||
|
|
||||||
|
|
||||||
@app.before_first_request
|
@app.before_first_request
|
||||||
def activate_job():
|
def activate_job():
|
||||||
helpers.load_dbconfig(app)
|
helpers.load_dbconfig(app)
|
||||||
|
@ -4,6 +4,7 @@ from sqlalchemy import create_engine, engine, text
|
|||||||
import pandas
|
import pandas
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
import uuid
|
||||||
|
|
||||||
song_table = "songs"
|
song_table = "songs"
|
||||||
entry_table = "entries"
|
entry_table = "entries"
|
||||||
@ -16,7 +17,6 @@ sql_engine = None
|
|||||||
def get_db_engine() -> engine.base.Engine:
|
def get_db_engine() -> engine.base.Engine:
|
||||||
global sql_engine
|
global sql_engine
|
||||||
if (not sql_engine):
|
if (not sql_engine):
|
||||||
print(current_app.config.get("DBCONNSTRING"))
|
|
||||||
sql_engine = create_engine(
|
sql_engine = create_engine(
|
||||||
current_app.config.get("DBCONNSTRING")) # type: ignore
|
current_app.config.get("DBCONNSTRING")) # type: ignore
|
||||||
return sql_engine
|
return sql_engine
|
||||||
@ -189,6 +189,26 @@ def clear_played_songs():
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_entry(id):
|
||||||
|
try:
|
||||||
|
with get_db_engine().connect() as conn:
|
||||||
|
cur = conn.execute(text("SELECT * FROM Liste WHERE entry_ID = :par_id"),
|
||||||
|
{"par_id": id}) # type: ignore
|
||||||
|
return cur.fetchall()[0]
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_raw_entry(id):
|
||||||
|
try:
|
||||||
|
with get_db_engine().connect() as conn:
|
||||||
|
cur = conn.execute(text("SELECT * FROM entries WHERE ID = :par_id"),
|
||||||
|
{"par_id": id}) # type: ignore
|
||||||
|
return cur.fetchall()[0]
|
||||||
|
except Exception:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def delete_entry(id):
|
def delete_entry(id):
|
||||||
with get_db_engine().connect() as conn:
|
with get_db_engine().connect() as conn:
|
||||||
conn.execute(text("DELETE FROM entries WHERE id= :par_id"), {
|
conn.execute(text("DELETE FROM entries WHERE id= :par_id"), {
|
||||||
@ -260,3 +280,18 @@ def check_config_table() -> bool:
|
|||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def init_event_id() -> bool:
|
||||||
|
if not get_config("EventID"):
|
||||||
|
set_config("EventID", str(uuid.uuid4()))
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def reset_event_id() -> bool:
|
||||||
|
set_config("EventID", str(uuid.uuid4()))
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_event_id() -> str:
|
||||||
|
return get_config("EventID")
|
||||||
|
@ -98,6 +98,7 @@ def setup_config(app: Flask):
|
|||||||
for key, value in default_config.items():
|
for key, value in default_config.items():
|
||||||
database.set_config(key, value)
|
database.set_config(key, value)
|
||||||
print("Created new config")
|
print("Created new config")
|
||||||
|
database.init_event_id()
|
||||||
config = database.get_config_list()
|
config = database.get_config_list()
|
||||||
app.config['BASIC_AUTH_USERNAME'] = config['username']
|
app.config['BASIC_AUTH_USERNAME'] = config['username']
|
||||||
app.config['BASIC_AUTH_PASSWORD'] = config['password']
|
app.config['BASIC_AUTH_PASSWORD'] = config['password']
|
||||||
@ -105,6 +106,7 @@ def setup_config(app: Flask):
|
|||||||
app.config['MAX_QUEUE'] = config['maxqueue']
|
app.config['MAX_QUEUE'] = config['maxqueue']
|
||||||
app.config['ENTRIES_ALLOWED'] = bool(config['entries_allowed'])
|
app.config['ENTRIES_ALLOWED'] = bool(config['entries_allowed'])
|
||||||
app.config['THEME'] = config['theme']
|
app.config['THEME'] = config['theme']
|
||||||
|
app.config['EVENT_ID'] = database.get_event_id()
|
||||||
|
|
||||||
# set queue admittance
|
# set queue admittance
|
||||||
|
|
||||||
@ -153,6 +155,15 @@ def set_theme(app: Flask, theme: str):
|
|||||||
print("Theme not found, not setting theme.")
|
print("Theme not found, not setting theme.")
|
||||||
|
|
||||||
|
|
||||||
|
def get_current_event_id(app: Flask):
|
||||||
|
return app.config['EVENT_ID']
|
||||||
|
|
||||||
|
|
||||||
|
def reset_current_event_id(app: Flask):
|
||||||
|
database.reset_event_id()
|
||||||
|
app.config['EVENT_ID'] = database.get_event_id()
|
||||||
|
|
||||||
|
|
||||||
def nocache(view):
|
def nocache(view):
|
||||||
@wraps(view)
|
@wraps(view)
|
||||||
def no_cache(*args, **kwargs):
|
def no_cache(*args, **kwargs):
|
||||||
|
@ -108,7 +108,7 @@
|
|||||||
{% block extrajs %}{% endblock %}
|
{% block extrajs %}{% endblock %}
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
loadOrGenerateClientId()
|
checkEventID()
|
||||||
// get current URL path and assign 'active' class
|
// get current URL path and assign 'active' class
|
||||||
var pathname = window.location.pathname;
|
var pathname = window.location.pathname;
|
||||||
$('.navbar-nav > li > a[href="' + pathname + '"]').parent().addClass('active');
|
$('.navbar-nav > li > a[href="' + pathname + '"]').parent().addClass('active');
|
||||||
@ -130,6 +130,23 @@
|
|||||||
localStorage.setItem("clientId", create_UUID())
|
localStorage.setItem("clientId", create_UUID())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getClientId() {
|
||||||
|
return localStorage.getItem("clientId")
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkEventID() {
|
||||||
|
const localEventID = localStorage.getItem("eventID")
|
||||||
|
const resp = await fetch("/api/events/current")
|
||||||
|
const respJson = await resp.json()
|
||||||
|
const remoteEventID = respJson.event
|
||||||
|
|
||||||
|
if (localEventID == null || localEventID != remoteEventID) {
|
||||||
|
localStorage.clear()
|
||||||
|
localStorage.setItem("eventID", remoteEventID)
|
||||||
|
loadOrGenerateClientId()
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/api/enqueue',
|
url: '/api/enqueue',
|
||||||
data: JSON.stringify(data), // or JSON.stringify ({name: 'jonas'}),
|
data: JSON.stringify(data),
|
||||||
success: success_callback,
|
success: success_callback,
|
||||||
statusCode: {
|
statusCode: {
|
||||||
423: blocked_callback
|
423: blocked_callback
|
||||||
@ -99,6 +99,7 @@
|
|||||||
enqueue(localStorage.getItem("clientId"),id, name, function () {
|
enqueue(localStorage.getItem("clientId"),id, name, function () {
|
||||||
$("#enqueueModal").modal('hide');
|
$("#enqueueModal").modal('hide');
|
||||||
window.location.href = '/#end';
|
window.location.href = '/#end';
|
||||||
|
|
||||||
}, function (response) {
|
}, function (response) {
|
||||||
bootbox.alert({
|
bootbox.alert({
|
||||||
message: "Deine Eintragung konnte leider nicht vorgenommen werden.\nGrund: "+response.responseJSON.status,
|
message: "Deine Eintragung konnte leider nicht vorgenommen werden.\nGrund: "+response.responseJSON.status,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user