Skip to content

Commit 49b52f7

Browse files
committed
scoreboard: make generation robust across Python versions; add PyYAML dep and zoneinfo fallback\n\n- Add PyYAML and conditional backports.zoneinfo to requirements\n- Avoid hard dependency on zoneinfo at import time; use fallback\n- Use MSK helper in deadlines/timestamp to prevent import errors\n- No functional change to table content except timestamp format
1 parent fedbe81 commit 49b52f7

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

scoreboard/main.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,18 @@
77
import yaml
88
import shutil
99
from jinja2 import Environment, FileSystemLoader
10-
from zoneinfo import ZoneInfo
1110
import logging
1211
import sys
1312

13+
# Try ZoneInfo from stdlib, then from backports, else fall back to naive time
14+
try:
15+
from zoneinfo import ZoneInfo # type: ignore
16+
except Exception: # pragma: no cover - fallback for Python < 3.9
17+
try:
18+
from backports.zoneinfo import ZoneInfo # type: ignore
19+
except Exception: # Last resort: define a stub
20+
ZoneInfo = None # type: ignore
21+
1422
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
1523
logger = logging.getLogger(__name__)
1624

@@ -44,6 +52,16 @@ def assign_variant(
4452
return 0
4553

4654

55+
def _now_msk():
56+
"""Return current datetime in MSK if tz support is available, else local time."""
57+
try:
58+
if ZoneInfo is not None:
59+
return datetime.now(ZoneInfo("Europe/Moscow"))
60+
except Exception:
61+
pass
62+
return datetime.now()
63+
64+
4765
def _read_tasks_type(task_dir: Path) -> str | None:
4866
"""Read tasks_type from settings.json in the task directory (if present)."""
4967
settings_path = task_dir / "settings.json"
@@ -561,7 +579,6 @@ def main():
561579

562580
# Helper: compute evenly spaced dates for current semester (MSK)
563581
from datetime import date, timedelta
564-
from zoneinfo import ZoneInfo as _ZoneInfo
565582
import calendar
566583

567584
def _abbr(day: date) -> str:
@@ -616,15 +633,21 @@ def _evenly_spaced_dates(n: int, start: date, end: date) -> list[date]:
616633
return res
617634

618635
def _compute_display_deadlines_threads(order: list[str]) -> dict[str, date]:
619-
# Threads = Spring semester
620-
today = datetime.now(_ZoneInfo("Europe/Moscow")).date()
636+
# Threads = Spring semester (prefer MSK; fallback to local time)
637+
try:
638+
today = _now_msk().date()
639+
except Exception:
640+
today = datetime.now().date()
621641
s, e = _spring_bounds(today)
622642
ds = _evenly_spaced_dates(len(order), s, e)
623643
return {t: d for t, d in zip(order, ds)}
624644

625645
def _compute_display_deadlines_processes(n_items: int) -> list[date]:
626-
# Processes = Autumn semester
627-
today = datetime.now(_ZoneInfo("Europe/Moscow")).date()
646+
# Processes = Autumn semester (prefer MSK; fallback to local time)
647+
try:
648+
today = _now_msk().date()
649+
except Exception:
650+
today = datetime.now().date()
628651
s, e = _autumn_bounds(today)
629652
ds = _evenly_spaced_dates(n_items, s, e)
630653
return ds
@@ -889,9 +912,7 @@ def _build_cell(dir_name: str, ttype: str):
889912
output_path.mkdir(parents=True, exist_ok=True)
890913

891914
# Render tables
892-
generated_msk = datetime.now(ZoneInfo("Europe/Moscow")).strftime(
893-
"%Y-%m-%d %H:%M:%S"
894-
)
915+
generated_msk = _now_msk().strftime("%Y-%m-%d %H:%M:%S")
895916
table_template = env.get_template("index.html.j2")
896917
threads_vmax = int((cfg.get("threads", {}) or {}).get("variants_max", 1))
897918
# Build display deadlines (use file values if present, fill missing with auto)

scoreboard/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
Jinja2>=3.0
2+
PyYAML>=6.0
3+
backports.zoneinfo; python_version < "3.9"

0 commit comments

Comments
 (0)