This commit is contained in:
Mat12143 2025-08-01 22:17:32 +02:00
commit ebabe54b09
3 changed files with 99 additions and 18 deletions

View file

@ -1,4 +1,5 @@
Flask==3.1.0 Flask==3.1.0
flask-cors flask-cors
flask-socketio
dotenv dotenv
requests requests

View file

@ -1,6 +1,8 @@
import dotenv import dotenv
from flask import Flask, Response, jsonify, request from flask import Flask, Response, jsonify, request
from flask_cors import CORS from flask_cors import CORS
from flask_socketio import SocketIO, emit
from .room import Room from .room import Room
from .song import Song, init_db from .song import Song, init_db
@ -11,6 +13,8 @@ dotenv.load_dotenv()
app = Flask(__name__) app = Flask(__name__)
app.config["SECRET_KEY"] = "your_secret_key"
socketio = SocketIO(app)
CORS(app) CORS(app)
@ -24,6 +28,7 @@ ROOMS: dict[int, Room] = {
{}, {},
[], [],
[Song(mbid="test", title="<title placeholder>", artist="<artist placeholder>", tags=["Metal"], image_id="img-id", youtube_id="yt-id")], [Song(mbid="test", title="<title placeholder>", artist="<artist placeholder>", tags=["Metal"], image_id="img-id", youtube_id="yt-id")],
playing_idx=1,
) )
} # { room_id: room, ... } } # { room_id: room, ... }
@ -63,13 +68,27 @@ def queue():
@app.post("/api/queue/next") @app.post("/api/queue/next")
def queue_next(): ... def queue_next():
if (room_id := request.args.get("room")) is None:
return error("Missing room id")
if (room := ROOMS.get(int(room_id))) is None:
return error("Invalid room")
@app.post("/api/queue/renew") room.playing_idx += 1
def queue_renew(): ...
if room.playing_idx >= len(room.playing):
## queue ended
# room.renew_queue()
emit("update_songs", {"songs": [1, 2, 3]}, broadcast=True, namespace="/")
return {"success": True, "ended": True, "index": room.playing_idx, "queue": []}
return {"success": True, "ended": False, "index": room.playing_idx}
init_db() init_db()
exit()
if __name__ == "__main__": if __name__ == "__main__":
app.run(debug=True) socketio.run(app, debug=True)

View file

