Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2485a42

Browse files
committed
Add contest-export script
1 parent 6f41c9a commit 2485a42

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

‎misc-tools/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ include $(TOPDIR)/Makefile.global
99
TARGETS =
1010
OBJECTS =
1111

12-
SUBST_DOMSERVER = fix_permissions configure-domjudge import-contest force-passwords
12+
SUBST_DOMSERVER = fix_permissions configure-domjudge import-contest \
13+
export-contest force-passwords
1314

1415
SUBST_JUDGEHOST = dj_make_chroot dj_run_chroot dj_make_chroot_docker \
1516
dj_judgehost_cleanup

‎misc-tools/export-contest.in

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env python3
2+
3+
'''
4+
export-contest -- Convenience script to export a contest (including metadata,
5+
teams and problems) from the command line. Defaults to using the CLI interface;
6+
Specify a DOMjudge API URL as to use that.
7+
8+
Reads credentials from ~/.netrc when using the API.
9+
10+
Part of the DOMjudge Programming Contest Jury System and licensed
11+
under the GNU GPL. See README and COPYING for details.
12+
'''
13+
14+
import json
15+
import sys
16+
from concurrent.futures import ThreadPoolExecutor
17+
from pathlib import Path
18+
19+
sys.path.append('@domserver_libdir@')
20+
import dj_utils
21+
22+
cid = None
23+
webappdir = '@domserver_webappdir@'
24+
25+
26+
def usage():
27+
print(f'Usage: {sys.argv[0]} [<domjudge-api-url>]')
28+
exit(1)
29+
30+
31+
def api_to_file(endpoint: str, filename: str):
32+
print(f"Fetching '{endpoint}' to '{filename}'")
33+
data = dj_utils.do_api_request(endpoint, decode=False)
34+
with open(filename, 'wb') as f:
35+
f.write(data)
36+
37+
return data
38+
39+
40+
def download_submission(submission):
41+
d = f'submissions/{submission["id"]}'
42+
Path(d).mkdir(parents=True, exist_ok=True)
43+
for f in submission['files']:
44+
if f['mime'] == 'application/zip':
45+
print(f"Downloading '{f['href']}'")
46+
data = dj_utils.do_api_request(f['href'], decode=False)
47+
with open(f'{d}/files.zip', 'wb') as f:
48+
f.write(data)
49+
50+
51+
if len(sys.argv) == 1:
52+
dj_utils.domjudge_webapp_folder_or_api_url = webappdir
53+
elif len(sys.argv) == 2:
54+
dj_utils.domjudge_webapp_folder_or_api_url = sys.argv[1]
55+
else:
56+
usage()
57+
58+
59+
user_data = dj_utils.do_api_request('user')
60+
if 'admin' not in user_data['roles']:
61+
print('Your user does not have the \'admin\' role, can not export.')
62+
exit(1)
63+
64+
65+
contest_id = 'wf48_finals'
66+
67+
for endpoint in [
68+
'accounts',
69+
'awards',
70+
'balloons',
71+
'clarifications',
72+
'groups',
73+
'judgements',
74+
'languages',
75+
'organizations',
76+
'problems',
77+
# 'runs',
78+
'scoreboard',
79+
'submissions',
80+
'teams',
81+
]:
82+
data = api_to_file(f'contests/{contest_id}/{endpoint}', f'{endpoint}.json')
83+
if endpoint == 'submissions':
84+
submissions = json.loads(data)
85+
86+
api_to_file(f'contests/{contest_id}/event-feed?stream=false', 'event-feed.ndjson')
87+
88+
with ThreadPoolExecutor(20) as executor:
89+
for submission in submissions[:10]:
90+
executor.submit(download_submission, submission)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /