262 lines
10 KiB
Python
262 lines
10 KiB
Python
import json
|
||
import os
|
||
import subprocess
|
||
from glob import glob
|
||
|
||
import requests
|
||
from flask import Flask, redirect, render_template, request
|
||
|
||
|
||
def wikiapi(id, field):
|
||
if os.path.isdir("data"):
|
||
pass
|
||
else:
|
||
os.mkdir("data")
|
||
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):
|
||
mitpartsin = []
|
||
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",
|
||
},
|
||
)
|
||
for result in r.json()["results"]:
|
||
if getescedition(result["id"]):
|
||
mitpartsin.append(result)
|
||
else:
|
||
ohnepartsin.append(result)
|
||
return mitpartsin + ohnepartsin
|
||
|
||
|
||
def getescedition(songId):
|
||
statements = wikiapi(songId, "statements")
|
||
if "P1344" in statements:
|
||
for statement in statements["partsin"]:
|
||
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 + ".*")
|
||
if file != []:
|
||
audio = file[0].replace("static/", "")
|
||
else:
|
||
audio = None
|
||
print(audio)
|
||
return audio
|
||
|
||
|
||
def dateiNameFürListe(name):
|
||
name = name.replace("/", "%2F")
|
||
name = name + ".json"
|
||
return name
|
||
|
||
|
||
def kartenGeneriren(song):
|
||
id = song["wikiid"]
|
||
print(id)
|
||
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 "land" not in song and "P495" in statements:
|
||
song["land"] = wikiapi(statements["P495"][0]["value"]["content"], "labels")[
|
||
"de"
|
||
]
|
||
song["bild"] = (
|
||
"Flag_of_"
|
||
+ wikiapi(statements["P495"][0]["value"]["content"], "labels")["en"]
|
||
+ ".svg"
|
||
)
|
||
if "ytid" not in song and "P1651" in statements:
|
||
song["ytid"] = statements["P1651"][0]["value"]["content"]
|
||
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 "backimg" not in song and "P495" in statements:
|
||
song["backimg"] = (
|
||
f"https://commons.wikimedia.org/w/index.php?title=Special:Redirect/file/Flag_of_{wikiapi(statements['P495'][0]['value']['content'], 'labels')['en']}.svg&width=300"
|
||
)
|
||
print(song["backimg"])
|
||
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"
|
||
)
|
||
|
||
|
||
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():
|
||
liste = request.args.get("liste")
|
||
flag = request.args.get("flag")
|
||
if liste is None:
|
||
return redirect("/playlists")
|
||
with open(dateiNameFürListe(liste), "r") as f:
|
||
songs = json.load(f)
|
||
for song in songs:
|
||
kartenGeneriren(song)
|
||
gesamtLaenge = 0
|
||
for song in songs:
|
||
gesamtLaenge += song["laenge"]
|
||
return render_template(
|
||
"index.html", karten=songs, gesamtLaenge=gesamtLaenge, liste=liste, flag=flag
|
||
)
|
||
|
||
|
||
@app.route("/playlists")
|
||
def playlists():
|
||
listen = glob("*.json")
|
||
listen = (liste.replace(".json", "") for liste in listen)
|
||
return render_template("playlists.html", lists=listen)
|
||
|
||
|
||
@app.route("/neueliste")
|
||
def neueliste():
|
||
name = request.args.get("name")
|
||
if name is not None:
|
||
with open(dateiNameFürListe(name), "x") as f:
|
||
json.dump([], f)
|
||
return redirect("/?liste=" + name)
|
||
return render_template("neueliste.html", name=name)
|
||
|
||
|
||
@app.route("/suche")
|
||
def suche():
|
||
such = request.args.get("suche")
|
||
liste = request.args.get("liste")
|
||
if such is not None:
|
||
ergebnisse = wikisuche(such)
|
||
else:
|
||
ergebnisse = []
|
||
return render_template(
|
||
"suche.html", ergebnisse=ergebnisse, anfrage=such, liste=liste
|
||
)
|
||
|
||
|
||
@app.route("/suche", methods=["POST"])
|
||
def suche_finden():
|
||
liste = request.args.get("liste")
|
||
if liste:
|
||
with open(dateiNameFürListe(liste), "r") as f:
|
||
songs = json.load(f)
|
||
song = {"wikiid": request.form.get("id")}
|
||
kartenGeneriren(song)
|
||
songs.append(song)
|
||
with open(dateiNameFürListe(liste), "w") as f:
|
||
json.dump(songs, f, indent=2, ensure_ascii=False)
|
||
return redirect("/suche?liste=" + liste, 303)
|
||
else:
|
||
return redirect("/")
|
||
|
||
|
||
@app.route("/remove")
|
||
def admin():
|
||
liste = request.args.get("liste")
|
||
if liste is None:
|
||
return redirect("/playlists")
|
||
with open(dateiNameFürListe(liste), "r") as f:
|
||
songs = json.load(f)
|
||
for song in songs:
|
||
kartenGeneriren(song)
|
||
gesamtLaenge = 0
|
||
for song in songs:
|
||
gesamtLaenge += song["laenge"]
|
||
return render_template(
|
||
"index.html", karten=songs, gesamtLaenge=gesamtLaenge, liste=liste, admin=True
|
||
)
|
||
|
||
|
||
@app.route("/remove", methods=["POST"])
|
||
def loeschen():
|
||
liste = request.args.get("liste")
|
||
if not liste:
|
||
return "Du Musst eine Liste angeben", 400
|
||
song = request.form.get("index")
|
||
if song is None:
|
||
return "Kein Lied", 400
|
||
try:
|
||
song = int(song)
|
||
except TypeError:
|
||
return "Irgendwas ist GANZ falsch", 400
|
||
try:
|
||
with open(dateiNameFürListe(liste), "r+") as f:
|
||
songs = json.load(f)
|
||
if len(songs) < song + 1:
|
||
return "Das Lied Gibt es Nicht", 400
|
||
del songs[song]
|
||
f.seek(0)
|
||
json.dump(songs, f, indent=2, ensure_ascii=False)
|
||
f.truncate()
|
||
return redirect("/remove?liste=" + liste, 303)
|
||
except FileNotFoundError:
|
||
return "Die Liste Ist nicht da (Du kannst Sie anlegen)", 400
|