Logo und andere kleinen Dinge

This commit is contained in:
mikka 2026-05-14 23:29:06 +02:00
parent 587f2546f9
commit 2623dfdf1a
9 changed files with 422 additions and 255 deletions

114
app.py
View file

@ -1,9 +1,11 @@
from flask import Flask, render_template, request, redirect
from glob import glob
import subprocess
import requests
import json import json
import os import os
import subprocess
from glob import glob
import requests
from flask import Flask, redirect, render_template, request
def wikiapi(id, field): def wikiapi(id, field):
if os.path.isdir("data"): if os.path.isdir("data"):
@ -15,27 +17,46 @@ def wikiapi(id,field):
with open(name, "r") as f: with open(name, "r") as f:
data = json.load(f) data = json.load(f)
except OSError: 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'}) 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() data = r.json()
with open(name, "x") as f: with open(name, "x") as f:
json.dump(data, f, indent=2, ensure_ascii=False) json.dump(data, f, indent=2, ensure_ascii=False)
return data[field] return data[field]
def wikisuche(text): def wikisuche(text):
mitp1344 = [] mitpartsin = []
ohnep1344 = [] ohnepartsin = []
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'}) 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"]: for result in r.json()["results"]:
if getescedition(result["id"]): if getescedition(result["id"]):
mitp1344.append(result) mitpartsin.append(result)
else: else:
ohnep1344.append(result) ohnepartsin.append(result)
return mitp1344 + ohnep1344 return mitpartsin + ohnepartsin
def getescedition(songId): def getescedition(songId):
statements = wikiapi(songId, "statements") statements = wikiapi(songId, "statements")
if "P1344" in statements: if "partsin" in statements:
for statement in statements["P1344"]: for statement in statements["partsin"]:
id = statement["value"]["content"] id = statement["value"]["content"]
escdata = wikiapi(id, "statements") escdata = wikiapi(id, "statements")
if escdata["P31"][0]["value"]["content"] == "Q110288240": if escdata["P31"][0]["value"]["content"] == "Q110288240":
@ -46,7 +67,9 @@ def datei(id):
file = glob("static/" + id + ".*") file = glob("static/" + id + ".*")
if file == []: if file == []:
subprocess.run(["yt-dlp",f"http://youtu.be/{id}","-x","-o",id],cwd="static") subprocess.run(
["yt-dlp", f"http://youtu.be/{id}", "-x", "-o", id], cwd="static"
)
file = glob("static/" + id + ".*") file = glob("static/" + id + ".*")
if file != []: if file != []:
audio = file[0].replace("static/", "") audio = file[0].replace("static/", "")
@ -55,13 +78,20 @@ def datei(id):
print(audio) print(audio)
return audio return audio
def kartenGeneriren(song): def kartenGeneriren(song):
id = song["wikiid"] id = song["wikiid"]
print(id) print(id)
statements = wikiapi(id, "statements") statements = wikiapi(id, "statements")
labels = wikiapi(id, "labels") labels = wikiapi(id, "labels")
song["titel"] = statements.get("P1476",[{"value": {"content":{"text":labels["en"]}}}])[0]["value"]["content"]["text"] song["titel"] = statements.get(
song["laenge"] = int(statements.get("P2047",[{"value": {"content":{"amount":"0"}}}])[0]["value"]["content"]["amount"]) "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) escedition = getescedition(id)
if escedition: if escedition:
(escedition, statement) = escedition (escedition, statement) = escedition
@ -69,24 +99,40 @@ def kartenGeneriren(song):
qualifiers = statement["qualifiers"] qualifiers = statement["qualifiers"]
for qualifier in qualifiers: for qualifier in qualifiers:
if qualifier["property"]["id"] == "P1352": if qualifier["property"]["id"] == "P1352":
song["plazirung"] = str(int(qualifier["value"]["content"]["amount"]))+"." song["plazirung"] = (
song["interprete"] = " x ".join(set(wikiapi(statement["value"]["content"],"labels")["en"] for statement in statements.get("P175",[]))) str(int(qualifier["value"]["content"]["amount"])) + "."
)
song["interprete"] = " x ".join(
set(
wikiapi(statement["value"]["content"], "labels")["en"]
for statement in statements.get("P175", [])
)
)
if "land" not in song and "P495" in statements:
song["land"] = wikiapi(statements["P495"][0]["value"]["content"], "labels")[
"de"
]
if "ytid" not in song and "P1651" in statements: if "ytid" not in song and "P1651" in statements:
song["ytid"] = statements["P1651"][0]["value"]["content"] song["ytid"] = statements["P1651"][0]["value"]["content"]
if "ytid" in song: if "ytid" in song:
song["datei"] = datei(song["ytid"]) song["datei"] = datei(song["ytid"])
song["img"] = f"http://img.youtube.com/vi/{ song["ytid"] }/sddefault.jpg" song["img"] = f"http://img.youtube.com/vi/{song['ytid']}/sddefault.jpg"
if "P6218" in statements: if "P6218" in statements:
song["text"] = f"//genius.com/{statements["P6218"][0]["value"]["content"]}" song["text"] = f"//genius.com/{statements['P6218'][0]['value']['content']}"
if "P18" in statements: 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" 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: if "img" not in song:
song["img"] = "https://commons.wikimedia.org/w/index.php?title=Special:Redirect/file/Eurovision_Song_Contest_heart_(20142025).svg&width=300" song["img"] = (
"https://commons.wikimedia.org/w/index.php?title=Special:Redirect/file/Eurovision_Song_Contest_heart_(20142025).svg&width=300"
)
app = Flask(__name__) app = Flask(__name__)
@app.template_filter('zeit')
@app.template_filter("zeit")
def zeit(sekunden): def zeit(sekunden):
minuten = sekunden // 60 minuten = sekunden // 60
rest = sekunden - minuten * 60 rest = sekunden - minuten * 60
@ -105,14 +151,17 @@ def hello_world():
gesamtLaenge = 0 gesamtLaenge = 0
for song in songs: for song in songs:
gesamtLaenge += song["laenge"] gesamtLaenge += song["laenge"]
return render_template('index.html', karten=songs,gesamtLaenge=gesamtLaenge,liste=liste ) return render_template(
"index.html", karten=songs, gesamtLaenge=gesamtLaenge, liste=liste
)
@app.route("/playlists") @app.route("/playlists")
def playlists(): def playlists():
listen = glob("*.json") listen = glob("*.json")
listen = (liste.replace(".json", "") for liste in listen) listen = (liste.replace(".json", "") for liste in listen)
return render_template('playlists.html',lists=listen) return render_template("playlists.html", lists=listen)
@app.route("/neueliste") @app.route("/neueliste")
def neueliste(): def neueliste():
@ -121,8 +170,8 @@ def neueliste():
with open(name + ".json", "x") as f: with open(name + ".json", "x") as f:
json.dump([], f) json.dump([], f)
return redirect("/?liste=" + name) return redirect("/?liste=" + name)
print(liste) return render_template("neueliste.html", name=name)
return render_template('neueliste.html',name=name)
@app.route("/suche") @app.route("/suche")
def suche(): def suche():
@ -132,7 +181,10 @@ def suche():
ergebnisse = wikisuche(such) ergebnisse = wikisuche(such)
else: else:
ergebnisse = [] ergebnisse = []
return render_template('suche.html', ergebnisse=ergebnisse,anfrage=such,liste=liste) return render_template(
"suche.html", ergebnisse=ergebnisse, anfrage=such, liste=liste
)
@app.route("/suche", methods=["POST"]) @app.route("/suche", methods=["POST"])
def suche_finden(): def suche_finden():
@ -146,6 +198,7 @@ def suche_finden():
json.dump(songs, f, indent=2, ensure_ascii=False) json.dump(songs, f, indent=2, ensure_ascii=False)
return redirect("/suche?liste=" + liste, 303) return redirect("/suche?liste=" + liste, 303)
@app.route("/remove") @app.route("/remove")
def admin(): def admin():
liste = request.args.get("liste") liste = request.args.get("liste")
@ -158,7 +211,10 @@ def admin():
gesamtLaenge = 0 gesamtLaenge = 0
for song in songs: for song in songs:
gesamtLaenge += song["laenge"] gesamtLaenge += song["laenge"]
return render_template('index.html', karten=songs,gesamtLaenge=gesamtLaenge,liste=liste,admin=True) return render_template(
"index.html", karten=songs, gesamtLaenge=gesamtLaenge, liste=liste, admin=True
)
@app.route("/remove", methods=["POST"]) @app.route("/remove", methods=["POST"])
def loeschen(): def loeschen():

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View file

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="125.33"
height="131.46"
version="1.1"
id="svg1"
sodipodi:docname="Eurovision_Song_Contest_heart_Wikidata_(20142025).svg"
xml:space="preserve"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="4.303099"
inkscape:cx="53.449851"
inkscape:cy="50.196382"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" /><g
id="g1"
transform="matrix(0.12157124,0,0,0.23068304,12.733877,4.287877)"><path
id="path1-3"
style="fill:#990000"
d="m 14.029438,47.537215 c -1.774828,0.01827 -1.013972,0.384871 -0.03213,0.626536 0.743679,-0.164572 1.490068,-0.325118 2.23313,-0.491069 -0.72782,-0.04244 -1.783992,-0.139759 -2.200998,-0.135467 z M 142.18539,59.094266 c -4.82297,3.438254 -9.69255,6.858605 -15.85683,9.685909 -9.38162,4.990549 -19.34173,9.624906 -30.380205,13.58906 -10.698213,3.846403 -21.764589,7.384325 -33.946788,9.78751 -0.669629,0.14639 -1.339128,0.292891 -2.00821,0.440268 V 399.87063 c 4.294457,2.59538 8.563573,5.20196 12.965006,7.74704 14.479715,8.05187 30.579687,15.20504 46.076377,22.69076 10.37587,4.79197 20.82658,9.52643 30.95857,14.45267 V 61.321009 c -2.64183,-0.684628 -5.26357,-1.407695 -7.80792,-2.226743 z m 37.81862,7.5523 V 459.74716 c 2.35383,1.15862 4.67161,2.33734 7.0689,3.47135 10.48296,4.92542 21.63634,9.42235 32.74186,13.94466 11.38075,4.82918 22.73005,9.68782 33.86646,14.6728 2.23876,1.1668 4.70542,2.2195 6.71546,3.49675 2.36848,1.50499 4.77459,3.02601 6.79578,4.66515 h 2.81149 V 74.402066 c -1.52365,-0.251491 -2.99632,-0.543839 -4.41806,-0.880537 -3.44536,-0.556772 -6.89455,-1.106275 -10.31417,-1.710274 -5.17069,-0.542732 -10.36811,-1.007044 -15.53551,-1.557873 -0.97125,-0.103562 -1.88782,-0.366087 -2.87576,-0.406402 -1.61527,-0.06633 -3.23252,-0.05736 -4.85184,-0.08467 -12.33914,-0.26891 -24.68661,-0.675896 -36.91894,-1.608674 -5.06761,-0.420601 -10.09953,-0.926035 -15.08567,-1.507073 z M 29.998726,98.980908 c -8.251681,1.796042 -16.220058,3.973792 -24.9660709,5.080022 -2.0724185,0.24509 -3.4743116,0.40985 -5.02855874,0.59267 V 393.09727 C 14.640724,395.66002 26.790289,396.67245 29.998726,392.34373 v -6.23996 c -0.803728,-1.96212 -2.182488,-4.26283 -4.305603,-7.01043 -0.191081,-0.24728 -0.479549,-0.48168 -0.562298,-0.74507 -0.02734,-0.087 -8.34e-4,-0.0983 0.08033,-0.0593 0.243479,0.11718 0.860945,0.67324 1.172795,0.88054 1.184122,0.78717 2.416754,1.5504 3.614778,2.32834 z" /><path
id="path2"
style="fill:#339966"
d="M 720.00374,-0.00332762 V 316.05873 c 9.4778,-7.25273 19.5086,-14.30976 29.99463,-21.17523 V 7.1933707 c -1.61483,-1.6498815 -1.49121,-3.0052856 0,-4.1232848 V -0.00332762 Z M 810.0037,7.5235722 C 799.38514,8.2567434 788.77164,8.7962855 779.993,9.4285806 V 20.232095 c 0.31997,0.13476 0.43431,0.208138 0,0.127 V 276.57002 c 3.48903,-1.88316 6.90501,-3.814 10.98893,-5.30862 6.88074,-2.51817 12.98246,-4.39552 19.02177,-5.71503 z M 299.99859,81.522564 V 499.99787 h 29.99463 V 97.160567 c -7.9882,-2.297003 -15.07698,-5.435046 -20.85325,-9.381108 -3.34736,-2.462292 -4.5133,-3.672614 -5.88004,-4.52122 -1.05183,-0.525067 -3.05402,-1.485727 -2.98822,-1.549407 0.0574,-0.05538 0.25839,0.0053 0.43377,0.06773 -0.21331,-0.09699 -0.48098,-0.163567 -0.70689,-0.254002 z m 89.99996,17.348277 c -8.20339,1.519749 -16.83464,2.407739 -25.64083,2.683949 -1.45128,-0.0369 -2.89992,-0.0475 -4.3538,-0.0677 v 398.51082 h 7.30989 c 1.48574,-6.49571 8.87825,-13.03235 22.68474,-18.01714 z" /><path
id="path3"
style="fill:#006699"
d="m 548.35799,-0.00332762 c 1.32928,3.78920772 2.24975,7.61254682 1.73509,11.48085062 -0.42645,1.741623 -0.60851,3.502756 -1.26919,5.223956 -1.60817,4.189623 -4.62212,8.251934 -8.82006,11.929586 V 418.95458 c 0.48825,-0.36573 0.93428,-0.74589 1.42985,-1.10914 2.62333,-1.9375 6.39128,-4.76412 9.10924,-6.55322 5.85514,-3.85417 12.52594,-7.29148 19.45554,-10.59185 V -0.00332762 Z m 51.6351,0 V 387.80558 c 4.47695,-1.73687 9.00958,-3.43485 13.6719,-5.04616 11.34729,-4.17629 22.86313,-8.22255 34.17171,-12.42912 7.06298,-2.78351 14.24938,-5.59077 19.96964,-9.16097 6.93356,-4.30741 12.65281,-9.01463 17.15815,-14.15633 1.65811,-1.61121 3.36978,-3.20652 5.02856,-4.81756 V -0.00332762 Z M 509.99314,42.56726 c -0.24486,0.0606 -0.47595,0.136521 -0.72296,0.194734 -8.74713,2.061395 -18.1919,2.88136 -27.56871,3.657616 -3.65751,0.48271 -1.00651,0.112622 -4.33774,0.609603 -3.88331,0.57934 -0.059,0.157044 -0.81935,-0.169334 -0.82252,-0.353035 -2.37514,1.932431 -2.6187,0.956737 -0.49781,0.226211 -1.00074,0.448451 -1.49411,0.677336 -0.3614,0.16765 -0.97876,0.756482 -1.0764,0.508003 -0.15229,-0.387359 1.54235,-1.288175 0.89968,-1.083738 -0.21675,0.06897 -0.33904,0.201743 -0.44984,0.321734 -0.44886,0.486165 -0.81218,0.98579 -1.22099,1.481674 -4.11781,5.237277 -6.68747,10.843785 -12.82042,15.604135 -5.6807,4.605146 -11.78003,9.07912 -18.65226,13.216525 -6.17704,3.674682 -12.21316,7.410557 -19.11816,10.718847 V 475.2751 c 3.0332,-0.37853 6.17199,-0.71814 9.47875,-0.99061 5.46251,-0.4501 10.93222,-0.82713 16.4352,-1.10067 0.29359,-0.0237 5.86112,-0.5336 5.88004,-0.52493 0.12774,0.0737 -0.54025,0.2544 -0.35345,0.23706 0.44544,-0.039 0.81522,-0.20879 1.22099,-0.31326 5.07815,-1.73672 9.61583,-3.74927 13.59157,-6.1807 7.3223,-4.3773 14.00387,-9.04125 21.38343,-13.39432 7.02366,-4.4061 14.2383,-8.73866 22.36343,-12.59846 z" /></g><path
d="m12.726 58.556c0.31803-28.513 15.157-37.437 23.237-37.437 11.285 0 15.946 8.6151 16.707 12.429 0.76116 3.8111 5.0324 6.8595 6.4047 0.60798 1.3734-6.2515 14.649-25.315 30.966-25.315 14.943 0 20.119 15.41 19.671 28.518-1.2228 35.683-47.19 64.158-53.239 82.143-5.3875-10.891-44.126-26.634-43.746-60.946zm82.652-58.556c-13.42 0-29.29 9.9111-38.896 26.382-2.592-5.9483-11.827-12.43-22.805-12.43-8.8462 0-33.676 11.056-33.676 46.74 0 46.052 46.593 55.508 56.011 69.825 0.64721 0.98433 2.7319 1.728 3.5276-0.62388 7.5157-22.18 65.791-47.242 65.791-92.379-5.3e-4 -25.314-16.536-37.513-29.955-37.513z"
stroke-width=".53006"
id="path1" /><g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="DATA" /></svg>

After

Width:  |  Height:  |  Size: 6.6 KiB

View file

@ -1,102 +1,98 @@
const audios = document.querySelectorAll("audio") const audios = document.querySelectorAll("audio");
const articles = document.querySelectorAll("article") const articles = document.querySelectorAll("article");
const kartenContainer = document.getElementById("flex-container") const kartenContainer = document.getElementById("flex-container");
outindex = 0 outindex = 0;
playing = false playing = false;
playcolor = "#00ff3c" playcolor = "#00ff3c";
loop = true loop = true;
function onplay(id) { function onplay(id) {
//What is id id = parseInt(id);
id = parseInt(id)
if (id > 0) { if (id > 0) {
articles[id-1].style.filter = "grayscale("+(id+1)*20+"%)" articles[id - 1].style.filter = "grayscale(" + (id + 1) * 20 + "%)";
articles[id-1].style.boxShadow = "0 0 0px 0px "+playcolor articles[id - 1].style.boxShadow = "0 0 0px 0px " + playcolor;
} }
if (articles[id].offsetWidth * id == window.innerWidth / 2) { if (articles[id].offsetWidth * id == window.innerWidth / 2) {
console.log(articles[id].offsetWidth) console.log(articles[id].offsetWidth);
kartenContainer.scrollWidth += articles[id].offsetWidth kartenContainer.scrollWidth += articles[id].offsetWidth;
} }
articles[id].style.filter = "grayscale(0%)" articles[id].style.filter = "grayscale(0%)";
articles[id].style.margin = "8px" articles[id].style.margin = "8px";
articles[id].style.boxShadow = "0 0 6px 1px "+playcolor articles[id].style.boxShadow = "0 0 6px 1px " + playcolor;
} }
function nächste(id) { function nächste(id) {
audios[id].pause() audios[id].pause();
id = parseInt(id) + 1 id = parseInt(id) + 1;
audios[id].play() audios[id].play();
onplay(id) onplay(id);
} }
function vorherige(id) { function vorherige(id) {
audios[id].pause() audios[id].pause();
audios[id-1].play() audios[id - 1].play();
onplay(id-1) onplay(id - 1);
} }
function looptrue() { function looptrue() {
if (loop) { if (loop) {
loop = false loop = false;
document.querySelector("#loop").innerHTML = "Kein Loop" document.querySelector("#loop").innerHTML = "Kein Loop";
document.querySelector("#loop").style.beckground document.querySelector("#loop").style.beckground;
} } else {
else{ loop = true;
loop = true document.querySelector("#loop").innerHTML = "Loop";
document.querySelector("#loop").innerHTML = "Loop"
} }
} }
function abspielendiese(id) { function abspielendiese(id) {
if (playing) { if (playing) {
//ON PAUSE //ON PAUSE
audios[id].pause() audios[id].pause();
playing = false playing = false;
articles[id].style.margin = "0px" articles[id].style.margin = "0px";
articles[id].style.boxShadow = "0 0 0px 0px "+playcolor articles[id].style.boxShadow = "0 0 0px 0px " + playcolor;
} } else {
else{
//ON PLAY //ON PLAY
audios[id].play() audios[id].play();
playing = true playing = true;
onplay(id) onplay(id);
} }
} }
function abspielen() { function abspielen() {
if (playing) { if (playing) {
//ON PAUSE //ON PAUSE
audios[outindex].pause() audios[outindex].pause();
playing = false playing = false;
articles[outindex].style.margin = "0px" articles[outindex].style.margin = "0px";
articles[outindex].style.boxShadow = "0 0 0px 0px "+playcolor articles[outindex].style.boxShadow = "0 0 0px 0px " + playcolor;
document.querySelector("#play").innerHTML = "Abspielen" document.querySelector("#play").innerHTML = "Abspielen";
} } else {
else{
//ON PLAY //ON PLAY
audios[outindex].play() audios[outindex].play();
playing = true playing = true;
document.querySelector("#play").innerHTML = "Pausieren" document.querySelector("#play").innerHTML = "Pausieren";
onplay(outindex) onplay(outindex);
} }
} }
for (const [index, audio] of audios.entries()) { for (const [index, audio] of audios.entries()) {
audio.addEventListener("ended", (event) => { audio.addEventListener("ended", (event) => {
if (index != audios.length - 1) { if (index != audios.length - 1) {
outindex = index +1 outindex = index + 1;
audios[outindex].play() audios[outindex].play();
onplay(index+1) onplay(index + 1);
} } else {
else{
//Last song ON END //Last song ON END
articles[index].style.filter = "grayscale(80%)" articles[index].style.filter = "grayscale(80%)";
articles[index].style.boxShadow = "0 0 0px 0px "+playcolor articles[index].style.boxShadow = "0 0 0px 0px " + playcolor;
articles[index].style.margin = "8px" articles[index].style.margin = "8px";
articles[index].style.boxShadow = "0 0 6px 1px "+playcolor articles[index].style.boxShadow = "0 0 6px 1px " + playcolor;
if (loop) { if (loop) {
audios[0].play() audios[0].play();
} }
} }
}) });
} }
//Audio visualising

View file

@ -11,7 +11,9 @@
border: none; border: none;
flex: 0 0 30rem; flex: 0 0 30rem;
} }
a,h1,h2{ a,
h1,
h2 {
display: block; display: block;
text-align: center; text-align: center;
} }
@ -38,7 +40,7 @@
h2 { h2 {
text-align: center; text-align: center;
} }
article > a{ #gray {
font-size: 0.75rem; font-size: 0.75rem;
display: block; display: block;
text-align: center; text-align: center;
@ -50,16 +52,38 @@
border: black; border: black;
border-radius: 20px; border-radius: 20px;
} }
#logo{
object-fit: scale-down;
}
#logocontaner{
margin: 0 auto;
height: 25%;
width: 25%;
}
#logo{
height: 105%;
scale: 150%;
}
#logocontaner{
margin: 0 auto;
}
</style> </style>
<a href="/" id="logocontaner"><img id="logo" src="/static/Eurovision_Song_Contest_heart_Wikidata_(20142025).svg"></img></a>
<h1>ESC Playlist</h1> <h1>ESC Playlist</h1>
<h2>2026</h2> <a href="/suche?liste={{liste}}"
<a href="/suche?liste={{liste}}">Du willst ein weiteres Lied in der Playlist?</a> >Du willst ein weiteres Lied in der Playlist?</a
<p>Die Playlist {{liste}} ist insgesamt {{ gesamtLaenge | zeit }} lang und enthält {{ karten|length }} Lieder</p> >
<p><button id="play" onclick="abspielen()">Abspielen</button><button id="loop" onclick="looptrue()">Loop</button></p> <p>
Die Playlist {{liste}} ist insgesamt {{ gesamtLaenge | zeit }} lang und
enthält {{ karten|length }} Lieder
</p>
<p>
<button id="play" onclick="abspielen()">Abspielen</button
><button id="loop" onclick="looptrue()">Loop</button>
</p>
<div id="flex-container"> <div id="flex-container">
{% for karte in karten %} {% for karte in karten %} {% set karte_loop = loop %} {% include
{% set karte_loop = loop %} "karte.html" %} {% endfor %}
{% include "karte.html" %}
{% endfor %}
</div> </div>
<script src="static/script.js"></script> <script src="static/script.js"></script>

