team-1/backend/src/app.py

152 lines
3.9 KiB
Python
Raw Normal View History

2025-08-01 20:59:09 +02:00
import dotenv
2025-08-01 18:46:38 +02:00
from flask import Flask, Response, jsonify, request
2025-08-01 18:07:11 +02:00
from flask_cors import CORS
2025-08-01 22:07:39 +02:00
from flask_socketio import SocketIO, emit
2025-08-01 19:16:20 +02:00
2025-08-01 23:29:40 +02:00
from .state import State
from .connect import get_connection
2025-08-01 19:16:20 +02:00
from .room import Room
2025-08-01 23:23:00 +02:00
from .song import Song, init_db, get_song_by_title_artist, add_song_in_db
from .song_fetch import lastfm_query_search, download_song_mp3
2025-08-01 18:07:11 +02:00
2025-08-01 19:13:12 +02:00
dotenv.load_dotenv()
2025-08-01 19:16:20 +02:00
2025-08-01 18:23:27 +02:00
2025-08-01 18:07:11 +02:00
app = Flask(__name__)
2025-08-01 22:07:39 +02:00
app.config["SECRET_KEY"] = "your_secret_key"
socketio = SocketIO(app)
2025-08-01 18:07:11 +02:00
CORS(app)
2025-08-01 23:07:00 +02:00
db_conn = get_connection()
state = State(app, db_conn.cursor())
init_db(state.db)
2025-08-01 18:23:27 +02:00
def error(msg: str, status: int = 400) -> Response:
res = jsonify({"success": False, "error": msg})
res.status_code = status
return res
2025-08-01 21:39:46 +02:00
@app.get("/api/join")
2025-08-01 18:23:27 +02:00
def join():
room_id = request.args.get("room")
code = request.args.get("code")
if room_id is None:
return error("Missing room id")
2025-08-01 23:07:00 +02:00
if (room := state.rooms.get(int(room_id))) is None:
2025-08-01 18:23:27 +02:00
return error("Invalid room")
if room.pin is not None and room.pin != code:
return error("Invalid code")
return {"success": True, "ws": f"/ws/{room_id}"}
2025-08-01 21:39:46 +02:00
@app.get("/api/queue")
def queue():
if (room_id := request.args.get("room")) is None:
return error("Missing room id")
2025-08-01 23:07:00 +02:00
if (room := state.rooms.get(int(room_id))) is None:
2025-08-01 21:39:46 +02:00
return error("Invalid room")
2025-08-01 23:32:48 +02:00
return {"success": True, "queue": room.playing, "index": room.playing_idx}
2025-08-01 21:39:46 +02:00
@app.post("/api/queue/next")
2025-08-01 22:07:39 +02:00
def queue_next():
if (room_id := request.args.get("room")) is None:
return error("Missing room id")
2025-08-01 23:07:00 +02:00
if (room := state.rooms.get(int(room_id))) is None:
2025-08-01 22:07:39 +02:00
return error("Invalid room")
room.playing_idx += 1
if room.playing_idx >= len(room.playing):
## queue ended
# room.renew_queue()
emit("update_songs", {"songs": [1, 2, 3]}, broadcast=True, namespace="/")
2025-08-01 21:39:46 +02:00
return {"success": True, "ended": True, "index": room.playing_idx, "queue": room.playing}
2025-08-01 21:39:46 +02:00
2025-08-01 22:07:39 +02:00
return {"success": True, "ended": False, "index": room.playing_idx}
2025-08-01 21:39:46 +02:00
@app.post("/api/room/new")
def room_new():
if (room_name := request.args.get("name")) is None:
return error("Missing room name")
if (room_cords := request.args.get("coords")) is None:
return error("Missing room coords")
if room_pin := request.args.get("pin"):
room_pin = int(room_pin)
else:
room_pin = None
lat, lon = room_cords.split(",")
room = Room(
2025-08-01 23:07:00 +02:00
id=max(state.rooms or [0]) + 1, #
coord=(float(lat), float(lon)),
name=room_name,
pin=room_pin,
tags=set([tag for tag in request.args.get("tags", "").split(",") if tag]),
songs={},
history=[],
playing=[],
playing_idx=-1,
)
2025-08-01 23:07:00 +02:00
state.rooms[room.id] = room
return {"success": True, "room_id": room.id}
@app.get("/api/room")
def room():
return [
{
"id": room.id,
"name": room.name,
"private": room.pin is not None,
"coords": room.coord,
}
2025-08-01 23:07:00 +02:00
for room in state.rooms.values()
]
2025-08-01 23:23:00 +02:00
@app.post("/api/addsong")
def add_song():
if (room_id := request.args.get("room")) is None:
return error("Missing room id")
if (room := state.rooms.get(int(room_id))) is None:
2025-08-01 23:23:00 +02:00
return error("Invalid room")
if (query := request.args.get("query")) is None:
return error("Missing query")
info = lastfm_query_search(query)
if (song := get_song_by_title_artist(info.title, info.artist)) is None:
res = download_song_mp3(info.title, info.artist)
if res is None:
return error("Cannot get info from YT")
2025-08-01 23:23:00 +02:00
yt_id, _ = res
## song not found, downolad from YT
## add in DB
add_song_in_db(info.artist, info.title, info.tags, info.img_id, yt_id)
return {"artist": info.artist, "title": info.title, "tags": info.tags, "image_id": info.img_id}
2025-08-01 18:07:11 +02:00
if __name__ == "__main__":
2025-08-01 22:07:39 +02:00
socketio.run(app, debug=True)