обновил еще капитонов

This commit is contained in:
2026-08-10 10:49:32 +03:00
parent b29fc06a4f
commit c759f34f0f
3 changed files with 130 additions and 24 deletions

View File

@@ -15,7 +15,10 @@ from repositories.coach_repository import (
create_coach_from_lineup,
)
from repositories.referee_repository import get_referee_id_by_name, upsert_referee
from repositories.match_lineup_repository import replace_match_lineups, save_match_lineup_for_editor
from repositories.match_lineup_repository import (
replace_match_lineups,
get_match_lineup_for_editor,
)
from repositories.match_coach_repository import replace_match_coaches
from repositories.match_referee_repository import replace_match_referees
@@ -35,6 +38,31 @@ def sync_match_page(
raise ValueError(f"Match not found by external_id: {match_external_id}")
match_id, _, home_team_id, away_team_id = match_row
# Сохраняем текущий выбор капитана ДО очистки данных матча. Это важно
# при повторной загрузке с сайта: на сайте капитана иногда не указывают,
# и в таком случае нельзя молча терять уже сделанный оператором выбор.
previous_lineup = get_match_lineup_for_editor(
match_id=match_id,
home_team_id=home_team_id,
away_team_id=away_team_id,
)
def previous_captain(side: str) -> dict | None:
rows = previous_lineup.get(f"{side}_starting", []) or []
for player in rows:
if bool(player.get("is_captain")):
return {
"player_id": player.get("player_id"),
"number": str(player.get("number") or "").strip(),
}
return None
previous_captains = {
"home": previous_captain("home"),
"away": previous_captain("away"),
}
clear_match_squad_data(match_id)
created_players_count = 0
@@ -117,7 +145,10 @@ def sync_match_page(
"number": player.get("number"),
"position": player.get("position"),
"position_full": player_position,
"is_captain": bool(player.get("is_captain")),
# Капитаном может быть только игрок основного состава.
# Если сайт по ошибке пометил игрока запаса, не переносим
# такой флаг в матчевые данные.
"is_captain": bool(player.get("is_captain")) and lineup_type == "starting",
"lineup_type": lineup_type,
"source": "parser",
}
@@ -128,6 +159,72 @@ def sync_match_page(
append_players(home_bench, home_team_id, "bench")
append_players(away_bench, away_team_id, "bench")
def restore_previous_captain_if_missing(side: str, team_id: int) -> bool:
"""Возвращает старого капитана только когда сайт не указал нового.
Восстановление разрешено исключительно для игрока, который всё ещё
присутствует в основном составе. Если прежний капитан отсутствует или
ушёл в запас, капитан остаётся не выбран — веб-интерфейс покажет
обязательное предупреждение оператору.
"""
starting_rows = [
row for row in lineup_rows
if row.get("team_id") == team_id and row.get("lineup_type") == "starting"
]
imported_captains = [row for row in starting_rows if bool(row.get("is_captain"))]
# Ровно один капитан с сайта — корректные данные, они имеют приоритет.
if len(imported_captains) == 1:
return False
# Если сайт по ошибке передал больше одного капитана, не выбираем
# случайного игрока. Сбрасываем конфликт и используем тот же безопасный
# fallback, что и при полностью отсутствующем капитане.
if len(imported_captains) > 1:
for row in imported_captains:
row["is_captain"] = False
old_captain = previous_captains.get(side)
if not old_captain:
return False
old_player_id = old_captain.get("player_id")
old_number = str(old_captain.get("number") or "").strip()
# Сначала точное совпадение по player_id.
if old_player_id is not None:
for row in starting_rows:
if row.get("player_id") is not None and str(row.get("player_id")) == str(old_player_id):
row["is_captain"] = True
return True
# Fallback для старых/неполных данных — по игровому номеру.
if old_number:
matches = [
row for row in starting_rows
if str(row.get("number") or "").strip() == old_number
]
if len(matches) == 1:
matches[0]["is_captain"] = True
return True
return False
restored_home_captain = restore_previous_captain_if_missing("home", home_team_id)
restored_away_captain = restore_previous_captain_if_missing("away", away_team_id)
if restored_home_captain or restored_away_captain:
restored = []
if restored_home_captain:
restored.append("home")
if restored_away_captain:
restored.append("away")
print(
f"[parser_game] website captain missing for match={match_external_id}; "
f"preserved previous captain for: {', '.join(restored)}"
)
coach_rows = []
def append_coaches(coaches: list[dict], team_id: int, side: str) -> None: