init
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
from flask_socketio import emit, join_room
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from .. import socketio
|
||||
from ..models import db
|
||||
from ..models.session import Session, Vote
|
||||
|
||||
|
||||
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",
|
||||
{
|
||||
"code": session.code,
|
||||
"status": session.status,
|
||||
"currentRecipeIndex": session.current_recipe_index,
|
||||
"matchedRecipeId": session.matched_recipe_id,
|
||||
"participants": [
|
||||
{"id": p.id, "name": p.name, "isHost": p.is_host}
|
||||
for p in session.participants
|
||||
],
|
||||
},
|
||||
room=room_name(session.code),
|
||||
)
|
||||
|
||||
|
||||
@socketio.on("session:subscribe")
|
||||
def subscribe(data):
|
||||
code = data.get("code", "").upper()
|
||||
session = Session.query.filter_by(code=code).first()
|
||||
if not session:
|
||||
emit("error", {"message": "Session nicht gefunden."})
|
||||
return
|
||||
|
||||
join_room(room_name(code))
|
||||
emit_session_update(session)
|
||||
|
||||
|
||||
@socketio.on("session:start")
|
||||
def start_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 starten."})
|
||||
return
|
||||
|
||||
session.status = "running"
|
||||
session.current_recipe_index = 0
|
||||
db.session.commit()
|
||||
emit_session_update(session)
|
||||
|
||||
|
||||
@socketio.on("vote")
|
||||
def vote(data):
|
||||
code = data.get("code", "").upper()
|
||||
participant_id = data.get("participantId")
|
||||
recipe_id = data.get("recipeId")
|
||||
vote_value = data.get("vote")
|
||||
|
||||
if vote_value not in ["yes", "no"]:
|
||||
emit("error", {"message": "Ungültige Stimme."})
|
||||
return
|
||||
|
||||
session = Session.query.filter_by(code=code).first()
|
||||
if not session or session.status != "running":
|
||||
emit("error", {"message": "Session läuft nicht."})
|
||||
return
|
||||
|
||||
recipe = next((r for r in session.recipes if r.id == recipe_id), None)
|
||||
if not recipe:
|
||||
emit("error", {"message": "Rezept nicht gefunden."})
|
||||
return
|
||||
|
||||
db.session.add(Vote(session_id=session.id, participant_id=participant_id, recipe_id=recipe.id, vote=vote_value))
|
||||
try:
|
||||
db.session.commit()
|
||||
except IntegrityError:
|
||||
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 yes_count == participant_count:
|
||||
session.status = "finished"
|
||||
session.matched_recipe_id = recipe.id
|
||||
db.session.commit()
|
||||
socketio.emit("session:match", {"recipe": serialize_recipe(recipe)}, room=room_name(code))
|
||||
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)
|
||||
Reference in New Issue
Block a user