refactor(gameplay): extract start/show transitions from lobby views
This commit is contained in:
124
lobby/views.py
124
lobby/views.py
@@ -1,7 +1,7 @@
|
||||
import json
|
||||
import random
|
||||
from datetime import timedelta
|
||||
|
||||
import json
|
||||
import random
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.db import IntegrityError, transaction
|
||||
from django.http import HttpRequest, JsonResponse
|
||||
@@ -11,14 +11,10 @@ from django.views.decorators.http import require_GET, require_POST
|
||||
from fupogfakta.models import Category, GameSession, Guess, LieAnswer, Player, Question, RoundConfig, RoundQuestion, ScoreEvent
|
||||
from fupogfakta.payloads import (
|
||||
build_leaderboard as _build_leaderboard,
|
||||
build_lie_started_payload as _build_lie_started_payload,
|
||||
build_phase_view_model as _build_phase_view_model,
|
||||
build_question_shown_payload as _build_question_shown_payload,
|
||||
build_question_shown_response as _build_question_shown_response,
|
||||
build_reveal_payload as _build_reveal_payload,
|
||||
build_round_question_payload as _build_round_question_payload,
|
||||
build_scoreboard_phase_event as _build_scoreboard_phase_event,
|
||||
build_start_round_response as _build_start_round_response,
|
||||
)
|
||||
from fupogfakta.services import (
|
||||
finish_game as _finish_game,
|
||||
@@ -27,7 +23,9 @@ from fupogfakta.services import (
|
||||
promote_reveal_to_scoreboard as _promote_reveal_to_scoreboard,
|
||||
resolve_scores as _resolve_scores,
|
||||
select_round_question as _select_round_question,
|
||||
show_question as _show_question,
|
||||
start_next_round as _start_next_round,
|
||||
start_round as _start_round,
|
||||
)
|
||||
from realtime.broadcast import sync_broadcast_phase_event
|
||||
|
||||
@@ -255,72 +253,23 @@ def start_round(request: HttpRequest, code: str) -> JsonResponse:
|
||||
status=403,
|
||||
)
|
||||
|
||||
if session.status != GameSession.Status.LOBBY:
|
||||
return api_error(
|
||||
request,
|
||||
code="round_start_invalid_phase",
|
||||
status=400,
|
||||
)
|
||||
|
||||
try:
|
||||
category = Category.objects.get(slug=category_slug, is_active=True)
|
||||
except Category.DoesNotExist:
|
||||
return api_error(
|
||||
request,
|
||||
code="category_not_found",
|
||||
status=404,
|
||||
)
|
||||
|
||||
if not Question.objects.filter(category=category, is_active=True).exists():
|
||||
return api_error(
|
||||
request,
|
||||
code="category_has_no_questions",
|
||||
status=400,
|
||||
)
|
||||
|
||||
with transaction.atomic():
|
||||
session = GameSession.objects.select_for_update().get(pk=session.pk)
|
||||
if session.status != GameSession.Status.LOBBY:
|
||||
return api_error(
|
||||
request,
|
||||
code="round_start_invalid_phase",
|
||||
status=400,
|
||||
)
|
||||
|
||||
if RoundConfig.objects.filter(session=session, number=session.current_round).exists():
|
||||
return api_error(
|
||||
request,
|
||||
code="round_already_configured",
|
||||
status=409,
|
||||
)
|
||||
|
||||
round_config = RoundConfig(
|
||||
session=session,
|
||||
number=session.current_round,
|
||||
category=category,
|
||||
)
|
||||
|
||||
try:
|
||||
round_question = _select_round_question(session, round_config)
|
||||
except ValueError as exc:
|
||||
return api_error(request, code=str(exc), status=400)
|
||||
|
||||
round_config.save()
|
||||
session.status = GameSession.Status.LIE
|
||||
session.save(update_fields=["status"])
|
||||
|
||||
lie_started_payload = _build_lie_started_payload(session, round_config, round_question)
|
||||
transition = _start_round(session, category_slug)
|
||||
except ValueError as exc:
|
||||
error_code = str(exc)
|
||||
error_status = {
|
||||
"category_not_found": 404,
|
||||
"round_already_configured": 409,
|
||||
}.get(error_code, 400)
|
||||
return api_error(request, code=error_code, status=error_status)
|
||||
|
||||
sync_broadcast_phase_event(
|
||||
session.code,
|
||||
"phase.lie_started",
|
||||
lie_started_payload,
|
||||
transition.session.code,
|
||||
transition.phase_event_name,
|
||||
transition.phase_event_payload,
|
||||
)
|
||||
|
||||
return JsonResponse(
|
||||
_build_start_round_response(session, round_config, round_question),
|
||||
status=201,
|
||||
)
|
||||
return JsonResponse(transition.response_payload, status=201)
|
||||
|
||||
|
||||
@require_POST
|
||||
@@ -344,45 +293,18 @@ def show_question(request: HttpRequest, code: str) -> JsonResponse:
|
||||
status=403,
|
||||
)
|
||||
|
||||
if session.status != GameSession.Status.LIE:
|
||||
return api_error(
|
||||
request,
|
||||
code="show_question_invalid_phase",
|
||||
status=400,
|
||||
)
|
||||
|
||||
try:
|
||||
round_config = RoundConfig.objects.get(session=session, number=session.current_round)
|
||||
except RoundConfig.DoesNotExist:
|
||||
return api_error(
|
||||
request,
|
||||
code="round_config_missing",
|
||||
status=400,
|
||||
)
|
||||
|
||||
existing_round_question = _get_current_round_question(session)
|
||||
if existing_round_question is not None:
|
||||
round_question = existing_round_question
|
||||
else:
|
||||
try:
|
||||
round_question = _select_round_question(session, round_config)
|
||||
except ValueError as exc:
|
||||
return api_error(request, code=str(exc), status=400)
|
||||
|
||||
lie_deadline_at = round_question.shown_at + timedelta(seconds=round_config.lie_seconds)
|
||||
|
||||
lie_deadline_iso = lie_deadline_at.isoformat()
|
||||
transition = _show_question(session)
|
||||
except ValueError as exc:
|
||||
return api_error(request, code=str(exc), status=400)
|
||||
|
||||
sync_broadcast_phase_event(
|
||||
session.code,
|
||||
"phase.question_shown",
|
||||
_build_question_shown_payload(round_question, lie_deadline_iso, round_config.lie_seconds),
|
||||
transition.session.code,
|
||||
transition.phase_event_name,
|
||||
transition.phase_event_payload,
|
||||
)
|
||||
|
||||
return JsonResponse(
|
||||
_build_question_shown_response(round_question, lie_deadline_iso, round_config.lie_seconds),
|
||||
status=201,
|
||||
)
|
||||
return JsonResponse(transition.response_payload, status=201)
|
||||
|
||||
|
||||
@require_POST
|
||||
|
||||
Reference in New Issue
Block a user