From 6e7fb8c4991d9ac52352a3d0b944c8f7ce3c0112 Mon Sep 17 00:00:00 2001 From: mikka Date: Sun, 19 Apr 2026 11:06:57 +0200 Subject: [PATCH] Erste version --- app.py | 129 +++++++++++++++++++++++++++++++++++++++++++ static/script.js | 6 ++ templates/index.html | 58 +++++++++++++++++++ templates/karte.html | 17 ++++++ templates/suche.html | 12 ++++ 5 files changed, 222 insertions(+) create mode 100755 app.py create mode 100755 static/script.js create mode 100755 templates/index.html create mode 100755 templates/karte.html create mode 100755 templates/suche.html diff --git a/app.py b/app.py new file mode 100755 index 0000000..d82b498 --- /dev/null +++ b/app.py @@ -0,0 +1,129 @@ +from flask import Flask, render_template, request, redirect +from glob import glob +import subprocess +import requests +import json + +def wikiapi(id,field): + name = f"data/{id}_{field}.json" + try: + with open(name, "r") as f: + data = json.load(f) + except OSError: + r = requests.get("https://www.wikidata.org/w/rest.php/wikibase/v1/entities/items/"+id+"?_fields="+field, headers={"user-agent":'esc/0.0(mikka@kleinrot.net)','Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJhNDBhYmZjYzQxZTlkOTc2YzJiN2NmODZkYzIwMmQzZiIsImp0aSI6ImQ3ODQ4YmJhNjZlMWYzYzdhZGZmODU5NTdmZWE1YjMxODBhMzE2NTc4YWYyMWMzZGZhZGJiOTZlZmM3ZTgyMmJkMTE4YTQ4YWMzMDM2ZmQyIiwiaWF0IjoxNzc1OTE4OTc1LjkzMjQsIm5iZiI6MTc3NTkxODk3NS45MzI0MDEsImV4cCI6MzMzMzI4Mjc3NzUuOTI5NDA1LCJzdWIiOiIxMzEiLCJpc3MiOiJodHRwczovL21ldGEud2lraW1lZGlhLm9yZyIsInJhdGVsaW1pdCI6eyJyZXF1ZXN0c19wZXJfdW5pdCI6NTAwMCwidW5pdCI6IkhPVVIifSwic2NvcGVzIjpbImJhc2ljIl19.WLXRXxNjsZ1kIK2RX-Wds59W8Z1CWphbiV3UBEWvm5STWZ6uvpHZpx5d9lomK5-H56G3259_DavuTymdebQTmAwkeuCGh1gb60u9_4MzmGgspQHBPq3mWX879AUVW69uqsSz2x2zIz-ZUmt5TrZM7X3OBxE01nhVBoiDWnlW4Gt19FjwBQ9WjXzrFHsH9A7BtPzgbKROMXACRQBqh9XZXkN23PvnEV08sx63AGB0cZBkteIsnIfm49-Ht2_DTZKd4_MpEw9TZjOHSjY9odyImXidZOgy7NadT-LwAKQiVlSn6UZWTvgsG6xwP6sad_ctqU1ZupcOJLzd158DhrLAEMk_Qq9-piTQDYtLzWfLx44Jatjae6-0nilOgvrB0XQJC6cTihVk3-9Lyn6Y-e6yIDnEHIIIBj0J8PUv5IJjAojo-2uZ4w8omEzCWDEzf95_GSZmRwj_nRNCVs5jQpVhG9hFpOm2OrTrhqPgYet_dsl3QVEbvtGnlVzCw7j9sj_86axAC1hklQQso6AiAAzEmOiTfC6VyrP8sFjbnDlLBCEiTkYTvOTp5nuYRC8VdwJQm6NJIafjNn5ihp4T8OvJQyzsK1HDYlthvW54-co2gPoeIX-cBItvdrCBNDofoA9bIP3zzwGXdvy1b7lofx5WekWKAGytPCfsr7i2ZJB93xU'}) + data = r.json() + with open(name, "x") as f: + json.dump(data, f,indent=2,ensure_ascii=False) + return data[field] + +def wikisuche(text): + mitp1344 = [] + ohnep1344 = [] + r = requests.get("https://www.wikidata.org/w/rest.php/wikibase/v1/search/items?q="+text+"&language=en", headers={"user-agent":'esc/0.0(mikka@kleinrot.net)','Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJhNDBhYmZjYzQxZTlkOTc2YzJiN2NmODZkYzIwMmQzZiIsImp0aSI6ImQ3ODQ4YmJhNjZlMWYzYzdhZGZmODU5NTdmZWE1YjMxODBhMzE2NTc4YWYyMWMzZGZhZGJiOTZlZmM3ZTgyMmJkMTE4YTQ4YWMzMDM2ZmQyIiwiaWF0IjoxNzc1OTE4OTc1LjkzMjQsIm5iZiI6MTc3NTkxODk3NS45MzI0MDEsImV4cCI6MzMzMzI4Mjc3NzUuOTI5NDA1LCJzdWIiOiIxMzEiLCJpc3MiOiJodHRwczovL21ldGEud2lraW1lZGlhLm9yZyIsInJhdGVsaW1pdCI6eyJyZXF1ZXN0c19wZXJfdW5pdCI6NTAwMCwidW5pdCI6IkhPVVIifSwic2NvcGVzIjpbImJhc2ljIl19.WLXRXxNjsZ1kIK2RX-Wds59W8Z1CWphbiV3UBEWvm5STWZ6uvpHZpx5d9lomK5-H56G3259_DavuTymdebQTmAwkeuCGh1gb60u9_4MzmGgspQHBPq3mWX879AUVW69uqsSz2x2zIz-ZUmt5TrZM7X3OBxE01nhVBoiDWnlW4Gt19FjwBQ9WjXzrFHsH9A7BtPzgbKROMXACRQBqh9XZXkN23PvnEV08sx63AGB0cZBkteIsnIfm49-Ht2_DTZKd4_MpEw9TZjOHSjY9odyImXidZOgy7NadT-LwAKQiVlSn6UZWTvgsG6xwP6sad_ctqU1ZupcOJLzd158DhrLAEMk_Qq9-piTQDYtLzWfLx44Jatjae6-0nilOgvrB0XQJC6cTihVk3-9Lyn6Y-e6yIDnEHIIIBj0J8PUv5IJjAojo-2uZ4w8omEzCWDEzf95_GSZmRwj_nRNCVs5jQpVhG9hFpOm2OrTrhqPgYet_dsl3QVEbvtGnlVzCw7j9sj_86axAC1hklQQso6AiAAzEmOiTfC6VyrP8sFjbnDlLBCEiTkYTvOTp5nuYRC8VdwJQm6NJIafjNn5ihp4T8OvJQyzsK1HDYlthvW54-co2gPoeIX-cBItvdrCBNDofoA9bIP3zzwGXdvy1b7lofx5WekWKAGytPCfsr7i2ZJB93xU'}) + for result in r.json()["results"]: + if getescedition(result["id"]): + mitp1344.append(result) + else: + ohnep1344.append(result) + return mitp1344 + ohnep1344 + +def getescedition(songId): + statements = wikiapi(songId,"statements") + if "P1344" in statements: + for statement in statements["P1344"]: + id = statement["value"]["content"] + escdata = wikiapi(id,"statements") + if escdata["P31"][0]["value"]["content"] == "Q110288240": + return id,statement + + +def datei(id): + file = glob("static/"+id+".*") + + if file == []: + subprocess.run(["yt-dlp",f"http://youtu.be/{id}","-x","-o",id],cwd="static") + file = glob("static/"+id+".*") + audio = file[0].replace("static/", "") + + return audio + +with open("songs.json","r") as f: + songs = json.load(f) +def kartenGeneriren(song): + id = song["wikiid"] + statements = wikiapi(id,"statements") + labels = wikiapi(id,"labels") + song["titel"] = statements.get("P1476",[{"value": {"content":{"text":labels["en"]}}}])[0]["value"]["content"]["text"] + song["laenge"] = int(statements.get("P2047",[{"value": {"content":{"amount":"0"}}}])[0]["value"]["content"]["amount"]) + escedition = getescedition(id) + if escedition: + (escedition,statement)=escedition + song["jahrgang"] = wikiapi(escedition,"labels")["en"] + qualifiers = statement["qualifiers"] + for qualifier in qualifiers: + if qualifier["property"]["id"] == "P1352": + song["plazirung"] = str(int(qualifier["value"]["content"]["amount"]))+"." + song["interprete"] = " x ".join(set(wikiapi(statement["value"]["content"],"labels")["en"] for statement in statements.get("P175",[]))) + if "ytid" not in song and "P1651" in statements: + song["ytid"] = statements["P1651"][0]["value"]["content"] + print(song) + if "ytid" in song: + song["datei"] = datei(song["ytid"]) + song["img"] = f"http://img.youtube.com/vi/{ song["ytid"] }/sddefault.jpg" + if "P6218" in statements: + song["text"] = f"//genius.com/{statements["P6218"][0]["value"]["content"]}" + if "P18" in statements: + song["img"] = f"https://commons.wikimedia.org/w/index.php?title=Special:Redirect/file/{statements["P18"][0]["value"]["content"]}&width=300" + if "img" not in song: + song["img"] = "https://commons.wikimedia.org/w/index.php?title=Special:Redirect/file/Eurovision_Song_Contest_heart_(2014–2025).svg&width=300" +for song in songs: + kartenGeneriren(song) + +app = Flask(__name__) + +@app.template_filter('zeit') +def zeit(sekunden): + minuten = sekunden // 60 + rest = sekunden - minuten * 60 + return f"{minuten}:{rest:02}" + + +@app.route("/") +def hello_world(): + gesamtLaenge = 0 + for song in songs: + gesamtLaenge += song["laenge"] + return render_template('index.html', karten=songs,gesamtLaenge=gesamtLaenge ) + +@app.route("/suche") +def suche(): + such = request.args.get("suche") + if such is not None: + ergebnisse = wikisuche(such) + else: + ergebnisse = [] + return render_template('suche.html', ergebnisse=ergebnisse,anfrage=such) + +@app.route("/suche",methods=["POST"]) +def suche_finden(): + song = {"wikiid":request.form.get("id")} + kartenGeneriren(song) + songs.append(song) + with open("songs.json","w") as f: + json.dump(songs,f,indent=2,ensure_ascii=False) + return redirect("/",303) + +@app.route("/ADMIN") +def admin(): + gesamtLaenge = 0 + for song in songs: + gesamtLaenge += song["laenge"] + return render_template('index.html', karten=songs,gesamtLaenge=gesamtLaenge,admin=True ) + +@app.route("/ADMIN",methods=["POST"]) +def loeschen(): + song = int(request.form.get("index")) + del songs[song] + with open("songs.json","w") as f: + json.dump(songs,f,indent=2,ensure_ascii=False) + return redirect("/ADMIN",303) \ No newline at end of file diff --git a/static/script.js b/static/script.js new file mode 100755 index 0000000..7794646 --- /dev/null +++ b/static/script.js @@ -0,0 +1,6 @@ +const audios = document.querySelectorAll("audio") + +for (const [index,audio] of audios.entries()){ + audio.addEventListener("ended", (event) => { audios[index + 1].play()}) +} +console.log(audios) \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100755 index 0000000..17c39b2 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,58 @@ + +

