xcpcio 0.65.0__tar.gz → 0.65.1__tar.gz
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-0.65.0 → xcpcio-0.65.1}/PKG-INFO +1 -1
- {xcpcio-0.65.0 → xcpcio-0.65.1}/tests/test_contest.py +9 -15
- {xcpcio-0.65.0 → xcpcio-0.65.1}/tests/test_types.py +4 -4
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/__version__.py +1 -1
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/types.py +20 -20
- {xcpcio-0.65.0 → xcpcio-0.65.1}/.gitignore +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/.python-version +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/README.md +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/pyproject.toml +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/scripts/generate_ccs_models.sh +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/tests/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/tests/test_submission.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/tests/test_team.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/uv.lock +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/api/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/api/client.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/api/models.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/app/clics_archiver.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/app/clics_server.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/app.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/dependencies.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/access.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/accounts.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/awards.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/clarifications.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/contests.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/general.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/groups.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/judgement_types.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/judgements.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/languages.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/organizations.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/problems.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/runs.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/submissions.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/teams.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/server.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/services/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/api_server/services/contest_service.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/base/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/base/types.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/clics_api_client.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/contest_archiver.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/model/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/model/model_2023_06/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/model/model_2023_06/model.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/reader/__init__.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/reader/contest_package_reader.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/clics/reader/interface.py +0 -0
- {xcpcio-0.65.0 → xcpcio-0.65.1}/xcpcio/constants.py +0 -0
|
@@ -15,8 +15,7 @@ class TestContest:
|
|
|
15
15
|
assert contest.frozen_time == 60 * 60 # 1 hour
|
|
16
16
|
assert contest.unfrozen_time == 0x3F3F3F3F3F3F3F3F
|
|
17
17
|
assert contest.penalty == 20 * 60 # 20 minutes
|
|
18
|
-
assert contest.
|
|
19
|
-
assert contest.problem_id == []
|
|
18
|
+
assert contest.problem_id is None
|
|
20
19
|
assert contest.organization == "School"
|
|
21
20
|
assert contest.medal is None
|
|
22
21
|
assert contest.balloon_color is None
|
|
@@ -55,7 +54,6 @@ class TestContest:
|
|
|
55
54
|
assert contest.contest_name == "ICPC World Finals 2024"
|
|
56
55
|
assert contest.start_time == 1234567890
|
|
57
56
|
assert contest.end_time == 1234567890 + 5 * 60 * 60
|
|
58
|
-
assert contest.problem_quantity == 12
|
|
59
57
|
assert len(contest.problem_id) == 12
|
|
60
58
|
assert contest.problem_id[0] == "A"
|
|
61
59
|
assert contest.problem_id[-1] == "L"
|
|
@@ -69,7 +67,6 @@ class TestContest:
|
|
|
69
67
|
contest_name="Test Contest",
|
|
70
68
|
start_time=1000000000,
|
|
71
69
|
end_time=1000000000 + 60 * 60 * 5,
|
|
72
|
-
problem_quantity=5,
|
|
73
70
|
problem_id=["A", "B", "C", "D", "E"],
|
|
74
71
|
organization="Test Org",
|
|
75
72
|
)
|
|
@@ -78,7 +75,6 @@ class TestContest:
|
|
|
78
75
|
contest_dict = contest.model_dump()
|
|
79
76
|
assert contest_dict["contest_name"] == "Test Contest"
|
|
80
77
|
assert contest_dict["start_time"] == 1000000000
|
|
81
|
-
assert contest_dict["problem_quantity"] == 5
|
|
82
78
|
assert contest_dict["organization"] == "Test Org"
|
|
83
79
|
|
|
84
80
|
# Test JSON round-trip
|
|
@@ -97,7 +93,6 @@ class TestContest:
|
|
|
97
93
|
|
|
98
94
|
contest = Contest(
|
|
99
95
|
contest_name="Contest with Media",
|
|
100
|
-
problem_quantity=2,
|
|
101
96
|
balloon_color=colors,
|
|
102
97
|
logo=logo,
|
|
103
98
|
banner=banner,
|
|
@@ -135,32 +130,32 @@ class TestContest:
|
|
|
135
130
|
|
|
136
131
|
def test_fill_problem_id(self):
|
|
137
132
|
"""Test fill_problem_id method"""
|
|
138
|
-
contest = Contest(
|
|
133
|
+
contest = Contest()
|
|
139
134
|
|
|
140
135
|
# Initially empty
|
|
141
|
-
assert contest.problem_id
|
|
136
|
+
assert contest.problem_id is None
|
|
142
137
|
|
|
143
138
|
# Fill with A-E
|
|
144
|
-
contest.fill_problem_id()
|
|
139
|
+
contest.fill_problem_id(5)
|
|
145
140
|
|
|
146
141
|
assert len(contest.problem_id) == 5
|
|
147
142
|
assert contest.problem_id == ["A", "B", "C", "D", "E"]
|
|
148
143
|
|
|
149
144
|
# Test with larger quantity
|
|
150
|
-
contest.
|
|
151
|
-
contest.fill_problem_id()
|
|
145
|
+
contest.fill_problem_id(10)
|
|
152
146
|
|
|
153
147
|
assert len(contest.problem_id) == 10
|
|
154
148
|
assert contest.problem_id == ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
|
|
155
149
|
|
|
156
150
|
def test_fill_balloon_color(self):
|
|
157
151
|
"""Test fill_balloon_color method"""
|
|
158
|
-
contest = Contest(
|
|
152
|
+
contest = Contest()
|
|
159
153
|
|
|
160
154
|
# Initially no colors
|
|
161
155
|
assert contest.balloon_color is None
|
|
162
156
|
|
|
163
|
-
# Fill
|
|
157
|
+
# Fill problem IDs first, then balloon colors
|
|
158
|
+
contest.fill_problem_id(3)
|
|
164
159
|
contest.fill_balloon_color()
|
|
165
160
|
|
|
166
161
|
assert contest.balloon_color is not None
|
|
@@ -180,13 +175,12 @@ class TestContest:
|
|
|
180
175
|
contest_name="Complex Contest",
|
|
181
176
|
start_time=1234567890,
|
|
182
177
|
end_time=1234567890 + 5 * 60 * 60,
|
|
183
|
-
problem_quantity=3,
|
|
184
178
|
organization="Complex Org",
|
|
185
179
|
medal="ccpc", # Use preset instead of dict
|
|
186
180
|
)
|
|
187
181
|
|
|
188
182
|
# Add problem IDs and colors
|
|
189
|
-
contest.fill_problem_id()
|
|
183
|
+
contest.fill_problem_id(3)
|
|
190
184
|
contest.fill_balloon_color()
|
|
191
185
|
|
|
192
186
|
# Add logo
|
|
@@ -101,8 +101,8 @@ class TestSubmissionReaction:
|
|
|
101
101
|
|
|
102
102
|
def test_reaction_empty(self):
|
|
103
103
|
"""Test SubmissionReaction with default values"""
|
|
104
|
-
reaction = SubmissionReaction()
|
|
105
|
-
assert reaction.url
|
|
104
|
+
reaction = SubmissionReaction(url="")
|
|
105
|
+
assert reaction.url == ""
|
|
106
106
|
|
|
107
107
|
def test_reaction_with_url(self):
|
|
108
108
|
"""Test SubmissionReaction with URL"""
|
|
@@ -124,10 +124,10 @@ class TestSubmissionReaction:
|
|
|
124
124
|
|
|
125
125
|
def test_reaction_no_url_serialization(self):
|
|
126
126
|
"""Test SubmissionReaction serialization with no URL"""
|
|
127
|
-
reaction = SubmissionReaction()
|
|
127
|
+
reaction = SubmissionReaction(url="")
|
|
128
128
|
|
|
129
129
|
reaction_dict = reaction.model_dump()
|
|
130
|
-
assert reaction_dict["url"]
|
|
130
|
+
assert reaction_dict["url"] == ""
|
|
131
131
|
|
|
132
132
|
# Test JSON round-trip
|
|
133
133
|
reaction_json = reaction.model_dump_json()
|
|
@@ -74,15 +74,6 @@ class I18NStringSet(BaseModel):
|
|
|
74
74
|
Text = Union[str, I18NStringSet]
|
|
75
75
|
|
|
76
76
|
|
|
77
|
-
class Person(BaseModel):
|
|
78
|
-
name: Text
|
|
79
|
-
cf_id: Optional[str] = None
|
|
80
|
-
icpc_id: Optional[str] = None
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
Persons = List[Person]
|
|
84
|
-
|
|
85
|
-
|
|
86
77
|
class Image(BaseModel):
|
|
87
78
|
url: Optional[str] = None
|
|
88
79
|
base64: Optional[str] = None
|
|
@@ -95,6 +86,15 @@ class BalloonColor(BaseModel):
|
|
|
95
86
|
background_color: str
|
|
96
87
|
|
|
97
88
|
|
|
89
|
+
class Person(BaseModel):
|
|
90
|
+
name: Text
|
|
91
|
+
cf_id: Optional[str] = None
|
|
92
|
+
icpc_id: Optional[str] = None
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
Persons = List[Person]
|
|
96
|
+
|
|
97
|
+
|
|
98
98
|
class Problem(BaseModel):
|
|
99
99
|
id: str
|
|
100
100
|
label: str
|
|
@@ -108,7 +108,7 @@ Problems = List[Problem]
|
|
|
108
108
|
|
|
109
109
|
|
|
110
110
|
class SubmissionReaction(BaseModel):
|
|
111
|
-
url:
|
|
111
|
+
url: str
|
|
112
112
|
|
|
113
113
|
|
|
114
114
|
class Submission(BaseModel):
|
|
@@ -129,7 +129,7 @@ class Submission(BaseModel):
|
|
|
129
129
|
|
|
130
130
|
|
|
131
131
|
class Submissions(RootModel[List[Submission]]):
|
|
132
|
-
|
|
132
|
+
pass
|
|
133
133
|
|
|
134
134
|
|
|
135
135
|
class Team(BaseModel):
|
|
@@ -138,7 +138,7 @@ class Team(BaseModel):
|
|
|
138
138
|
|
|
139
139
|
organization: str = ""
|
|
140
140
|
group: List[str] = Field(default_factory=list)
|
|
141
|
-
tag: List[str] =
|
|
141
|
+
tag: Optional[List[str]] = None
|
|
142
142
|
|
|
143
143
|
coaches: Optional[Union[Text, List[Text], Persons]] = None
|
|
144
144
|
members: Optional[Union[Text, List[Text], Persons]] = None
|
|
@@ -179,14 +179,13 @@ class Contest(BaseModel):
|
|
|
179
179
|
|
|
180
180
|
freeze_time: Optional[Union[int, DateTimeISO8601String]] = None
|
|
181
181
|
frozen_time: int = 60 * 60 # unit: seconds
|
|
182
|
-
unfrozen_time: int = 0x3F3F3F3F3F3F3F3F
|
|
183
182
|
|
|
184
183
|
problems: Optional[Problems] = None
|
|
185
|
-
|
|
186
|
-
problem_id: List[str] =
|
|
184
|
+
|
|
185
|
+
problem_id: Optional[List[str]] = None
|
|
187
186
|
balloon_color: Optional[List[BalloonColor]] = None
|
|
188
187
|
|
|
189
|
-
status_time_display:
|
|
188
|
+
status_time_display: Dict[str, bool] = constants.FULL_STATUS_TIME_DISPLAY
|
|
190
189
|
|
|
191
190
|
badge: Optional[str] = None
|
|
192
191
|
organization: str = "School"
|
|
@@ -205,14 +204,16 @@ class Contest(BaseModel):
|
|
|
205
204
|
|
|
206
205
|
options: ContestOptions = Field(default_factory=ContestOptions)
|
|
207
206
|
|
|
207
|
+
unfrozen_time: int = 0x3F3F3F3F3F3F3F3F
|
|
208
|
+
|
|
208
209
|
def append_balloon_color(self, color: BalloonColor):
|
|
209
210
|
if self.balloon_color is None:
|
|
210
211
|
self.balloon_color = []
|
|
211
212
|
self.balloon_color.append(color)
|
|
212
213
|
return self
|
|
213
214
|
|
|
214
|
-
def fill_problem_id(self):
|
|
215
|
-
self.problem_id = [chr(ord("A") + i) for i in range(
|
|
215
|
+
def fill_problem_id(self, problem_quantity: int):
|
|
216
|
+
self.problem_id = [chr(ord("A") + i) for i in range(problem_quantity)]
|
|
216
217
|
return self
|
|
217
218
|
|
|
218
219
|
def fill_balloon_color(self):
|
|
@@ -232,7 +233,6 @@ class Contest(BaseModel):
|
|
|
232
233
|
BalloonColor(background_color="rgba(144, 238, 144, 0.7)", color="#000"),
|
|
233
234
|
BalloonColor(background_color="rgba(77, 57, 0, 0.7)", color="#fff"),
|
|
234
235
|
]
|
|
235
|
-
|
|
236
|
-
self.balloon_color = default_balloon_color_list[: self.problem_quantity]
|
|
236
|
+
self.balloon_color = default_balloon_color_list[: len(self.problem_id)]
|
|
237
237
|
|
|
238
238
|
return self
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|