xcpcio 0.69.0__py3-none-any.whl → 0.69.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of xcpcio might be problematic. Click here for more details.
- xcpcio/__version__.py +1 -1
- xcpcio/app/clics_uploader.py +1 -1
- xcpcio/clics/contest_uploader.py +1 -1
- xcpcio/clics/reader/contest_package_reader.py +31 -19
- {xcpcio-0.69.0.dist-info → xcpcio-0.69.2.dist-info}/METADATA +1 -1
- {xcpcio-0.69.0.dist-info → xcpcio-0.69.2.dist-info}/RECORD +8 -8
- {xcpcio-0.69.0.dist-info → xcpcio-0.69.2.dist-info}/WHEEL +0 -0
- {xcpcio-0.69.0.dist-info → xcpcio-0.69.2.dist-info}/entry_points.txt +0 -0
xcpcio/__version__.py
CHANGED
xcpcio/app/clics_uploader.py
CHANGED
|
@@ -51,7 +51,7 @@ def main(
|
|
|
51
51
|
verbose: bool,
|
|
52
52
|
):
|
|
53
53
|
"""
|
|
54
|
-
Upload CLICS Contest API data to
|
|
54
|
+
Upload CLICS Contest API data to XCPCIO with polling support.
|
|
55
55
|
|
|
56
56
|
This tool fetches contest data from a CLICS API and uploads raw JSON data to the xcpcio board-admin service.
|
|
57
57
|
It continuously polls every 5 seconds and uses SHA256 checksums to avoid uploading unchanged files.
|
xcpcio/clics/contest_uploader.py
CHANGED
|
@@ -239,7 +239,7 @@ class ContestUploader:
|
|
|
239
239
|
if not api_files:
|
|
240
240
|
return None
|
|
241
241
|
|
|
242
|
-
logger.info(f"Uploading {len(api_files)} API file(s) to
|
|
242
|
+
logger.info(f"Uploading {len(api_files)} API file(s) to XCPCIO...")
|
|
243
243
|
response = await self._api_client.upload_board_data(extra_files=api_files)
|
|
244
244
|
logger.info(f"API upload successful! ({len(api_files)} files)")
|
|
245
245
|
|
|
@@ -27,17 +27,26 @@ class ContestPackageReader(BaseContestReader):
|
|
|
27
27
|
res[item[id_name]].append(item)
|
|
28
28
|
return res
|
|
29
29
|
|
|
30
|
-
def _load_json_file(
|
|
30
|
+
def _load_json_file(
|
|
31
|
+
self,
|
|
32
|
+
filepath: str,
|
|
33
|
+
default_value: Optional[Union[Dict[str, Any], List[Any]]] = None,
|
|
34
|
+
) -> Union[Dict[str, Any], List[Any]]:
|
|
31
35
|
full_path = self.contest_package_dir / filepath
|
|
32
36
|
try:
|
|
33
37
|
with open(full_path, "r", encoding="utf-8") as f:
|
|
34
38
|
return json.load(f)
|
|
35
39
|
except FileNotFoundError:
|
|
40
|
+
if default_value is not None:
|
|
41
|
+
logger.warning("File not found, will return default value. [filepath={}]", filepath)
|
|
42
|
+
return default_value
|
|
36
43
|
raise HTTPException(status_code=404, detail=f"File not found: {filepath}")
|
|
37
44
|
except json.JSONDecodeError as e:
|
|
38
45
|
raise HTTPException(status_code=500, detail=f"Invalid JSON in file {filepath}: {e}")
|
|
39
46
|
|
|
40
|
-
def _load_ndjson_file(
|
|
47
|
+
def _load_ndjson_file(
|
|
48
|
+
self, filepath: str, default_value: Optional[List[Dict[str, Any]]] = None
|
|
49
|
+
) -> List[Dict[str, Any]]:
|
|
41
50
|
full_path = self.contest_package_dir / filepath
|
|
42
51
|
try:
|
|
43
52
|
data = list()
|
|
@@ -46,57 +55,60 @@ class ContestPackageReader(BaseContestReader):
|
|
|
46
55
|
data.append(json.loads(line))
|
|
47
56
|
return data
|
|
48
57
|
except FileNotFoundError:
|
|
58
|
+
if default_value is not None:
|
|
59
|
+
logger.warning("File not found, will load default value. [filepath={}]", filepath)
|
|
60
|
+
return default_value
|
|
49
61
|
raise HTTPException(status_code=404, detail=f"File not found: {filepath}")
|
|
50
62
|
except json.JSONDecodeError as e:
|
|
51
63
|
raise HTTPException(status_code=500, detail=f"Invalid JSON in file {filepath}: {e}")
|
|
52
64
|
|
|
53
65
|
def _load_indexes(self) -> None:
|
|
54
|
-
self.access = self._load_json_file("access.json")
|
|
66
|
+
self.access = self._load_json_file("access.json", default_value={})
|
|
55
67
|
|
|
56
|
-
self.accounts = self._load_json_file("accounts.json")
|
|
68
|
+
self.accounts = self._load_json_file("accounts.json", default_value=[])
|
|
57
69
|
self.accounts_by_id = {account["id"]: account for account in self.accounts}
|
|
58
70
|
|
|
59
|
-
self.api_info = self._load_json_file("api.json")
|
|
71
|
+
self.api_info = self._load_json_file("api.json", default_value={})
|
|
60
72
|
|
|
61
|
-
self.awards = self._load_json_file("awards.json")
|
|
73
|
+
self.awards = self._load_json_file("awards.json", default_value=[])
|
|
62
74
|
self.awards_by_id = {award["id"]: award for award in self.awards}
|
|
63
75
|
|
|
64
|
-
self.clarifications = self._load_json_file("clarifications.json")
|
|
76
|
+
self.clarifications = self._load_json_file("clarifications.json", default_value=[])
|
|
65
77
|
self.clarifications_by_id = {clarification["id"]: clarification for clarification in self.clarifications}
|
|
66
78
|
|
|
67
|
-
self.contest = self._load_json_file("contest.json")
|
|
68
|
-
self.contest_state = self._load_json_file("state.json")
|
|
79
|
+
self.contest = self._load_json_file("contest.json", default_value={})
|
|
80
|
+
self.contest_state = self._load_json_file("state.json", default_value={})
|
|
69
81
|
|
|
70
|
-
self.groups = self._load_json_file("groups.json")
|
|
82
|
+
self.groups = self._load_json_file("groups.json", default_value=[])
|
|
71
83
|
self.groups_by_id = {group["id"]: group for group in self.groups}
|
|
72
84
|
|
|
73
|
-
self.judgement_types = self._load_json_file("judgement-types.json")
|
|
85
|
+
self.judgement_types = self._load_json_file("judgement-types.json", default_value=[])
|
|
74
86
|
self.judgement_types_by_id = {judgement_type["id"]: judgement_type for judgement_type in self.judgement_types}
|
|
75
87
|
|
|
76
|
-
self.judgements = self._load_json_file("judgements.json")
|
|
88
|
+
self.judgements = self._load_json_file("judgements.json", default_value=[])
|
|
77
89
|
self.judgements_by_id = {judgement["id"]: judgement for judgement in self.judgements}
|
|
78
90
|
self.judgements_by_submission_id = self._create_index_by_id(self.judgements, "submission_id")
|
|
79
91
|
|
|
80
|
-
self.languages = self._load_json_file("languages.json")
|
|
92
|
+
self.languages = self._load_json_file("languages.json", default_value=[])
|
|
81
93
|
self.languages_by_id = {language["id"]: language for language in self.languages}
|
|
82
94
|
|
|
83
|
-
self.organizations = self._load_json_file("organizations.json")
|
|
95
|
+
self.organizations = self._load_json_file("organizations.json", default_value=[])
|
|
84
96
|
self.organizations_by_id = {org["id"]: org for org in self.organizations}
|
|
85
97
|
|
|
86
|
-
self.problems = self._load_json_file("problems.json")
|
|
98
|
+
self.problems = self._load_json_file("problems.json", default_value=[])
|
|
87
99
|
self.problems_by_id = {problem["id"]: problem for problem in self.problems}
|
|
88
100
|
|
|
89
|
-
self.runs = self._load_json_file("runs.json")
|
|
101
|
+
self.runs = self._load_json_file("runs.json", default_value=[])
|
|
90
102
|
self.runs_by_id = {run["id"]: run for run in self.runs}
|
|
91
103
|
self.runs_by_judgement_id = self._create_index_by_id(self.runs, "judgement_id")
|
|
92
104
|
|
|
93
|
-
self.submissions = self._load_json_file("submissions.json")
|
|
105
|
+
self.submissions = self._load_json_file("submissions.json", default_value=[])
|
|
94
106
|
self.submissions_by_id = {submission["id"]: submission for submission in self.submissions}
|
|
95
107
|
|
|
96
|
-
self.teams = self._load_json_file("teams.json")
|
|
108
|
+
self.teams = self._load_json_file("teams.json", default_value=[])
|
|
97
109
|
self.teams_by_id = {team["id"]: team for team in self.teams}
|
|
98
110
|
|
|
99
|
-
self.event_feed = self._load_ndjson_file("event-feed.ndjson")
|
|
111
|
+
self.event_feed = self._load_ndjson_file("event-feed.ndjson", default_value=[])
|
|
100
112
|
self.event_feed_tokens = [event["token"] for event in self.event_feed]
|
|
101
113
|
|
|
102
114
|
self.contest_id = self.contest["id"]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
xcpcio/__init__.py,sha256=NB6wpVr5JUrOx2vLIQSVtYuCz0d7kNFE39TSQlvoENk,125
|
|
2
|
-
xcpcio/__version__.py,sha256=
|
|
2
|
+
xcpcio/__version__.py,sha256=PvjPXbHRuuaoDW81aw_C7GwWvp2Ic1Jtr2QT5eokctk,172
|
|
3
3
|
xcpcio/constants.py,sha256=MjpAgNXiBlUsx1S09m7JNT-nekNDR-aE6ggvGL3fg0I,2297
|
|
4
4
|
xcpcio/types.py,sha256=GElkg8wz2BloN6PzyjvLrrd2h7Lm5itaaNnZv3hVQ-U,7591
|
|
5
5
|
xcpcio/api/__init__.py,sha256=fFRUU0d_cUG-uzG2rLgirqRng8Z3UoV5ZCkBiYuXdu0,302
|
|
@@ -7,11 +7,11 @@ xcpcio/api/client.py,sha256=TEcf3tjLu537HHhyBBVHlQ3fFL7_abjG3IrQtp39oks,2389
|
|
|
7
7
|
xcpcio/api/models.py,sha256=DBS9TjtPSX32TpwO3gYnnGo7RFHLHrxYpRIAhxCHmLs,1258
|
|
8
8
|
xcpcio/app/clics_archiver.py,sha256=wd7zkbq2oyWfkS09w0f3KBr32F2yCcTMx36H5HFMgRg,7995
|
|
9
9
|
xcpcio/app/clics_server.py,sha256=-zUixNf08yICT2sry23h72ZrEm6NPb30bH5AHCXZlBM,4623
|
|
10
|
-
xcpcio/app/clics_uploader.py,sha256=
|
|
10
|
+
xcpcio/app/clics_uploader.py,sha256=9sgjnIvmuEhP3LjsdmVa0Rps42ij3j49dHBnr3KsM3I,3456
|
|
11
11
|
xcpcio/clics/__init__.py,sha256=coTZiqxzXesn2SYmI2ZCsDZW6XaFi_6p-PFozZ4dfl4,150
|
|
12
12
|
xcpcio/clics/clics_api_client.py,sha256=N6mYlou6eTrQYiUKxE4fdwCClCt9DrmVyKQmpc53iaY,9670
|
|
13
13
|
xcpcio/clics/contest_archiver.py,sha256=9q3qB4hOPfd4ttaG78cQ7sg7vWkumO_KUZpqwYlHDlM,9933
|
|
14
|
-
xcpcio/clics/contest_uploader.py,sha256=
|
|
14
|
+
xcpcio/clics/contest_uploader.py,sha256=6U22U7YYHQY4F4GC8mjyD528QD-LAF5nopHs-zXTeOQ,9930
|
|
15
15
|
xcpcio/clics/api_server/__init__.py,sha256=ASvVJ_ibGkXFDSNmy05eb9gESXRS8hjYHCrBecSnaS0,174
|
|
16
16
|
xcpcio/clics/api_server/app.py,sha256=dYvkxaR8PjkDIHbSX8YyU3TvPud93Dg29k6midylakE,979
|
|
17
17
|
xcpcio/clics/api_server/dependencies.py,sha256=2Zhom6vUnAOikr9bh-_kXYCc3g6JGXReVuQX7Ok90r4,1444
|
|
@@ -40,9 +40,9 @@ xcpcio/clics/model/__init__.py,sha256=cZE1q5JY-iHDEKZpsx0UZaMhH-23H4oAHaYOkW7dZ5
|
|
|
40
40
|
xcpcio/clics/model/model_2023_06/__init__.py,sha256=VzBaFcAwYw9G18p0Lh7rNPrvchyaYx_jgw6YE4W1yNg,168
|
|
41
41
|
xcpcio/clics/model/model_2023_06/model.py,sha256=bVMDWpJTwPSpz1fHPxWrWerxCBIboH3LKVZpIZGQ2pY,15287
|
|
42
42
|
xcpcio/clics/reader/__init__.py,sha256=Nfi78X8J1tJPh7WeSRPLMRUprlS2JYelYJHW4DfyJ7U,162
|
|
43
|
-
xcpcio/clics/reader/contest_package_reader.py,sha256=
|
|
43
|
+
xcpcio/clics/reader/contest_package_reader.py,sha256=baUEtH62ci4q7yMwR0BnTqUy6YU7zd5XogVVqZtEk0s,15081
|
|
44
44
|
xcpcio/clics/reader/interface.py,sha256=lK2JXU1n8GJ4PecXnfFBijMaCVLYk404e4QwV_Ti2Hk,3918
|
|
45
|
-
xcpcio-0.69.
|
|
46
|
-
xcpcio-0.69.
|
|
47
|
-
xcpcio-0.69.
|
|
48
|
-
xcpcio-0.69.
|
|
45
|
+
xcpcio-0.69.2.dist-info/METADATA,sha256=Ez3KGwkANQ9rTmProPurxv1jehMBkyq8fpM9YAvAMLs,2233
|
|
46
|
+
xcpcio-0.69.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
47
|
+
xcpcio-0.69.2.dist-info/entry_points.txt,sha256=KxviS5TVXlZ9KqS9UNMx3nI15xhEGvkTq86RaPhUhs4,158
|
|
48
|
+
xcpcio-0.69.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|