добавлена функция генерации турнирной таблицы раз в 10 минут с сообщением в телеграм
This commit is contained in:
93
get_data.py
93
get_data.py
@@ -28,6 +28,7 @@ import time
|
|||||||
import json
|
import json
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
|
import pandas as pd
|
||||||
import logging.config
|
import logging.config
|
||||||
import threading
|
import threading
|
||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
@@ -40,6 +41,7 @@ from zoneinfo import ZoneInfo
|
|||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from threading import Event, Lock
|
||||||
|
|
||||||
import requests
|
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_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_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_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 # проверять "онлайн?" раз в минуту
|
STATUS_CHECK_INTERVAL_SEC = 60 # проверять "онлайн?" раз в минуту
|
||||||
ONLINE_FETCH_INTERVAL_SEC = 1 # когда матч онлайн, дергать три запроса каждую секунду
|
ONLINE_FETCH_INTERVAL_SEC = 1 # когда матч онлайн, дергать три запроса каждую секунду
|
||||||
POLL_INTERVAL_OFFLINE_SEC = 300 # резервный интервал сна при ошибках/до старта
|
POLL_INTERVAL_OFFLINE_SEC = 300 # резервный интервал сна при ошибках/до старта
|
||||||
|
TIMEOUT_DATA_OFF = 600
|
||||||
|
|
||||||
TELEGRAM_BOT_TOKEN = "7639240596:AAH0YtdQoWZSC-_R_EW4wKAHHNLIA0F_ARY"
|
TELEGRAM_BOT_TOKEN = "7639240596:AAH0YtdQoWZSC-_R_EW4wKAHHNLIA0F_ARY"
|
||||||
# TELEGRAM_CHAT_ID = 228977654
|
# TELEGRAM_CHAT_ID = 228977654
|
||||||
@@ -1499,6 +1503,76 @@ def status_online_func(merged: dict, *, out_dir: str = "static") -> None:
|
|||||||
return 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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# ==========================
|
# ==========================
|
||||||
# ---- ДОМЕННАЯ ЛОГИКА
|
# ---- ДОМЕННАЯ ЛОГИКА
|
||||||
# ==========================
|
# ==========================
|
||||||
@@ -1904,6 +1978,10 @@ def main():
|
|||||||
# 1) Узнать последний сезон
|
# 1) Узнать последний сезон
|
||||||
season = get_last_season_or_die(league, args.lang)
|
season = get_last_season_or_die(league, args.lang)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 2) Получить расписание для команды
|
# 2) Получить расписание для команды
|
||||||
team_games = get_team_schedule_or_die(league, season, team, args.lang)
|
team_games = get_team_schedule_or_die(league, season, team, args.lang)
|
||||||
if not team_games:
|
if not team_games:
|
||||||
@@ -1973,12 +2051,27 @@ def main():
|
|||||||
)
|
)
|
||||||
rollover_thread.start()
|
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:
|
try:
|
||||||
while True:
|
while True:
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
logger.info("Завершение по Ctrl+C…")
|
logger.info("Завершение по Ctrl+C…")
|
||||||
|
stop_event.set()
|
||||||
|
for t in threads:
|
||||||
|
t.join()
|
||||||
|
logger.debug(f"Поток {t.name} завершён.")
|
||||||
finally:
|
finally:
|
||||||
stop_event.set()
|
stop_event.set()
|
||||||
monitor_mgr.stop()
|
monitor_mgr.stop()
|
||||||
|
|||||||
Reference in New Issue
Block a user