View file

@ -1,24 +1,42 @@
<article> <article>
<img src="{{ karte.img }}" /> <img src="{{ karte.img }}" />
{% if karte.ytid %} {% if karte.ytid %}
<p><button id="{{karte_loop.index0}}" onclick="vorherige(this.id)">Vorherige</button><button id="{{karte_loop.index0}}" onclick="abspielendiese(this.id)">Abspielen</button><button id="{{karte_loop.index0}}" onclick="nächste(this.id)">Nächstes</button></p> <p>
<audio controls src="/static/{{karte.datei}}"></audio> <button id="{{karte_loop.index0}}" onclick="vorherige(this.id)">
Vorherige</button
><button id="{{karte_loop.index0}}" onclick="abspielendiese(this.id)">
Abspielen</button
><button id="{{karte_loop.index0}}" onclick="nächste(this.id)">
Nächstes
</button>
</p>
<audio src="/static/{{karte.datei}}"></audio>
{% endif %} {% endif %}
<h2>{{ karte.titel}}</h2> <h2>{{ karte.titel}}</h2>
<p><b>Übersetzter Titel:</b>{{ karte.uetitel}}</p>
<p><b>Interpreten:</b>{{ karte.interprete}}</p>
{% if karte.jahrgang %} {% if karte.jahrgang %}
<p><b>Jahrgang:</b> {{ karte.jahrgang }}</p> <p><b>Jahrgang:</b> {{ karte.jahrgang }}</p>
{% endif %} {% endif %} {% if karte.plazirung%}
{% if karte.plazirung%}
<p><b>Plazirung:</b> {{ karte.plazirung }}</p> <p><b>Plazirung:</b> {{ karte.plazirung }}</p>
{% endif %} {% if karte.land %}
<p><b>Antretent für:</b> {{karte.land}}</p>
{% endif %} {% endif %}
<p><b>Interpret(en):</b> {{ karte.interprete}}</p>
<p><b>Länge:</b> {{karte.laenge|zeit}}</p> <p><b>Länge:</b> {{karte.laenge|zeit}}</p>
<p><a href="https://www.wikidata.org/entity/{{karte.wikiid}}">Q-id:</a> {{karte.wikiid}}</p> <p id="gray">
{% if karte.text %} {% if karte.text %}
<a href="{{ karte.text }}" target="_blank">Original Text</a> <a id="gray" href="{{ karte.text }}" target="_blank">Original Text</a>
{% endif %} {% endif %}
<a id="gray" href="https://www.wikidata.org/entity/{{karte.wikiid}}"
>Q-id:{{karte.wikiid}}</a
>
</p>
{% if admin %} {% if admin %}
<form method="post"><button name="index" value="{{karte_loop.index0}}">&lt;X&gt;</button></form> <form method="post">
<button name="index" value="{{karte_loop.index0}}">&lt;X&gt;</button>
</form>
{% endif %} {% endif %}
</article> </article>

View file

@ -1,8 +1,19 @@
<style> <style>
body{
display: block;
text-align: center;
}
form{ form{
display: block; display: block;
text-align: center; text-align: center;
color: black; color: black;
} }
#logo{
object-fit: scale-down;
}
#logocontaner{
margin: 3px;
}
</style> </style>
<a href="/" id="logocontaner"><img src="/static/Eurovision_Song_Contest_heart_Wikidata_(20142025).svg"></img></a>
<form><input name="name" value={{name}} placeholder="Name der Playlist"></form> <form><input name="name" value={{name}} placeholder="Name der Playlist"></form>

View file

@ -11,7 +11,14 @@
text-align: center; text-align: center;
font-size: smaller; font-size: smaller;
} }
#logo{
object-fit: scale-down;
}
#logocontaner{
margin: 3px;
}
</style> </style>
<a id="logocontaner"><img src="/static/Eurovision_Song_Contest_heart_Wikidata_(20142025).svg"></img></a>
{% for list in lists %} {% for list in lists %}
<a id="playlist" href="/?liste={{list}}"> {{list}} </a> <a id="playlist" href="/?liste={{list}}"> {{list}} </a>
{% endfor %} {% endfor %}

View file

@ -4,7 +4,14 @@
text-align: center; text-align: center;
color: black; color: black;
} }
#logo{
object-fit: scale-down;
}
#logocontaner{
margin: 3px;
}
</style> </style>
<a href="/" id="logocontaner"><img src="/static/Eurovision_Song_Contest_heart_Wikidata_(20142025).svg"></img></a>
{% if liste == empty %} {% if liste == empty %}
<p>Du musst etwas in die Playlist Screiben</p> <p>Du musst etwas in die Playlist Screiben</p>
{% endif %} {% endif %}