ESC Playlist

+

2026

+Du willst ein weiteres Lied in der Playlist? +

Die Playlist ist insgesamt lang {{ gesamtLaenge | zeit }} und enthält {{ karten|length }} Lieder

+
+ {% for karte in karten %} + {% set karte_loop = loop %} + {% include "karte.html" %} + {% endfor %} +
+ \ No newline at end of file diff --git a/templates/karte.html b/templates/karte.html new file mode 100755 index 0000000..8e2eb5a --- /dev/null +++ b/templates/karte.html @@ -0,0 +1,17 @@ +
+ + +

{{ karte.titel}}

+

Übersetzter Titel:{{ karte.uetitel}}

+

Interpreten:{{ karte.interprete}}

+

Jahrgang: {{ karte.jahrgang }}

+

Plazirung: {{ karte.plazirung }}

+

Länge: {{karte.laenge|zeit}}

+

Interesanter Fakt: {{ karte.interesanterfakt }}

+ {% if karte.text %} + Original Text + {% endif %} + {% if admin %} +
+ {% endif %} +
diff --git a/templates/suche.html b/templates/suche.html new file mode 100755 index 0000000..c54ffe0 --- /dev/null +++ b/templates/suche.html @@ -0,0 +1,12 @@ +
+{% if ergebnisse %} +
    +{% for ergebnis in ergebnisse %} +
    • {{ ergebnis.description.value }}
  1. +{% endfor %}
+ +{%elif anfrage%} +

Leider gibt es diesen Eintrag nicht!

+{%endif%} + +Doch nicht? \ No newline at end of file