синхронизация текущего времени матча во всех браузерах, тест 1

This commit is contained in:
2026-05-25 14:22:47 +03:00
parent 64cd3891ea
commit 998774bf1c
2 changed files with 194 additions and 0 deletions

78
app.py
View File

@@ -440,6 +440,49 @@ def logout(request: Request):
return response
class ClockStatePayload(BaseModel):
currentPeriod: str | None = None
matchClockSeconds: int = 0
timerRunning: bool = False
pausedAccumulatedSeconds: int | None = None
sourceClientId: str | None = None
# Простое общее состояние часов для всех браузеров.
# localStorage остаётся резервом на стороне клиента.
MATCH_CLOCK_STATES: Dict[int, dict] = {}
def build_clock_state_payload(match_id: int) -> dict:
state = MATCH_CLOCK_STATES.get(match_id)
if not state:
return {
"exists": False,
"currentPeriod": None,
"matchClockSeconds": 0,
"timerRunning": False,
"serverSavedAt": None,
"sourceClientId": None,
}
seconds = int(state.get("matchClockSeconds") or 0)
timer_running = bool(state.get("timerRunning"))
saved_at = float(state.get("serverSavedAt") or time.time())
if timer_running:
seconds += max(0, int(time.time() - saved_at))
return {
"exists": True,
"currentPeriod": state.get("currentPeriod"),
"matchClockSeconds": max(0, seconds),
"timerRunning": timer_running,
"serverSavedAt": saved_at,
"sourceClientId": state.get("sourceClientId"),
}
class MatchEventPayload(BaseModel):
side: str
type: str
@@ -1082,6 +1125,41 @@ def save_formation(session_token: str, payload: FormationSavePayload):
return {"success": True}
@app.get("/admin/session/{session_token}/clock-state")
def api_get_clock_state(session_token: str):
session_row = get_match_session_by_token(session_token)
if not session_row:
return JSONResponse({"error": "session_not_found"}, status_code=404)
match_id = session_row[1]
return build_clock_state_payload(match_id)
@app.post("/admin/session/{session_token}/clock-state")
def api_save_clock_state(session_token: str, payload: ClockStatePayload):
session_row = get_match_session_by_token(session_token)
if not session_row:
return JSONResponse({"error": "session_not_found"}, status_code=404)
match_id = session_row[1]
seconds = max(0, int(payload.matchClockSeconds or 0))
MATCH_CLOCK_STATES[match_id] = {
"currentPeriod": payload.currentPeriod,
"matchClockSeconds": seconds,
"timerRunning": bool(payload.timerRunning),
"pausedAccumulatedSeconds": (
int(payload.pausedAccumulatedSeconds)
if payload.pausedAccumulatedSeconds is not None
else seconds
),
"serverSavedAt": time.time(),
"sourceClientId": payload.sourceClientId,
}
return build_clock_state_payload(match_id)
@app.get("/admin/session/{session_token}/events")
def api_get_events(session_token: str):
session_row = get_match_session_by_token(session_token)