This commit is contained in:
2026-06-09 23:10:17 +02:00
parent 7b3b9a890f
commit 90e5f61b91
15 changed files with 911 additions and 86 deletions
+96 -21
View File
@@ -3,23 +3,15 @@ from sqlalchemy.exc import IntegrityError
from .. import socketio
from ..models import db
from ..models.session import Session, Vote
from ..services.match_modes import handle_final_round_vote, is_final_round_mode
from ..services.session_recipes import add_recipe_batch, replace_recipe_batch, serialize_recipe
from ..services.session_settings import get_match_mode, get_required_likes, get_voting_round, set_match_mode, set_required_likes, set_voting_round
def room_name(code):
return f"session:{code.upper()}"
def serialize_recipe(recipe):
return {
"id": recipe.id,
"title": recipe.title,
"url": recipe.url,
"imageUrl": recipe.image_url,
"meta": recipe.meta,
"position": recipe.position,
}
def emit_session_update(session):
socketio.emit(
"session:update",
@@ -32,6 +24,10 @@ def emit_session_update(session):
{"id": p.id, "name": p.name, "isHost": p.is_host}
for p in session.participants
],
"recipes": [serialize_recipe(recipe) for recipe in session.recipes],
"requiredLikes": get_required_likes(session),
"matchMode": get_match_mode(session),
"votingRound": get_voting_round(session),
},
room=room_name(session.code),
)
@@ -65,6 +61,76 @@ def start_session(data):
session.status = "running"
session.current_recipe_index = 0
session.matched_recipe_id = None
set_voting_round(session, 1)
db.session.commit()
emit_session_update(session)
@socketio.on("session:set_required_likes")
def update_required_likes(data):
code = data.get("code", "").upper()
participant_id = data.get("participantId")
session = Session.query.filter_by(code=code).first()
if not session:
emit("error", {"message": "Session nicht gefunden."})
return
host = next((p for p in session.participants if p.id == participant_id and p.is_host), None)
if not host:
emit("error", {"message": "Nur der Host kann die Match-Regel ändern."})
return
if session.status != "waiting":
emit("error", {"message": "Die Match-Regel kann nur in der Lobby geändert werden."})
return
set_required_likes(session, data.get("requiredLikes", len(session.participants)))
db.session.commit()
emit_session_update(session)
@socketio.on("session:set_match_mode")
def update_match_mode(data):
code = data.get("code", "").upper()
participant_id = data.get("participantId")
session = Session.query.filter_by(code=code).first()
if not session:
emit("error", {"message": "Session nicht gefunden."})
return
host = next((p for p in session.participants if p.id == participant_id and p.is_host), None)
if not host:
emit("error", {"message": "Nur der Host kann den Modus ändern."})
return
if session.status != "waiting":
emit("error", {"message": "Der Modus kann nur in der Lobby geändert werden."})
return
set_match_mode(session, data.get("matchMode"))
db.session.commit()
emit_session_update(session)
@socketio.on("session:restart")
def restart_session(data):
code = data.get("code", "").upper()
participant_id = data.get("participantId")
session = Session.query.filter_by(code=code).first()
if not session:
emit("error", {"message": "Session nicht gefunden."})
return
host = next((p for p in session.participants if p.id == participant_id and p.is_host), None)
if not host:
emit("error", {"message": "Nur der Host kann neu starten."})
return
session.status = "running"
session.current_recipe_index = 0
set_voting_round(session, 1)
replace_recipe_batch(session)
db.session.commit()
emit_session_update(session)
@@ -97,11 +163,17 @@ def vote(data):
db.session.rollback()
return
participant_count = len(session.participants)
yes_count = Vote.query.filter_by(session_id=session.id, recipe_id=recipe.id, vote="yes").count()
vote_count = Vote.query.filter_by(session_id=session.id, recipe_id=recipe.id).count()
if is_final_round_mode(session):
result = handle_final_round_vote(session, recipe)
db.session.commit()
if result == "match":
matched_recipe = next((r for r in session.recipes if r.id == session.matched_recipe_id), recipe)
socketio.emit("session:match", {"recipe": serialize_recipe(matched_recipe)}, room=room_name(code))
emit_session_update(session)
return
if yes_count == participant_count:
yes_count = Vote.query.filter_by(session_id=session.id, recipe_id=recipe.id, vote="yes").count()
if yes_count >= get_required_likes(session):
session.status = "finished"
session.matched_recipe_id = recipe.id
db.session.commit()
@@ -109,9 +181,12 @@ def vote(data):
emit_session_update(session)
return
if vote_count == participant_count:
session.current_recipe_index += 1
if session.current_recipe_index >= len(session.recipes):
session.status = "finished"
db.session.commit()
emit_session_update(session)
participant_vote_count = Vote.query.filter_by(
session_id=session.id,
participant_id=participant_id,
).count()
if participant_vote_count >= len(session.recipes):
add_recipe_batch(session)
db.session.commit()
emit_session_update(session)