BUILD149 — исправление статуса «Подготовка»

This commit is contained in:
2026-09-18 19:13:12 +03:00
parent f6bfb75f89
commit bda5235657
3 changed files with 246624 additions and 65293 deletions

File diff suppressed because it is too large Load Diff

2
app.py
View File

@@ -29,7 +29,7 @@ from ui_builder import install_ui_builder
from khl_site.khl_data_center import APP as khl_site_app
BASE_DIR = Path(__file__).resolve().parent
BUILD_VERSION = "2026.09.18.6"
BUILD_VERSION = "2026.09.18.7"
# compatibility: BUILD_VERSION = "2026.08.26.1"
# compatibility: BUILD_VERSION = "2026.08.25.1"
# compatibility: BUILD_VERSION = "2026.08.24.15"

View File

@@ -326,10 +326,11 @@ class HockeyDataService:
The tournament schedule XML remains the calendar source, while the match
JSON card is used to confirm the current score and canonical match state.
Status transitions are monotonic: scheduled -> live -> finished. This
prevents a delayed Stat2TV response from moving an already-live/finished
game backwards. A deep pass checks every started/undated game in the
tournament; normal maintenance keeps the request window bounded.
Status transitions are normally monotonic: scheduled -> live -> finished.
Explicit Stat2TV pre-game states (for example ``подготовка`` /
``preparation``) are authoritative and may repair a false ``live`` that
was inferred from statusvalue alone. Finished games never move backwards.
A deep pass checks only a bounded recent window.
"""
tournament_id = str(tournament_external_id or "").strip()
if not tournament_id:
@@ -4063,8 +4064,10 @@ class HockeyDataService:
"""Map Stat2TV game-card state to scheduled/live/finished.
Stat2TV payloads can use several textual state names. Runtime components
intentionally receive only three stable values. Once a game advances to
live or finished, a stale response is not allowed to move it backwards.
intentionally receive only three stable values. Explicit pre-game text
(notably ``подготовка`` / ``preparation``) is trusted over the numeric
fallback so it can repair a falsely inferred live state. Finished remains
terminal; other stale responses are not allowed to move state backwards.
"""
current_token = cls._canonical_game_status_token(current_status)
if current_approved or cls.is_terminal_game_status(current_status):
@@ -4075,12 +4078,20 @@ class HockeyDataService:
current = "scheduled"
token = cls._canonical_game_status_token(raw_status)
explicit_preparation = (
token in {"preparation", "preparing", "prepare", "подготовка"}
or "preparation" in token
or "preparing" in token
or "подготов" in token
)
if status_value >= 90 or cls.is_terminal_game_status(raw_status):
incoming = "finished"
else:
scheduled_tokens = {
"scheduled", "schedule", "upcoming", "notstarted", "prematch",
"pregame", "pending", "planned", "waiting", "ожидается",
"scheduled", "sheduled", "schedule", "upcoming", "notstarted", "prematch",
"pregame", "preparation", "preparing", "prepare",
"pending", "planned", "waiting", "ожидается",
"подготовка", "подготовкакматчу", "подготовкакигре",
"неначался", "предстоящий", "запланирован",
}
live_tokens = {
@@ -4091,7 +4102,11 @@ class HockeyDataService:
"овертайм", "буллиты",
}
if token in scheduled_tokens or any(
marker in token for marker in ("notstarted", "prematch", "pregame", "upcoming")
marker in token
for marker in (
"notstarted", "prematch", "pregame", "upcoming",
"preparation", "preparing", "подготов",
)
):
incoming = "scheduled"
elif token in live_tokens or any(
@@ -4110,7 +4125,17 @@ class HockeyDataService:
incoming = current
rank = {"scheduled": 0, "live": 1, "finished": 2}
canonical = incoming if rank[incoming] >= rank[current] else current
# BUILD149: ``подготовка`` / ``preparation`` is an explicit pre-game
# state from the per-match Stat2TV JSON. BUILD146 used the numeric
# fallback ``statusvalue > 0 -> live`` for unknown text and therefore
# incorrectly marked preparation cards as live. Allow this one explicit
# state to repair that false live value already stored in PostgreSQL.
# A truly finished/approved match remains terminal.
if current != "finished" and explicit_preparation:
canonical = "scheduled"
else:
canonical = incoming if rank[incoming] >= rank[current] else current
return canonical, canonical == "finished"
@classmethod