host pro, добавил в телеграмм сообщение о статусе запросов раз в 5 минут
This commit is contained in:
120
get_data.py
120
get_data.py
@@ -354,6 +354,11 @@ def results_consumer():
|
|||||||
game["data"]["result"]["game"]["fullScore"] = payload["result"][
|
game["data"]["result"]["game"]["fullScore"] = payload["result"][
|
||||||
"fullScore"
|
"fullScore"
|
||||||
]
|
]
|
||||||
|
game["data"]["result"]["game"]["score"] = payload["result"][
|
||||||
|
"teams"
|
||||||
|
][0]["total"]["points"] + ":" + payload["result"][
|
||||||
|
"teams"
|
||||||
|
][1]["total"]["points"]
|
||||||
for team in game["data"]["result"]["teams"]:
|
for team in game["data"]["result"]["teams"]:
|
||||||
if team["teamNumber"] != 0:
|
if team["teamNumber"] != 0:
|
||||||
box_team = [
|
box_team = [
|
||||||
@@ -579,6 +584,112 @@ def extract_game_datetime(game_item: dict) -> datetime | None:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def build_pretty_status_message():
|
||||||
|
"""
|
||||||
|
Собирает одно красивое сообщение про текущее состояние онлайна.
|
||||||
|
Если game ещё нет — шлём хотя бы статусы источников.
|
||||||
|
"""
|
||||||
|
lines = []
|
||||||
|
lines.append(f"🏀 <b>{LEAGUE.upper()}</b> • {TEAM}")
|
||||||
|
lines.append(f"📌 Game ID: <code>{GAME_ID}</code>")
|
||||||
|
lines.append(f"🕒 {datetime.now().strftime('%d.%m.%Y %H:%M:%S')}")
|
||||||
|
|
||||||
|
# сначала попробуем собрать нормальный game
|
||||||
|
game_wrap = latest_data.get("game")
|
||||||
|
has_game = False
|
||||||
|
if game_wrap:
|
||||||
|
game_data = game_wrap.get("data") or game_wrap
|
||||||
|
result = game_data.get("result") or {}
|
||||||
|
game_info = result.get("game") or {}
|
||||||
|
|
||||||
|
|
||||||
|
team1_name = game_data["team1"]["name"]
|
||||||
|
team2_name = game_data["team2"]["name"]
|
||||||
|
|
||||||
|
score_now = game_info.get("score") or ""
|
||||||
|
full_score = game_info.get("fullScore") or ""
|
||||||
|
|
||||||
|
lines.append(f"👥 {team1_name} vs {team2_name}")
|
||||||
|
if score_now:
|
||||||
|
lines.append(f"🔢 Score: <b>{score_now}</b>")
|
||||||
|
|
||||||
|
if isinstance(full_score, str) and full_score:
|
||||||
|
quarters = full_score.split(",")
|
||||||
|
q_text = " | ".join(
|
||||||
|
f"Q{i+1} {q}" for i, q in enumerate(quarters) if q
|
||||||
|
)
|
||||||
|
if q_text:
|
||||||
|
lines.append(f"🧱 By quarters: {q_text}")
|
||||||
|
|
||||||
|
has_game = True
|
||||||
|
|
||||||
|
# live-status отдельно
|
||||||
|
ls = latest_data.get("live-status", {})
|
||||||
|
ls_raw = ls.get("data") or {}
|
||||||
|
ls_status = (
|
||||||
|
ls_raw.get("status")
|
||||||
|
or ls_raw.get("gameStatus")
|
||||||
|
or ls_raw.get("state")
|
||||||
|
or "—"
|
||||||
|
)
|
||||||
|
lines.append(f"🟢 LIVE status: <b>{ls_status}</b>")
|
||||||
|
|
||||||
|
# добавим блок по источникам — это как раз “состояние запросов”
|
||||||
|
sort_order = ["game", "live-status", "box-score", "play-by-play"]
|
||||||
|
keys = [k for k in sort_order if k in latest_data] + sorted(
|
||||||
|
[k for k in latest_data if k not in sort_order]
|
||||||
|
)
|
||||||
|
src_lines = []
|
||||||
|
for k in keys:
|
||||||
|
d = latest_data.get(k) or {}
|
||||||
|
ts = d.get("ts", "—")
|
||||||
|
dat = d.get("data")
|
||||||
|
if isinstance(dat, dict) and "status" in dat:
|
||||||
|
st = dat["status"]
|
||||||
|
else:
|
||||||
|
st = dat
|
||||||
|
src_lines.append(f"• <b>{k}</b>: {st} ({ts})")
|
||||||
|
|
||||||
|
if src_lines:
|
||||||
|
lines.append("📡 Sources:")
|
||||||
|
lines.extend(src_lines)
|
||||||
|
|
||||||
|
# даже если game не успел — мы всё равно что-то вернём
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def status_broadcaster():
|
||||||
|
"""
|
||||||
|
Если матч live — сразу шлём статус.
|
||||||
|
Потом — раз в 5 минут.
|
||||||
|
Если матч не live — ждём и проверяем снова.
|
||||||
|
"""
|
||||||
|
INTERVAL = 300 # 5 минут
|
||||||
|
last_text = None
|
||||||
|
first_live_sent = False
|
||||||
|
|
||||||
|
while not stop_event.is_set():
|
||||||
|
# если игра не идёт — спим по чуть-чуть и крутимся
|
||||||
|
if STATUS not in ("live", "live_soon"):
|
||||||
|
first_live_sent = False # чтобы при новом лайве снова сразу отправить
|
||||||
|
time.sleep(5)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# сюда попадаем только если live
|
||||||
|
text = build_pretty_status_message()
|
||||||
|
if text and text != last_text:
|
||||||
|
logger.info(text)
|
||||||
|
last_text = text
|
||||||
|
first_live_sent = True
|
||||||
|
|
||||||
|
# после первого лайва ждём 5 минут, а до него — 10 секунд
|
||||||
|
wait_sec = INTERVAL if first_live_sent else 10
|
||||||
|
for _ in range(wait_sec):
|
||||||
|
if stop_event.is_set():
|
||||||
|
break
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def lifespan(app: FastAPI):
|
async def lifespan(app: FastAPI):
|
||||||
@@ -627,6 +738,12 @@ async def lifespan(app: FastAPI):
|
|||||||
daemon=True,
|
daemon=True,
|
||||||
)
|
)
|
||||||
thread_result_consumer.start()
|
thread_result_consumer.start()
|
||||||
|
|
||||||
|
thread_status_broadcaster = threading.Thread(
|
||||||
|
target=status_broadcaster,
|
||||||
|
daemon=True,
|
||||||
|
)
|
||||||
|
thread_status_broadcaster.start()
|
||||||
|
|
||||||
# 5. Подготовим онлайн и офлайн наборы (как у тебя)
|
# 5. Подготовим онлайн и офлайн наборы (как у тебя)
|
||||||
threads_live = [
|
threads_live = [
|
||||||
@@ -754,10 +871,11 @@ async def lifespan(app: FastAPI):
|
|||||||
yield
|
yield
|
||||||
|
|
||||||
# -------- shutdown --------
|
# -------- shutdown --------
|
||||||
stop_event.set() # завершить consumer
|
stop_event.set()
|
||||||
stop_live_threads()
|
stop_live_threads()
|
||||||
stop_offline_threads()
|
stop_offline_threads()
|
||||||
thread_result_consumer.join(timeout=1)
|
thread_result_consumer.join(timeout=1)
|
||||||
|
thread_status_broadcaster.join(timeout=1)
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI(lifespan=lifespan)
|
app = FastAPI(lifespan=lifespan)
|
||||||
|
|||||||
Reference in New Issue
Block a user