добавлена функция генерации турнирной таблицы раз в 10 минут с сообщением в телеграм

This commit is contained in:
2025-10-24 18:12:26 +03:00
parent 629854c104
commit dcfcbb0958

View File

@@ -28,6 +28,7 @@ import time
import json
import argparse
import logging
import pandas as pd
import logging.config
import threading
import concurrent.futures
@@ -40,6 +41,7 @@ from zoneinfo import ZoneInfo
from typing import Any, Dict, List
import tempfile
from pathlib import Path
from threading import Event, Lock
import requests
@@ -78,11 +80,13 @@ URL_GAME = "https://{host}/api/abc/games/game?Id={game_id}&lang={lang}"
URL_BOX_SCORE = "https://{host}/api/abc/games/box-score?Id={game_id}&lang={lang}"
URL_PLAY_BY_PLAY = "https://{host}/api/abc/games/play-by-play?Id={game_id}&lang={lang}"
URL_LIVE_STATUS = "https://{host}/api/abc/games/live-status?Id={game_id}&lang={lang}"
URL_STANDINGS = "https://{host}/api/abc/comps/actual-standings?tag={league}&season={season}&lang={lang}"
# Интервалы опроса
STATUS_CHECK_INTERVAL_SEC = 60 # проверять "онлайн?" раз в минуту
ONLINE_FETCH_INTERVAL_SEC = 1 # когда матч онлайн, дергать три запроса каждую секунду
POLL_INTERVAL_OFFLINE_SEC = 300 # резервный интервал сна при ошибках/до старта
TIMEOUT_DATA_OFF = 600
TELEGRAM_BOT_TOKEN = "7639240596:AAH0YtdQoWZSC-_R_EW4wKAHHNLIA0F_ARY"
# TELEGRAM_CHAT_ID = 228977654
@@ -1499,6 +1503,76 @@ def status_online_func(merged: dict, *, out_dir: str = "static") -> None:
return None
def Standing_func(league, season, lang, stop_event: threading.Event, out_dir: str = "static") -> None:
logger.info("START making json for standings")
while not stop_event.is_set():
try:
url = URL_STANDINGS.format(host=HOST, league=league, season=season, lang=lang)
data_standings = fetch_json(url)
if data_standings and "items" in data_standings and data_standings["items"]:
standings_temp = data_standings["items"]
for item in standings_temp:
if "standings" in item and item["standings"] != []:
standings_temp = item["standings"]
df = pd.json_normalize(standings_temp)
del df["scores"]
if not df["totalWin"].isna().all():
df["w_l"] = (
df["totalWin"].astype(str)
+ " / "
+ df["totalDefeat"].astype(str)
)
df["procent"] = df.apply(
lambda row: (
0
if row["w_l"] == "0 / 0"
or row["totalGames"] == 0
or pd.isna(row["totalWin"])
else round(
row["totalWin"] * 100 / row["totalGames"]
+ 0.000005
)
),
axis=1,
)
df["plus_minus"] = (
df["totalGoalPlus"] - df["totalGoalMinus"]
)
filepath = os.path.join(
out_dir,
f"standings_{league}_{item['comp']['name'].replace(' ', '_')}.json",
)
df.to_json(
filepath,
orient="records",
force_ascii=False,
indent=4,
)
logger.info("Standings data saved successfully.")
elif "playoffPairs" in item and item["playoffPairs"] != []:
standings_temp = item["playoffPairs"]
df = pd.json_normalize(standings_temp)
filepath = os.path.join(
out_dir,
f"standings_{league}_{item['comp']['name'].replace(' ', '_')}.json",
)
df.to_json(
filepath,
orient="records",
force_ascii=False,
indent=4,
)
logger.info("Standings data saved successfully.")
except Exception as e:
logger.warning(f"Ошибка в турнирном положении: {e}")
stop_event.wait(TIMEOUT_DATA_OFF)
# ==========================
# ---- ДОМЕННАЯ ЛОГИКА
# ==========================
@@ -1903,6 +1977,10 @@ def main():
# 1) Узнать последний сезон
season = get_last_season_or_die(league, args.lang)
# 2) Получить расписание для команды
team_games = get_team_schedule_or_die(league, season, team, args.lang)
@@ -1972,6 +2050,17 @@ def main():
daemon=True,
)
rollover_thread.start()
# 1.1) турнирная таблица
threads = [
threading.Thread(
target=Standing_func,
args=(league, season, args.lang, stop_event),
name="standings",)]
for t in threads:
t.start()
logger.debug(f"Поток {t.name} запущен.")
# Держим главный поток живым
try:
@@ -1979,6 +2068,10 @@ def main():
time.sleep(1)
except KeyboardInterrupt:
logger.info("Завершение по Ctrl+C…")
stop_event.set()
for t in threads:
t.join()
logger.debug(f"Поток {t.name} завершён.")
finally:
stop_event.set()
monitor_mgr.stop()