modified: .env.example

modified:   Dockerfile
	modified:   app.py
	new file:   locales/de-DE.json
	modified:   templates/login.html
	modified:   templates/playlists.html
	modified:   templates/quiz.html
This commit is contained in:
SimolZimol
2025-05-19 17:39:11 +02:00
parent 53e669b5c1
commit d38254bc3c
7 changed files with 69 additions and 23 deletions

View File

@@ -7,4 +7,6 @@ SPOTIPY_REDIRECT_URI=http://localhost:5000/callback
SECRET_KEY=dein_geheimer_flask_key
# Flask Umgebung (optional)
FLASK_ENV=development
FLASK_ENV=development
LANG=de-DE

View File

@@ -17,6 +17,7 @@ ENV SPOTIPY_CLIENT_ID=$SPOTIPY_CLIENT_ID
ENV SPOTIPY_CLIENT_SECRET=$SPOTIPY_CLIENT_SECRET
ENV SPOTIPY_REDIRECT_URI=$SPOTIPY_REDIRECT_URI
ENV FLASK_ENV=development
ENV LANG=$LANG
# Starten mit Gunicorn für Production
CMD ["python", "app.py"]

18
app.py
View File

@@ -9,6 +9,7 @@ from spotipy.oauth2 import SpotifyOAuth
import random
from difflib import SequenceMatcher
import re
import json
app = Flask(__name__)
app.secret_key = os.getenv("SECRET_KEY")
@@ -16,6 +17,20 @@ app.secret_key = os.getenv("SECRET_KEY")
# Erweiterte Berechtigungen für Web Playback SDK
SCOPE = "user-library-read playlist-read-private streaming user-read-email user-read-private"
def get_locale():
return os.getenv("LANG", "de-DE")
def get_translations():
lang = get_locale()
path = os.path.join(os.path.dirname(__file__), "locales", f"{lang}.json")
try:
with open(path, encoding="utf-8") as f:
return json.load(f)
except Exception:
# Fallback auf Deutsch
with open(os.path.join(os.path.dirname(__file__), "locales", "de-DE.json"), encoding="utf-8") as f:
return json.load(f)
def get_spotify_client():
token_info = session.get("token_info", None)
if not token_info:
@@ -150,7 +165,8 @@ def quiz(playlist_id):
question_number=len(played_tracks),
total_questions=len(tracks),
score=score,
answered=answered
answered=answered,
translations=get_translations()
)
@app.route("/search_track", methods=["POST"])

24
locales/de-DE.json Normal file
View File

@@ -0,0 +1,24 @@
{
"login_title": "Login mit Spotify",
"login_button": "Mit Spotify einloggen",
"quiz_title": "Musik Quiz",
"choose_playlist": "Wähle eine Playlist:",
"guess_artist": "Künstler erraten",
"guess_title": "Titel erraten",
"guess_year": "Jahr erraten",
"question_artist": "Wer ist der Künstler dieses Songs?",
"question_title": "Wie heißt dieser Song?",
"question_year": "In welchem Jahr wurde dieser Song veröffentlicht?",
"input_artist": "Künstlername eingeben...",
"input_title": "Songtitel eingeben...",
"input_year": "Jahr eingeben...",
"answer_button": "Antworten",
"next_question": "Nächste Frage",
"quiz_end": "Quiz beenden",
"tip_artist": "Tipp: Gib den Namen des Künstlers ein, der diesen Song performt.",
"tip_title": "Tipp: Gib den Titel des Songs ein, den du gerade hörst.",
"tip_year": "Tipp: Gib das Erscheinungsjahr des Songs ein.",
"correct": "Richtig! 🎉",
"wrong": "Falsch 😢",
"right_answer": "Die richtige Antwort ist:"
}

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>Login mit Spotify</title>
<title>{{ translations['login_title'] }}</title>
<style>
body {
background: linear-gradient(135deg, #1DB954 0%, #191414 100%);
@@ -46,7 +46,7 @@
<body>
<div class="login-container">
<h1>Quizify Musik Quiz</h1>
<a href="/login" class="button">Mit Spotify einloggen</a>
<a href="/login" class="button">{{ translations['login_button'] }}</a>
</div>
</body>
</html>

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>Deine Playlists</title>
<title>{{ translations['quiz_title'] }}</title>
<style>
body {
background: linear-gradient(135deg, #191414 0%, #1DB954 100%);
@@ -55,7 +55,7 @@
</head>
<body>
<div class="playlist-container">
<h2>Wähle eine Playlist:</h2>
<h2>{{ translations['choose_playlist'] }}</h2>
<ul>
{% for pl in playlists %}
<li><a class="playlist-link" href="/quiz/{{ pl.id }}">{{ pl.name }}</a></li>

View File

@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>Musik Quiz</title>
<title>{{ translations['quiz_title'] }}</title>
<!-- Spotify Web Playback SDK -->
<script src="https://sdk.scdn.co/spotify-player.js"></script>
<style>
@@ -104,6 +104,9 @@
let currentGameMode = "{{ game_mode }}";
let correctAnswer = "";
// translations für JS verfügbar machen
const i18n = {{ translations|tojson }};
// Wird aufgerufen, wenn Spotify Web Playback SDK geladen ist
window.onSpotifyWebPlaybackSDKReady = () => {
const token = '{{ access_token }}';
@@ -184,16 +187,16 @@
function setCorrectAnswer() {
if (currentGameMode === 'artist') {
correctAnswer = "{{ track.artists[0].name }}";
document.getElementById('question-text').innerText = "Wer ist der Künstler dieses Songs?";
document.getElementById('answerInput').placeholder = "Künstlername eingeben...";
document.getElementById('question-text').innerText = i18n.question_artist;
document.getElementById('answerInput').placeholder = i18n.input_artist;
} else if (currentGameMode === 'title') {
correctAnswer = "{{ track.name }}";
document.getElementById('question-text').innerText = "Wie heißt dieser Song?";
document.getElementById('answerInput').placeholder = "Songtitel eingeben...";
document.getElementById('question-text').innerText = i18n.question_title;
document.getElementById('answerInput').placeholder = i18n.input_title;
} else if (currentGameMode === 'year') {
correctAnswer = "{{ track.album.release_date[:4] }}";
document.getElementById('question-text').innerText = "In welchem Jahr wurde dieser Song veröffentlicht?";
document.getElementById('answerInput').placeholder = "Jahr eingeben...";
document.getElementById('question-text').innerText = i18n.question_year;
document.getElementById('answerInput').placeholder = i18n.input_year;
document.getElementById('answerInput').type = "number";
}
}
@@ -332,16 +335,16 @@ window.onload = function() {
<div style="text-align:center; margin-bottom: 20px;">
<a href="/reset_quiz/{{ playlist_id }}" class="btn btn-danger" style="margin-top:10px;">Quiz beenden</a>
</div>
<h2 id="question-text">Wer ist der Künstler dieses Songs?</h2>
<h2 id="question-text">{{ translations['question_artist'] }}</h2>
<!-- Verstecktes Feld für device_id -->
<input type="hidden" id="device_id" value="">
<!-- Spielmodi -->
<div class="game-modes">
<button class="btn {{ 'btn-success' if game_mode == 'artist' else 'btn-secondary' }}" onclick="switchGameMode('artist')">Künstler erraten</button>
<button class="btn {{ 'btn-success' if game_mode == 'title' else 'btn-secondary' }}" onclick="switchGameMode('title')">Titel erraten</button>
<button class="btn {{ 'btn-success' if game_mode == 'year' else 'btn-secondary' }}" onclick="switchGameMode('year')">Jahr erraten</button>
<button class="btn {{ 'btn-success' if game_mode == 'artist' else 'btn-secondary' }}" onclick="switchGameMode('artist')">{{ translations['guess_artist'] }}</button>
<button class="btn {{ 'btn-success' if game_mode == 'title' else 'btn-secondary' }}" onclick="switchGameMode('title')">{{ translations['guess_title'] }}</button>
<button class="btn {{ 'btn-success' if game_mode == 'year' else 'btn-secondary' }}" onclick="switchGameMode('year')">{{ translations['guess_year'] }}</button>
</div>
<!-- Optionen für das Spiel -->
@@ -369,8 +372,8 @@ window.onload = function() {
<!-- Antwort-Eingabe -->
<div style="text-align: center; margin-top: 30px;">
<input type="text" id="answerInput" placeholder="Gib deine Antwort ein..." oninput="searchTracks()">
<button class="btn" onclick="checkAnswer()">Antworten</button>
<input type="text" id="answerInput" placeholder="{{ translations['input_artist'] }}" oninput="searchTracks()">
<button class="btn" onclick="checkAnswer()">{{ translations['answer_button'] }}</button>
<!-- Suchergebnisse -->
<div id="searchResults" class="search-results"></div>
@@ -379,17 +382,17 @@ window.onload = function() {
<div id="resultContainer" class="result-container"></div>
<!-- Nächste Frage Button, wird nach Antwort angezeigt -->
<a id="nextQuestionBtn" href="/quiz/{{ playlist_id }}?mode={{ game_mode }}" class="btn" style="display: none;">Nächste Frage</a>
<a id="nextQuestionBtn" href="/quiz/{{ playlist_id }}?mode={{ game_mode }}" class="btn" style="display: none;">{{ translations['next_question'] }}</a>
</div>
<!-- Hilfe-Text je nach Modus -->
<div class="hint-container">
{% if game_mode == 'artist' %}
<p>Tipp: Gib den Namen des Künstlers ein, der diesen Song performt.</p>
<p>{{ translations['tip_artist'] }}</p>
{% elif game_mode == 'title' %}
<p>Tipp: Gib den Titel des Songs ein, den du gerade hörst.</p>
<p>{{ translations['tip_title'] }}</p>
{% elif game_mode == 'year' %}
<p>Tipp: Gib das Erscheinungsjahr des Songs ein.</p>
<p>{{ translations['tip_year'] }}</p>
{% endif %}
</div>
</body>