поправил турнирку
This commit is contained in:
@@ -688,15 +688,6 @@ def run_live_loop(
|
|||||||
render_thread.start()
|
render_thread.start()
|
||||||
logger.info("[LIVE_THREAD] render thread spawned")
|
logger.info("[LIVE_THREAD] render thread spawned")
|
||||||
|
|
||||||
# поток standings
|
|
||||||
standings_thread = threading.Thread(
|
|
||||||
target=Standing_func,
|
|
||||||
args=(session, league, season, lang, stop_event),
|
|
||||||
daemon=False,
|
|
||||||
)
|
|
||||||
standings_thread.start()
|
|
||||||
logger.info("[LIVE_THREAD] standings thread spawned")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
poll_game_live(
|
poll_game_live(
|
||||||
session=session,
|
session=session,
|
||||||
@@ -714,7 +705,6 @@ def run_live_loop(
|
|||||||
logger.info(f"[LIVE_THREAD] stopping worker threads for game_id={game_id}")
|
logger.info(f"[LIVE_THREAD] stopping worker threads for game_id={game_id}")
|
||||||
|
|
||||||
render_thread.join()
|
render_thread.join()
|
||||||
standings_thread.join()
|
|
||||||
|
|
||||||
logger.info(f"[LIVE_THREAD] stop live loop for game_id={game_id}")
|
logger.info(f"[LIVE_THREAD] stop live loop for game_id={game_id}")
|
||||||
|
|
||||||
@@ -823,7 +813,6 @@ def render_once_after_game(
|
|||||||
Referee(state)
|
Referee(state)
|
||||||
|
|
||||||
# === 4. live_status и общий state ===
|
# === 4. live_status и общий state ===
|
||||||
atomic_write_json([state["result"]["live_status"]], "live_status")
|
|
||||||
atomic_write_json(state["result"], out_name)
|
atomic_write_json(state["result"], out_name)
|
||||||
|
|
||||||
logger.info("[RENDER_ONCE] финальные json сохранены успешно")
|
logger.info("[RENDER_ONCE] финальные json сохранены успешно")
|
||||||
@@ -1460,6 +1449,8 @@ def Standing_func(
|
|||||||
|
|
||||||
# когда мы последний раз успешно обновили standings
|
# когда мы последний раз успешно обновили standings
|
||||||
last_call_ts = 0
|
last_call_ts = 0
|
||||||
|
json_seasons = fetch_api_data(session, "seasons", host=HOST, league=league, lang=lang)
|
||||||
|
season = json_seasons[0]["season"]
|
||||||
|
|
||||||
# как часто вообще можно дёргать standings
|
# как часто вообще можно дёргать standings
|
||||||
interval = get_interval_by_name("standings")
|
interval = get_interval_by_name("standings")
|
||||||
@@ -1705,64 +1696,70 @@ def get_data_API(
|
|||||||
logger.info("Для этой команды игр сегодня нет и нет завершённой последней игры.")
|
logger.info("Для этой команды игр сегодня нет и нет завершённой последней игры.")
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main():
|
||||||
"""
|
|
||||||
Главный цикл демона.
|
|
||||||
|
|
||||||
Работает бесконечно:
|
|
||||||
- собирает данные на сегодня (get_data_API)
|
|
||||||
- если нужно, следит за матчем в реальном времени до свистка
|
|
||||||
- после этого уходит спать до 00:05 следующего дня по APP_TZ
|
|
||||||
- повторяет
|
|
||||||
|
|
||||||
Ctrl+C:
|
|
||||||
- моментально поднимает stop_event и завершает работу.
|
|
||||||
"""
|
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument("--league", default="vtb")
|
parser.add_argument("--league", default="vtb")
|
||||||
parser.add_argument("--team", required=True)
|
parser.add_argument("--team", required=True)
|
||||||
parser.add_argument("--lang", default="en")
|
parser.add_argument("--lang", default="en")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
while True:
|
# Один общий stop_event на всё приложение.
|
||||||
# на каждый "прогон дня" — своя HTTP-сессия и свой stop_event
|
|
||||||
session = create_session()
|
|
||||||
stop_event = threading.Event()
|
stop_event = threading.Event()
|
||||||
|
|
||||||
|
# Одна сессия для standings-потока.
|
||||||
|
# Её достаточно, потому что standings не требует суперчастого обновления.
|
||||||
|
standings_session = create_session()
|
||||||
|
|
||||||
|
# Запускаем standings-поток навсегда (пока процесс жив).
|
||||||
|
standings_thread = threading.Thread(
|
||||||
|
target=Standing_func,
|
||||||
|
args=(standings_session, args.league, None, args.lang, stop_event),
|
||||||
|
daemon=False,
|
||||||
|
)
|
||||||
|
standings_thread.start()
|
||||||
|
logger.info("[MAIN] standings thread started (global)")
|
||||||
|
|
||||||
|
# Основной дневной цикл.
|
||||||
|
while True:
|
||||||
|
session = create_session()
|
||||||
try:
|
try:
|
||||||
get_data_API(session, args.league, args.team, args.lang, stop_event)
|
get_data_API(session, args.league, args.team, args.lang, stop_event)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
logger.info("KeyboardInterrupt -> остановка по запросу оператора")
|
logger.info("KeyboardInterrupt -> останавливаем всё")
|
||||||
stop_event.set()
|
stop_event.set()
|
||||||
break
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# мы не падаем навсегда, а логируем, чтобы демон продолжил жить
|
|
||||||
logger.exception(f"main loop crash: {e}")
|
logger.exception(f"main loop crash: {e}")
|
||||||
|
|
||||||
# === сон до завтрашних 00:05 по APP_TZ ===
|
# спим до завтра 00:05
|
||||||
now = datetime.now(APP_TZ)
|
now = datetime.now(APP_TZ)
|
||||||
tomorrow = (now + timedelta(days=1)).replace(
|
tomorrow = (now + timedelta(days=1)).replace(
|
||||||
hour=0, minute=5, second=0, microsecond=0
|
hour=0, minute=5, second=0, microsecond=0
|
||||||
)
|
)
|
||||||
sleep_seconds = (tomorrow - now).total_seconds()
|
sleep_seconds = (tomorrow - now).total_seconds()
|
||||||
if sleep_seconds < 0:
|
if sleep_seconds < 0:
|
||||||
# защита, если вдруг текущее время уже после 00:05 и replace() дал прошедшее
|
|
||||||
tomorrow = (now + timedelta(days=2)).replace(
|
tomorrow = (now + timedelta(days=2)).replace(
|
||||||
hour=0, minute=5, second=0, microsecond=0
|
hour=0, minute=5, second=0, microsecond=0
|
||||||
)
|
)
|
||||||
sleep_seconds = (tomorrow - now).total_seconds()
|
sleep_seconds = (tomorrow - now).total_seconds()
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Работа завершена. Засыпаем до {tomorrow.strftime('%d.%m %H:%M')} "
|
f"Работа за день завершена. Засыпаем до {tomorrow.strftime('%d.%m %H:%M')} "
|
||||||
f"(~{round(sleep_seconds/3600, 2)} ч)."
|
f"(~{round(sleep_seconds/3600, 2)} ч)."
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
time.sleep(sleep_seconds)
|
time.sleep(sleep_seconds)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
logger.info("KeyboardInterrupt во время сна -> выходим.")
|
logger.info("KeyboardInterrupt во время сна -> выходим")
|
||||||
|
stop_event.set()
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Выход из while True → стопаем standings-поток
|
||||||
|
stop_event.set()
|
||||||
|
standings_thread.join()
|
||||||
|
logger.info("[MAIN] standings thread stopped, shutdown complete")
|
||||||
|
|
||||||
# идём на новую итерацию while True
|
# идём на новую итерацию while True
|
||||||
# (новая сессия / новый stop_event создаются в начале цикла)
|
# (новая сессия / новый stop_event создаются в начале цикла)
|
||||||
|
|
||||||
|
|||||||
@@ -439,13 +439,13 @@ cached_referee = st.session_state.get("referee")
|
|||||||
league_tag = None
|
league_tag = None
|
||||||
if isinstance(cached_game_online, dict):
|
if isinstance(cached_game_online, dict):
|
||||||
league_tag = (cached_game_online.get("league") or {}).get("tag")
|
league_tag = (cached_game_online.get("league") or {}).get("tag")
|
||||||
print(cached_game_online.get("comp").get("name"))
|
|
||||||
comp_name = (cached_game_online.get("comp") or {}).get("name").replace(" ", "_")
|
comp_name = (cached_game_online.get("comp") or {}).get("name").replace(" ", "_")
|
||||||
if league_tag:
|
if league_tag:
|
||||||
load_data_from_json(f"standings_{league_tag}_{comp_name}")
|
load_data_from_json(f"standings_{league_tag}_{comp_name}")
|
||||||
cached_standings = (
|
cached_standings = (
|
||||||
st.session_state.get(f"standings_{league_tag}_{comp_name}") if league_tag else None
|
st.session_state.get(f"standings_{league_tag}_{comp_name}") if league_tag else None
|
||||||
)
|
)
|
||||||
|
|
||||||
load_data_from_json("scores_quarter")
|
load_data_from_json("scores_quarter")
|
||||||
cached_scores_quarter = st.session_state.get("scores_quarter")
|
cached_scores_quarter = st.session_state.get("scores_quarter")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user