-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathcontest.py
More file actions
114 lines (91 loc) · 2.97 KB
/
Copy pathcontest.py
File metadata and controls
114 lines (91 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import config
from pathlib import Path
from typing import cast, Any, Optional
from util import *
# Read the contest.yaml, if available
_contest_yaml: Optional[dict[str, Any]] = None
def contest_yaml() -> dict[str, Any]:
global _contest_yaml
if _contest_yaml is not None:
return _contest_yaml
contest_yaml_path = Path("contest.yaml")
if contest_yaml_path.is_file():
_contest_yaml = read_yaml_settings(contest_yaml_path)
return _contest_yaml
_contest_yaml = {}
return _contest_yaml
_problems_yaml = None
def problems_yaml() -> Optional[list[dict[str, Any]]]:
global _problems_yaml
if _problems_yaml is False:
return None
if _problems_yaml:
return _problems_yaml
problemsyaml_path = Path("problems.yaml")
if not problemsyaml_path.is_file():
_problems_yaml = False
return None
_problems_yaml = read_yaml(problemsyaml_path)
return cast(list[dict[str, Any]], _problems_yaml)
def get_api() -> str:
api = config.args.api or cast(str, contest_yaml().get("api"))
if not api:
fatal(
"Could not find key `api` in contest.yaml and it was not specified on the command line."
)
if api.endswith("/"):
api = api[:-1]
if not api.endswith("/api/v4"):
api += "/api/v4"
return api
def get_contest_id():
contest_id = (
config.args.contest_id
if config.args.contest_id
else contest_yaml()["contest_id"]
if "contest_id" in contest_yaml()
else None
)
contests = get_contests()
if contest_id is not None:
if contest_id not in {c["id"] for c in contests}:
for contest in contests:
log(f"{contest['id']}: {contest['name']}")
fatal(f"Contest {contest_id} not found.")
else:
return contest_id
if len(contests) > 1:
for contest in contests:
log(f"{contest['id']}: {contest['name']}")
fatal(
"Server has multiple active contests. Pass --contest-id <cid> or set it in contest.yaml."
)
if len(contests) == 1:
log(f"The only active contest has id {contests[0]['id']}")
return contests[0]["id"]
def get_contests():
url = f"{get_api()}/contests"
verbose(f"query {url}")
contests = call_api_get_json("/contests")
assert isinstance(contests, list)
return contests
def call_api(method, endpoint, **kwargs):
import requests # Slow import, so only import it inside this function.
url = get_api() + endpoint
verbose(f"{method} {url}")
r = requests.request(
method,
url,
auth=requests.auth.HTTPBasicAuth(config.args.username, config.args.password),
**kwargs,
)
if not r.ok:
error(r.text)
return r
def call_api_get_json(url: str):
r = call_api("GET", url)
r.raise_for_status()
try:
return r.json()
except Exception as e:
print(f"\nError in decoding JSON:\n{e}\n{r.text()}")