diff --git a/cmscontrib/loaders/italy_yaml.py b/cmscontrib/loaders/italy_yaml.py index f8f5dd80b..f307522f9 100644 --- a/cmscontrib/loaders/italy_yaml.py +++ b/cmscontrib/loaders/italy_yaml.py @@ -27,7 +27,8 @@ import os import os.path import sys -from datetime import timedelta +from datetime import datetime, timedelta, timezone +from copy import deepcopy import yaml @@ -39,7 +40,6 @@ from cmscommon.constants import \ SCORE_MODE_MAX, SCORE_MODE_MAX_SUBTASK, SCORE_MODE_MAX_TOKENED_LAST from cmscommon.crypto import build_password -from cmscommon.datetime import make_datetime from cmscontrib import touch from .base_loader import ContestLoader, TaskLoader, UserLoader, TeamLoader, LANGUAGE_MAP @@ -61,9 +61,15 @@ def getmtime(fname): return os.stat(fname).st_mtime +yaml_cache = {} + def load_yaml_from_path(path): + if path in yaml_cache: + return yaml_cache[path] with open(path, "rt", encoding="utf-8") as f: - return yaml.safe_load(f) + value = yaml.safe_load(f) + yaml_cache[path] = value + return deepcopy(value) def load(src, dst, src_name, dst_name=None, conv=lambda i: i): @@ -118,6 +124,12 @@ def load(src, dst, src_name, dst_name=None, conv=lambda i: i): return conv(res) +def parse_datetime(val): + if isinstance(val, (int, float)): + return datetime.fromtimestamp(val, timezone.utc) + return datetime.fromisoformat(val) + + def make_timedelta(t): return timedelta(seconds=t) @@ -207,8 +219,8 @@ def get_contest(self): if args["token_gen_interval"].total_seconds() == 0: args["token_gen_interval"] = timedelta(minutes=1) - load(conf, args, ["start", "inizio"], conv=make_datetime) - load(conf, args, ["stop", "fine"], conv=make_datetime) + load(conf, args, ["start", "inizio"], conv=parse_datetime) + load(conf, args, ["stop", "fine"], conv=parse_datetime) load(conf, args, ["per_user_time"], conv=make_timedelta) load(conf, args, ["timezone"])