xcpcio 0.64.5__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.64.5 → xcpcio-0.65.1}/PKG-INFO +1 -1
- {xcpcio-0.64.5 → xcpcio-0.65.1}/tests/test_contest.py +15 -21
- {xcpcio-0.64.5 → xcpcio-0.65.1}/tests/test_submission.py +6 -5
- {xcpcio-0.64.5 → xcpcio-0.65.1}/tests/test_team.py +6 -6
- {xcpcio-0.64.5 → xcpcio-0.65.1}/tests/test_types.py +22 -22
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/__version__.py +1 -1
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/types.py +71 -37
- {xcpcio-0.64.5 → xcpcio-0.65.1}/.gitignore +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/.python-version +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/README.md +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/pyproject.toml +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/scripts/generate_ccs_models.sh +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/tests/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/uv.lock +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/api/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/api/client.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/api/models.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/app/clics_archiver.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/app/clics_server.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/app.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/dependencies.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/access.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/accounts.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/awards.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/clarifications.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/contests.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/general.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/groups.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/judgement_types.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/judgements.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/languages.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/organizations.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/problems.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/runs.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/submissions.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/routes/teams.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/server.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/services/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/api_server/services/contest_service.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/base/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/base/types.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/clics_api_client.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/contest_archiver.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/model/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/model/model_2023_06/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/model/model_2023_06/model.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/reader/__init__.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/reader/contest_package_reader.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/clics/reader/interface.py +0 -0
- {xcpcio-0.64.5 → xcpcio-0.65.1}/xcpcio/constants.py +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from xcpcio import constants
|
|
2
|
-
from xcpcio.types import
|
|
2
|
+
from xcpcio.types import BalloonColor, Contest, ContestOptions, Image
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class TestContest:
|
|
@@ -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
|
|
@@ -89,15 +85,14 @@ class TestContest:
|
|
|
89
85
|
def test_contest_with_colors_and_images(self):
|
|
90
86
|
"""Test Contest with balloon colors, logo, and banner"""
|
|
91
87
|
colors = [
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
BalloonColor(color="#fff", background_color="rgba(255, 0, 0, 0.7)"),
|
|
89
|
+
BalloonColor(color="#000", background_color="rgba(0, 255, 0, 0.7)"),
|
|
94
90
|
]
|
|
95
91
|
logo = Image(url="https://example.com/logo.png", type="png")
|
|
96
92
|
banner = Image(url="https://example.com/banner.jpg", type="jpg")
|
|
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,
|
|
@@ -119,7 +114,7 @@ class TestContest:
|
|
|
119
114
|
assert contest.balloon_color is None
|
|
120
115
|
|
|
121
116
|
# Add first color
|
|
122
|
-
red_color =
|
|
117
|
+
red_color = BalloonColor(color="#fff", background_color="red")
|
|
123
118
|
contest.append_balloon_color(red_color)
|
|
124
119
|
|
|
125
120
|
assert contest.balloon_color is not None
|
|
@@ -127,7 +122,7 @@ class TestContest:
|
|
|
127
122
|
assert contest.balloon_color[0] == red_color
|
|
128
123
|
|
|
129
124
|
# Add second color
|
|
130
|
-
blue_color =
|
|
125
|
+
blue_color = BalloonColor(color="#fff", background_color="blue")
|
|
131
126
|
contest.append_balloon_color(blue_color)
|
|
132
127
|
|
|
133
128
|
assert len(contest.balloon_color) == 2
|
|
@@ -135,37 +130,37 @@ 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
|
|
167
162
|
assert len(contest.balloon_color) == 3
|
|
168
|
-
assert all(isinstance(color,
|
|
163
|
+
assert all(isinstance(color, BalloonColor) for color in contest.balloon_color)
|
|
169
164
|
|
|
170
165
|
# Check first few default colors
|
|
171
166
|
assert contest.balloon_color[0].background_color == "rgba(189, 14, 14, 0.7)"
|
|
@@ -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
|
|
@@ -3,7 +3,7 @@ import json
|
|
|
3
3
|
import pytest
|
|
4
4
|
|
|
5
5
|
from xcpcio import constants
|
|
6
|
-
from xcpcio.types import
|
|
6
|
+
from xcpcio.types import SubmissionReaction, Submission, Submissions
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class TestSubmission:
|
|
@@ -12,7 +12,8 @@ class TestSubmission:
|
|
|
12
12
|
def test_submission_creation_defaults(self):
|
|
13
13
|
"""Test Submission creation with default values"""
|
|
14
14
|
submission = Submission()
|
|
15
|
-
assert submission.id
|
|
15
|
+
assert submission.id is None
|
|
16
|
+
assert submission.submission_id is None
|
|
16
17
|
assert submission.team_id == ""
|
|
17
18
|
assert submission.problem_id == 0
|
|
18
19
|
assert submission.timestamp == 0
|
|
@@ -24,7 +25,7 @@ class TestSubmission:
|
|
|
24
25
|
|
|
25
26
|
def test_submission_creation_with_values(self):
|
|
26
27
|
"""Test Submission creation with provided values"""
|
|
27
|
-
reaction =
|
|
28
|
+
reaction = SubmissionReaction(url="https://reaction.com/video.mp4")
|
|
28
29
|
submission = Submission(
|
|
29
30
|
id="sub_001",
|
|
30
31
|
status=constants.SUBMISSION_STATUS_ACCEPTED,
|
|
@@ -79,7 +80,7 @@ class TestSubmission:
|
|
|
79
80
|
|
|
80
81
|
def test_submission_with_reaction_serialization(self):
|
|
81
82
|
"""Test Submission with Reaction serialization"""
|
|
82
|
-
reaction =
|
|
83
|
+
reaction = SubmissionReaction(url="https://example.com/reaction.mp4")
|
|
83
84
|
submission = Submission(
|
|
84
85
|
id="sub_003",
|
|
85
86
|
status=constants.SUBMISSION_STATUS_ACCEPTED,
|
|
@@ -125,7 +126,7 @@ class TestSubmissions:
|
|
|
125
126
|
timestamp=1234567891,
|
|
126
127
|
time=300,
|
|
127
128
|
language="C++",
|
|
128
|
-
reaction=
|
|
129
|
+
reaction=SubmissionReaction(url="https://reaction.com/video.mp4"),
|
|
129
130
|
),
|
|
130
131
|
Submission(
|
|
131
132
|
id="sub_003",
|
|
@@ -15,7 +15,7 @@ class TestTeam:
|
|
|
15
15
|
assert team.name == ""
|
|
16
16
|
assert team.organization == ""
|
|
17
17
|
assert team.members is None
|
|
18
|
-
assert team.
|
|
18
|
+
assert team.coaches is None
|
|
19
19
|
assert team.location is None
|
|
20
20
|
assert team.group == []
|
|
21
21
|
assert team.extra == {}
|
|
@@ -27,7 +27,7 @@ class TestTeam:
|
|
|
27
27
|
name="Test Team",
|
|
28
28
|
organization="Test University",
|
|
29
29
|
members=["Alice", "Bob", "Charlie"],
|
|
30
|
-
|
|
30
|
+
coaches="Dr. Smith",
|
|
31
31
|
location="Building A",
|
|
32
32
|
)
|
|
33
33
|
|
|
@@ -35,7 +35,7 @@ class TestTeam:
|
|
|
35
35
|
assert team.name == "Test Team"
|
|
36
36
|
assert team.organization == "Test University"
|
|
37
37
|
assert team.members == ["Alice", "Bob", "Charlie"]
|
|
38
|
-
assert team.
|
|
38
|
+
assert team.coaches == "Dr. Smith"
|
|
39
39
|
assert team.location == "Building A"
|
|
40
40
|
|
|
41
41
|
def test_group_management(self):
|
|
@@ -75,7 +75,7 @@ class TestTeamSerialization:
|
|
|
75
75
|
name="Alpha Team",
|
|
76
76
|
organization="University A",
|
|
77
77
|
members=["Alice", "Bob", "Charlie"],
|
|
78
|
-
|
|
78
|
+
coaches="Dr. Smith",
|
|
79
79
|
location="Building A",
|
|
80
80
|
group=["undergraduate", "local"],
|
|
81
81
|
extra={"room": "101", "contact": "alice@test.edu"},
|
|
@@ -90,7 +90,7 @@ class TestTeamSerialization:
|
|
|
90
90
|
assert team_dict["name"] == "Alpha Team"
|
|
91
91
|
assert team_dict["organization"] == "University A"
|
|
92
92
|
assert team_dict["members"] == ["Alice", "Bob", "Charlie"]
|
|
93
|
-
assert team_dict["
|
|
93
|
+
assert team_dict["coaches"] == "Dr. Smith"
|
|
94
94
|
assert team_dict["location"] == "Building A"
|
|
95
95
|
assert team_dict["group"] == ["undergraduate", "local"]
|
|
96
96
|
assert team_dict["extra"] == {"room": "101", "contact": "alice@test.edu"}
|
|
@@ -161,7 +161,7 @@ class TestTeamList:
|
|
|
161
161
|
name="Alpha Team",
|
|
162
162
|
organization="University A",
|
|
163
163
|
members=["Alice", "Bob"],
|
|
164
|
-
|
|
164
|
+
coaches="Coach A",
|
|
165
165
|
),
|
|
166
166
|
Team(
|
|
167
167
|
id="team002",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from xcpcio import constants
|
|
2
|
-
from xcpcio.types import
|
|
2
|
+
from xcpcio.types import BalloonColor, ContestOptions, Image, SubmissionReaction
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class TestImage:
|
|
@@ -35,18 +35,18 @@ class TestImage:
|
|
|
35
35
|
assert reconstructed_image == image
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
class
|
|
39
|
-
"""Test cases for
|
|
38
|
+
class TestBalloonColor:
|
|
39
|
+
"""Test cases for BalloonColor Pydantic model"""
|
|
40
40
|
|
|
41
41
|
def test_color_creation(self):
|
|
42
|
-
"""Test
|
|
43
|
-
color =
|
|
42
|
+
"""Test BalloonColor creation"""
|
|
43
|
+
color = BalloonColor(color="#ffffff", background_color="#000000")
|
|
44
44
|
assert color.color == "#ffffff"
|
|
45
45
|
assert color.background_color == "#000000"
|
|
46
46
|
|
|
47
47
|
def test_color_serialization(self):
|
|
48
|
-
"""Test
|
|
49
|
-
color =
|
|
48
|
+
"""Test BalloonColor serialization and deserialization"""
|
|
49
|
+
color = BalloonColor(color="red", background_color="blue")
|
|
50
50
|
|
|
51
51
|
# Test model_dump
|
|
52
52
|
color_dict = color.model_dump()
|
|
@@ -55,7 +55,7 @@ class TestColor:
|
|
|
55
55
|
|
|
56
56
|
# Test JSON round-trip
|
|
57
57
|
color_json = color.model_dump_json()
|
|
58
|
-
reconstructed_color =
|
|
58
|
+
reconstructed_color = BalloonColor.model_validate_json(color_json)
|
|
59
59
|
assert reconstructed_color == color
|
|
60
60
|
|
|
61
61
|
|
|
@@ -96,22 +96,22 @@ class TestContestOptions:
|
|
|
96
96
|
assert reconstructed_options == options
|
|
97
97
|
|
|
98
98
|
|
|
99
|
-
class
|
|
100
|
-
"""Test cases for
|
|
99
|
+
class TestSubmissionReaction:
|
|
100
|
+
"""Test cases for SubmissionReaction Pydantic model"""
|
|
101
101
|
|
|
102
102
|
def test_reaction_empty(self):
|
|
103
|
-
"""Test
|
|
104
|
-
reaction =
|
|
105
|
-
assert reaction.url
|
|
103
|
+
"""Test SubmissionReaction with default values"""
|
|
104
|
+
reaction = SubmissionReaction(url="")
|
|
105
|
+
assert reaction.url == ""
|
|
106
106
|
|
|
107
107
|
def test_reaction_with_url(self):
|
|
108
|
-
"""Test
|
|
109
|
-
reaction =
|
|
108
|
+
"""Test SubmissionReaction with URL"""
|
|
109
|
+
reaction = SubmissionReaction(url="https://reaction.com/video.mp4")
|
|
110
110
|
assert reaction.url == "https://reaction.com/video.mp4"
|
|
111
111
|
|
|
112
112
|
def test_reaction_serialization(self):
|
|
113
|
-
"""Test
|
|
114
|
-
reaction =
|
|
113
|
+
"""Test SubmissionReaction serialization"""
|
|
114
|
+
reaction = SubmissionReaction(url="https://test.com/reaction.mp4")
|
|
115
115
|
|
|
116
116
|
# Test model_dump
|
|
117
117
|
reaction_dict = reaction.model_dump()
|
|
@@ -119,17 +119,17 @@ class TestReaction:
|
|
|
119
119
|
|
|
120
120
|
# Test JSON round-trip
|
|
121
121
|
reaction_json = reaction.model_dump_json()
|
|
122
|
-
reconstructed_reaction =
|
|
122
|
+
reconstructed_reaction = SubmissionReaction.model_validate_json(reaction_json)
|
|
123
123
|
assert reconstructed_reaction == reaction
|
|
124
124
|
|
|
125
125
|
def test_reaction_no_url_serialization(self):
|
|
126
|
-
"""Test
|
|
127
|
-
reaction =
|
|
126
|
+
"""Test SubmissionReaction serialization with no URL"""
|
|
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()
|
|
134
|
-
reconstructed_reaction =
|
|
134
|
+
reconstructed_reaction = SubmissionReaction.model_validate_json(reaction_json)
|
|
135
135
|
assert reconstructed_reaction == reaction
|
|
@@ -61,9 +61,19 @@ SubmissionStatus = Literal[
|
|
|
61
61
|
ImagePreset = Literal["ICPC", "CCPC", "HUNAN_CPC"]
|
|
62
62
|
MedalPreset = Literal["ccpc", "icpc"]
|
|
63
63
|
BannerMode = Literal["ONLY_BANNER", "ALL"]
|
|
64
|
+
Lang = Literal["en", "zh-CN"]
|
|
64
65
|
DateTimeISO8601String = str
|
|
65
66
|
|
|
66
67
|
|
|
68
|
+
class I18NStringSet(BaseModel):
|
|
69
|
+
fallback: Optional[str] = None
|
|
70
|
+
fallback_lang: Optional[Lang] = None
|
|
71
|
+
texts: Optional[Dict[Lang, str]] = None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
Text = Union[str, I18NStringSet]
|
|
75
|
+
|
|
76
|
+
|
|
67
77
|
class Image(BaseModel):
|
|
68
78
|
url: Optional[str] = None
|
|
69
79
|
base64: Optional[str] = None
|
|
@@ -71,20 +81,42 @@ class Image(BaseModel):
|
|
|
71
81
|
preset: Optional[ImagePreset] = None
|
|
72
82
|
|
|
73
83
|
|
|
74
|
-
class
|
|
84
|
+
class BalloonColor(BaseModel):
|
|
75
85
|
color: str
|
|
76
86
|
background_color: str
|
|
77
87
|
|
|
78
88
|
|
|
79
|
-
class
|
|
80
|
-
|
|
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
|
+
class Problem(BaseModel):
|
|
99
|
+
id: str
|
|
100
|
+
label: str
|
|
101
|
+
name: Optional[Text] = None
|
|
102
|
+
time_limit: Optional[str] = None
|
|
103
|
+
memory_limit: Optional[str] = None
|
|
104
|
+
balloon_color: Optional[BalloonColor] = None
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
Problems = List[Problem]
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class SubmissionReaction(BaseModel):
|
|
111
|
+
url: str
|
|
81
112
|
|
|
82
113
|
|
|
83
114
|
class Submission(BaseModel):
|
|
84
|
-
id: str =
|
|
115
|
+
id: Optional[str] = None
|
|
116
|
+
submission_id: Optional[str] = None
|
|
85
117
|
|
|
86
118
|
team_id: str = ""
|
|
87
|
-
problem_id: int = 0
|
|
119
|
+
problem_id: Union[int, str] = 0
|
|
88
120
|
timestamp: int = 0 # unit: seconds
|
|
89
121
|
status: SubmissionStatus = constants.SUBMISSION_STATUS_UNKNOWN
|
|
90
122
|
|
|
@@ -93,23 +125,23 @@ class Submission(BaseModel):
|
|
|
93
125
|
|
|
94
126
|
is_ignore: Optional[bool] = None
|
|
95
127
|
|
|
96
|
-
reaction: Optional[
|
|
128
|
+
reaction: Optional[SubmissionReaction] = None
|
|
97
129
|
|
|
98
130
|
|
|
99
131
|
class Submissions(RootModel[List[Submission]]):
|
|
100
|
-
|
|
132
|
+
pass
|
|
101
133
|
|
|
102
134
|
|
|
103
135
|
class Team(BaseModel):
|
|
104
136
|
id: str = ""
|
|
105
|
-
name:
|
|
137
|
+
name: Text = ""
|
|
106
138
|
|
|
107
139
|
organization: str = ""
|
|
108
140
|
group: List[str] = Field(default_factory=list)
|
|
109
|
-
tag: List[str] =
|
|
141
|
+
tag: Optional[List[str]] = None
|
|
110
142
|
|
|
111
|
-
|
|
112
|
-
members: Optional[List[
|
|
143
|
+
coaches: Optional[Union[Text, List[Text], Persons]] = None
|
|
144
|
+
members: Optional[Union[Text, List[Text], Persons]] = None
|
|
113
145
|
|
|
114
146
|
badge: Optional[Image] = None
|
|
115
147
|
|
|
@@ -139,7 +171,7 @@ class ContestOptions(BaseModel):
|
|
|
139
171
|
|
|
140
172
|
|
|
141
173
|
class Contest(BaseModel):
|
|
142
|
-
contest_name:
|
|
174
|
+
contest_name: Text = ""
|
|
143
175
|
|
|
144
176
|
start_time: Union[int, DateTimeISO8601String] = 0
|
|
145
177
|
end_time: Union[int, DateTimeISO8601String] = 0
|
|
@@ -147,17 +179,18 @@ class Contest(BaseModel):
|
|
|
147
179
|
|
|
148
180
|
freeze_time: Optional[Union[int, DateTimeISO8601String]] = None
|
|
149
181
|
frozen_time: int = 60 * 60 # unit: seconds
|
|
150
|
-
unfrozen_time: int = 0x3F3F3F3F3F3F3F3F
|
|
151
182
|
|
|
152
|
-
|
|
153
|
-
problem_id: List[str] = Field(default_factory=list)
|
|
183
|
+
problems: Optional[Problems] = None
|
|
154
184
|
|
|
155
|
-
|
|
156
|
-
|
|
185
|
+
problem_id: Optional[List[str]] = None
|
|
186
|
+
balloon_color: Optional[List[BalloonColor]] = None
|
|
187
|
+
|
|
188
|
+
status_time_display: Dict[str, bool] = constants.FULL_STATUS_TIME_DISPLAY
|
|
157
189
|
|
|
158
190
|
badge: Optional[str] = None
|
|
191
|
+
organization: str = "School"
|
|
192
|
+
|
|
159
193
|
medal: Optional[Union[Dict[str, Dict[str, int]], MedalPreset]] = None
|
|
160
|
-
balloon_color: Optional[List[Color]] = None
|
|
161
194
|
|
|
162
195
|
group: Optional[Dict[str, str]] = None
|
|
163
196
|
tag: Optional[Dict[str, str]] = None
|
|
@@ -171,34 +204,35 @@ class Contest(BaseModel):
|
|
|
171
204
|
|
|
172
205
|
options: ContestOptions = Field(default_factory=ContestOptions)
|
|
173
206
|
|
|
174
|
-
|
|
207
|
+
unfrozen_time: int = 0x3F3F3F3F3F3F3F3F
|
|
208
|
+
|
|
209
|
+
def append_balloon_color(self, color: BalloonColor):
|
|
175
210
|
if self.balloon_color is None:
|
|
176
211
|
self.balloon_color = []
|
|
177
212
|
self.balloon_color.append(color)
|
|
178
213
|
return self
|
|
179
214
|
|
|
180
|
-
def fill_problem_id(self):
|
|
181
|
-
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)]
|
|
182
217
|
return self
|
|
183
218
|
|
|
184
219
|
def fill_balloon_color(self):
|
|
185
220
|
default_balloon_color_list = [
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
221
|
+
BalloonColor(background_color="rgba(189, 14, 14, 0.7)", color="#fff"),
|
|
222
|
+
BalloonColor(background_color="rgba(149, 31, 217, 0.7)", color="#fff"),
|
|
223
|
+
BalloonColor(background_color="rgba(16, 32, 96, 0.7)", color="#fff"),
|
|
224
|
+
BalloonColor(background_color="rgba(38, 185, 60, 0.7)", color="#000"),
|
|
225
|
+
BalloonColor(background_color="rgba(239, 217, 9, 0.7)", color="#000"),
|
|
226
|
+
BalloonColor(background_color="rgba(243, 88, 20, 0.7)", color="#fff"),
|
|
227
|
+
BalloonColor(background_color="rgba(12, 76, 138, 0.7)", color="#fff"),
|
|
228
|
+
BalloonColor(background_color="rgba(156, 155, 155, 0.7)", color="#000"),
|
|
229
|
+
BalloonColor(background_color="rgba(4, 154, 115, 0.7)", color="#000"),
|
|
230
|
+
BalloonColor(background_color="rgba(159, 19, 236, 0.7)", color="#fff"),
|
|
231
|
+
BalloonColor(background_color="rgba(42, 197, 202, 0.7)", color="#000"),
|
|
232
|
+
BalloonColor(background_color="rgba(142, 56, 54, 0.7)", color="#fff"),
|
|
233
|
+
BalloonColor(background_color="rgba(144, 238, 144, 0.7)", color="#000"),
|
|
234
|
+
BalloonColor(background_color="rgba(77, 57, 0, 0.7)", color="#fff"),
|
|
200
235
|
]
|
|
201
|
-
|
|
202
|
-
self.balloon_color = default_balloon_color_list[: self.problem_quantity]
|
|
236
|
+
self.balloon_color = default_balloon_color_list[: len(self.problem_id)]
|
|
203
237
|
|
|
204
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
|