get_json поменял местами данные

This commit is contained in:
2025-10-29 11:44:13 +03:00
parent 6721951c34
commit 7b44ab3d5d

View File

@@ -1,5 +1,5 @@
import time
import os
import os, tempfile
import json
import tempfile
import argparse
@@ -9,6 +9,7 @@ import logging.config
from datetime import datetime, timedelta, timezone
from zoneinfo import ZoneInfo
from typing import Any, Dict, List, Tuple, Optional
from pathlib import Path
import pandas as pd
import numpy as np
@@ -23,7 +24,7 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
# 1. Константы / глобальные объекты
# ============================================================================
HOST = "https://ref.russiabasket.org"
HOST = "https://deti.russiabasket.org"
# Таймзона, в которой мы считаем время матчей / расписания / сна до завтра
APP_TZ = ZoneInfo("Europe/Moscow")
@@ -35,7 +36,8 @@ TELEGRAM_BOT_TOKEN = "7639240596:AAH0YtdQoWZSC-_R_EW4wKAHHNLIA0F_ARY"
TELEGRAM_CHAT_ID = -4803699526
# Глобальный лок для потокобезопасной записи JSON
_write_lock = threading.Lock()
_write_lock_api = threading.Lock()
_write_lock_out = threading.Lock()
_pregame_done_for_game = {}
# Карта всех ручек API, с интервалами опроса в секундах.
@@ -146,28 +148,41 @@ logger.handlers[2].formatter.use_emoji = True
# ============================================================================
def atomic_write_json(data: Any, name: str, out_dir: str = "static") -> None:
def _select_lock(path: str):
filename = os.path.basename(path)
# все сырые файлы мы называем api_*.json (api_game.json, api_box-score.json, ...)
if filename.startswith("api_"):
return _write_lock_api
return _write_lock_out
def atomic_write_json(path: str, data: Any) -> None:
"""
Потокобезопасная запись JSON в static/<name>.json.
Запись делается через временный файл + os.replace, чтобы:
- читатели не получили битый файл во время перезаписи;
- не было гонок между render_loop и poll_game_live.
Безопасно записывает JSON:
1. Сериализуем в память (без локов).
2. Под коротким локом - пишем tmp и делаем os.replace().
"""
os.makedirs(out_dir, exist_ok=True)
filename = os.path.join(out_dir, f"{name}.json")
# 1. Готовим данные заранее
# ensure_ascii=False чтобы не терять юникод, indent=None чтобы не раздувать файл
payload = json.dumps(data, ensure_ascii=False, separators=(",", ":"))
with _write_lock:
with tempfile.NamedTemporaryFile(
"w", delete=False, dir=out_dir, encoding="utf-8"
) as tmp_file:
json.dump(data, tmp_file, ensure_ascii=False, indent=2)
tmp_file.flush()
os.fsync(tmp_file.fileno())
tmp_name = tmp_file.name
target = Path(path)
tmp_fd, tmp_path = tempfile.mkstemp(
dir=target.parent,
prefix=target.name + ".tmp.",
text=True,
)
os.close(tmp_fd) # мы будем писать сами
os.replace(tmp_name, filename)
lock = _select_lock(path)
with lock:
# 2a. Записываем полностью во временный файл
with open(tmp_path, "w", encoding="utf-8") as f:
f.write(payload)
f.flush()
os.fsync(f.fileno())
# 2b. Атомарно подменяем
os.replace(tmp_path, target)
def read_local_json(name: str, in_dir: str = "static") -> Optional[dict]:
"""
@@ -251,7 +266,7 @@ def get_json(session: requests.Session, url: str, name: str) -> Any:
resp = session.get(url, timeout=10)
resp.raise_for_status()
data = resp.json()
atomic_write_json(data, f"api_{name}")
atomic_write_json(f"api_{name}", data)
return data