@ -1,3 +1,4 @@
import random
from dataclasses import dataclass from dataclasses import dataclass
from .song import Song from .song import Song
@ -13,6 +14,18 @@ RECENT_COUNT = 10
type UserScoredSong = tuple[Song, int] type UserScoredSong = tuple[Song, int]
@dataclass
class Rank:
user_score: float
tag: float
artist: float
random: float
recent_penalty: float
def total(self) -> float:
return self.user_score + self.tag + self.artist + self.random - self.recent_penalty
@dataclass @dataclass
class Room: class Room:
id: int id: int
@ -24,42 +37,90 @@ class Room:
songs: dict[str, UserScoredSong] # canzoni + voto songs: dict[str, UserScoredSong] # canzoni + voto
history: list[Song] # canzoni riprodotte (in ordine) history: list[Song] # canzoni riprodotte (in ordine)
playing: list[Song] # canzoni che sono i riproduzione playing: list[Song] # canzoni che sono i riproduzione
playing_idx: int
def rank_song(self, song: Song, user_score: int) -> float: def rank_song_from_id(self, id: str) -> Rank:
rank = 0.0 scored = self.songs[id]
return self.rank_song(scored[0], scored[1])
def rank_song(self, song: Song, user_score: int) -> Rank:
song_items = self.songs.items() song_items = self.songs.items()
lowest_score = min(song_items, key=lambda item: item[1][1])[1][1] lowest_score = min(song_items, key=lambda item: item[1][1])[1][1]
highest_score = min(song_items, key=lambda item: item[1][1])[1][1] highest_score = max(song_items, key=lambda item: item[1][1])[1][1]
rank += translate(user_score, lowest_score, highest_score, 0.0, USER_SCORE_WEIGHT) score_rank = translate(user_score, lowest_score, highest_score, 0.0, USER_SCORE_WEIGHT)
recent_songs = self.history[-RECENT_COUNT:] recent_songs = self.history[-RECENT_COUNT:]
tag_counts = {} tag_counts = {}
artist_counts = {} artist_counts = {}
for song in recent_songs: for recent_song in recent_songs:
for tag in song.tags: for tag in recent_song.tags:
if tag not in tag_counts: if tag not in tag_counts:
tag_counts[tag] = 0 tag_counts[tag] = 0
tag_counts[tag] += 1 tag_counts[tag] += 1
if song.artist not in artist_counts: if recent_song.artist not in artist_counts:
artist_counts[song.artist] = 0 artist_counts[recent_song.artist] = 0
artist_counts[song.artist] += 1 artist_counts[recent_song.artist] += 1
tag_total = 0 tag_total = 0
for tag in song.tags: for tag in song.tags:
if tag in tag_counts: if tag in tag_counts:
tag_total += tag_counts[tag] tag_total += tag_counts[tag]
rank += translate(tag_total, 0, RECENT_COUNT, 0, TAG_WEIGHT) artist_total = artist_counts[song.artist] if song.artist in artist_counts else 0
rank += translate(artist_counts[song.artist], 0, RECENT_COUNT, 0, ARTIST_WEIGHT)
if song in recent_songs: tag_value = min(RECENT_COUNT, len(self.history)) - tag_total
rank -= RECENT_PENALTY artist_value = min(RECENT_COUNT, len(self.history)) - artist_total
return rank tag_rank = translate(tag_value, 0, min(RECENT_COUNT, len(self.history)), 0, TAG_WEIGHT)
artist_rank = translate(artist_value, 0, min(RECENT_COUNT, len(self.history)), 0, ARTIST_WEIGHT)
random_rank = translate(random.random(), 0, 1, 0.0, RANDOM_WEIGHT)
recent_penalty = RECENT_PENALTY if song in recent_songs else 0
return Rank(score_rank, tag_rank, artist_rank, random_rank, recent_penalty)
def translate(value: float, in_min: float, in_max: float, out_min: float, out_max: float): def translate(value: float, in_min: float, in_max: float, out_min: float, out_max: float):
if in_max == in_min:
return out_min
return (value - in_min) / (in_max - in_min) * (out_max - out_min) + out_min return (value - in_min) / (in_max - in_min) * (out_max - out_min) + out_min
def test_algo():
songs = [
Song("paulham", "Io e i miei banchi", "Paul Ham", ["pop"], "", ""),
Song("cisco", "CiscoPT", "Cantarex", ["rap"], "", ""),
Song("vpn", "VPN", "Cantarex", ["rap"], "", ""),
Song("gang", "Gang Gang Gang", "Cantarex", ["rap"], "", ""),
Song("bertha1", "Rindondantha", "Berthanetti", ["rock"], "", ""),
Song("bertha2", "Ragatthi", "Berthanetti", ["rock"], "", ""),
Song("bertha3", "Tranthathione", "Berthanetti", ["rock"], "", ""),
Song("cexx", "Spritz", "Cex", ["kpop"], "", ""),
]
room = Room(
123,
(0.0, 0.0),
"test",
None,
set(["rock", "rap"]),
{
"paulham": (songs[0], 2),
"cisco": (songs[1], 1),
"vpn": (songs[2], 5),
"gang": (songs[3], 1),
"bertha1": (songs[4], 1),
"bertha2": (songs[5], 1),
"bertha3": (songs[6], 1),
"cexx": (songs[7], -123123),
},
[songs[4], songs[5], songs[0]],
)
print(room.rank_song_from_id("paulham"), room.rank_song_from_id("paulham").total())
print(room.rank_song_from_id("vpn"), room.rank_song_from_id("vpn").total())
print(room.rank_song_from_id("cexx"), room.rank_song_from_id("cexx").total())