|
| 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