Skip to content

Commit 872a504

Browse files
committed
Allow printing from the submit client
To allow easy deployments, have printing and submitting in the same python file such that we can share code without need to import library files. For convenience of teams, you probably want to alias `printfile` to the submit client with predefined `--print` argument to prevent any accidental submission.
1 parent 399cf3b commit 872a504

File tree

1 file changed

+58
-2
lines changed

1 file changed

+58
-2
lines changed

submit/submit

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#
99

1010
import argparse
11+
import base64
1112
import datetime
1213
import json
1314
import logging
@@ -299,6 +300,55 @@ Submit multiple files (the problem and language are taken from the first):
299300
return "\n\n".join(part for part in epilog_parts if part)
300301

301302

303+
def do_api_print():
304+
'''Submit to the API for printing with the given data.'''
305+
306+
if len(filenames) != 1:
307+
error('You can only print a single file')
308+
filename = filenames[0]
309+
310+
with open(filename, 'rb') as file:
311+
data = {
312+
'original_name': filename,
313+
'language': my_language['name'],
314+
'file_contents': base64.b64encode(file.read()),
315+
}
316+
if entry_point:
317+
data['entry_point'] = entry_point
318+
319+
url = f"{baseurl}api/{api_version}printing/team"
320+
logging.info(f'connecting to {url}')
321+
322+
response = requests.post(url, data=data, headers=headers)
323+
324+
logging.debug(f"API call 'printing' returned:\n{response.text}")
325+
326+
# The connection worked, but we may have received an HTTP error
327+
if response.status_code >= 300:
328+
print(response.text)
329+
if response.status_code == 401:
330+
raise RuntimeError('Authentication failed, please check your DOMjudge credentials in ~/.netrc.')
331+
else:
332+
raise RuntimeError(f'Printing failed (code {response.status_code})')
333+
334+
# We got a successful HTTP response. It worked.
335+
# But check that we indeed received a success response.
336+
337+
try:
338+
result = json.loads(response.text)
339+
except json.decoder.JSONDecodeError as e:
340+
error(f'Parsing DOMjudge\'s API output failed: {e}')
341+
342+
if not isinstance(result, dict) or 'success' not in result:
343+
error('DOMjudge\'s API returned unexpected JSON data.')
344+
345+
if result['success']:
346+
print("DOMjudge reported a successful print job.")
347+
else:
348+
# Should not happen, as the status code should've been >= 300
349+
print(f"DOMjudge reported a printing error: {result['output']}")
350+
351+
302352
def do_api_submit():
303353
'''Submit to the API with the given data.'''
304354

@@ -374,6 +424,7 @@ parser.add_argument('-c', '--contest', help='''submit for contest with ID or sho
374424
Defaults to the value of the
375425
environment variable 'SUBMITCONTEST'.
376426
Mandatory when more than one contest is active.''')
427+
parser.add_argument('-P', '--print', help='submit the file for printing instead of submission', action='store_true')
377428
parser.add_argument('-p', '--problem', help='submit for problem with ID or label PROBLEM', default='')
378429
parser.add_argument('-l', '--language', help='submit in language with ID LANGUAGE', default='')
379430
parser.add_argument('-e', '--entry_point', help='set an explicit entry_point, e.g. the java main class')
@@ -540,7 +591,7 @@ for problem in problems:
540591
my_problem = problem
541592
break
542593

543-
if not my_problem:
594+
if not my_problem and not args.print:
544595
usage('No known problem specified or detected.')
545596

546597
# Guess entry point if not already specified.
@@ -556,11 +607,16 @@ if not entry_point and my_language['entry_point_required']:
556607
error('Entry point required but not specified nor detected.')
557608

558609
logging.debug(f"contest is `{my_contest['shortname']}'")
559-
logging.debug(f"problem is `{my_problem['label']}'")
610+
if not args.print:
611+
logging.debug(f"problem is `{my_problem['label']}'")
560612
logging.debug(f"language is `{my_language['name']}'")
561613
logging.debug(f"entry_point is `{entry_point or '<None>'}'")
562614
logging.debug(f"url is `{baseurl}'")
563615

616+
if args.print:
617+
do_api_print()
618+
exit(0)
619+
564620
if not args.assume_yes:
565621
print('Submission information:')
566622
if len(filenames) == 1:

0 commit comments

Comments
 (0)