Skip to content

Commit

Permalink
Added fetch-from-contest feature
Browse files Browse the repository at this point in the history
  • Loading branch information
cip999 committed Jan 15, 2023
1 parent e3f4552 commit 709a28c
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
19 changes: 13 additions & 6 deletions p2d/p2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def prepare_argument_parser():
parser.add_argument('--polygon', '--import', '--get', '--download', action='store_true', help='Whether the problem packages should be downloaded from Polygon. Otherwise only the packages already present in the system will be considered.')
parser.add_argument('--convert', action='store_true', help='Whether the polygon packages should be converted to DOMjudge packages. Otherwise only the DOMjudge packages already present in the system will be considered.')
parser.add_argument('--domjudge', '--export', '--send', '--upload', action='store_true', help='Whether the DOMjudge packages shall be uploaded to the DOMjudge instance specified in config.yaml.')
parser.add_argument('--from-contest', type=int, help='Update config.yaml with the problems of the specified Polygon contest.')
parser.add_argument('--pdf-contest', action='store_true', help='Whether the pdf of the whole problemset and the pdf with all the solutions should be generated. If set, the files are created in \'contest_dir/tex/problemset.pdf\' and \'contest_dir/tex/solutions.pdf\'.')
parser.add_argument('--verbosity', choices=['debug', 'info', 'warning'],
default='info', help='Verbosity of the logs.')
Expand Down Expand Up @@ -50,9 +51,10 @@ def p2d(args):
p2d_utils.validate_config_yaml(config)

if not args.polygon and not args.convert and not args.domjudge \
and args.from_contest is None \
and not args.pdf_contest \
and not args.clear_dir and not args.clear_domjudge_ids:
logging.error('At least one of the flags --polygon, --convert, --domjudge, --contestpdf, --clear-dir, --clear-domjudge-ids is necessary.')
logging.error('At least one of the flags --polygon, --convert, --domjudge, --from-contest, --contestpdf, --clear-dir, --clear-domjudge-ids is necessary.')
exit(1)

if args.clear_dir:
Expand All @@ -75,11 +77,12 @@ def p2d(args):
p2d_utils.save_config_yaml(config, contest_dir)
logging.info('Deleted the DOMjudge IDs from config.yaml.')

if args.polygon and ('polygon' not in config
or 'key' not in config['polygon']
or 'secret' not in config['polygon']):
if (args.polygon or args.from_contest) \
and ('polygon' not in config
or 'key' not in config['polygon']
or 'secret' not in config['polygon']):
logging.error('The entries polygon:key and polygon:secret must be '
'present in config.yaml to download problems from polygon.')
'present in config.yaml to access Polygon problems.')
exit(1)

if args.domjudge and ('domjudge' not in config
Expand All @@ -89,13 +92,17 @@ def p2d(args):
or 'password' not in config['domjudge']):
logging.error('The entries domjudge:contest_id, domjudge:server, '
'domjudge:username, domjudge:password must be present '
'in config.yaml to download problems from polygon.')
'in config.yaml to upload problems on DOMjudge.')
exit(1)

pathlib.Path(os.path.join(contest_dir, 'polygon')).mkdir(exist_ok=True)
pathlib.Path(os.path.join(contest_dir, 'domjudge')).mkdir(exist_ok=True)
pathlib.Path(os.path.join(contest_dir, 'tex')).mkdir(exist_ok=True)

if args.from_contest is not None:
p2d_utils.fill_config_from_contest(config, args.from_contest)
p2d_utils.save_config_yaml(config, contest_dir)

# Process the problems, one at a time.
# For each problem some of the following operations are performed (depending
# on the command line flags used to run the command):
Expand Down
29 changes: 29 additions & 0 deletions p2d/p2d_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,35 @@ def manage_domjudge(config, domjudge_dir, problem):

logging.info('Updated the DOMjudge package on the server \'%s\', with id = \'%s\'.' % (config['domjudge']['server'], problem['domjudge_id']))

# Updates config with the data of the problems in the specified contest.
def fill_config_from_contest(config, contest_id):
contest_problems = polygon_api.get_contest_problems(
config['polygon']['key'], config['polygon']['secret'],
contest_id
)
logging.info('Fetched problems from contest {}.'.format(contest_id))

new_problems = []

for label in contest_problems:
problem = contest_problems[label]
if problem['deleted']:
continue
if problem['id'] not in [p['polygon_id'] for p in config['problems']]:
config['problems'].append({
'name': problem['name'],
'polygon_id': problem['id']
})
new_problems.append(problem['name'])
config_problem = [p for p in config['problems'] if p['polygon_id'] == problem['id']][0]
if 'label' not in config_problem:
config_problem['label'] = label

if len(new_problems) > 0:
logging.info('Found new problems: {}.'.format(', '.join(new_problems)))
else:
logging.info('No new problems were found in the contest.')

# Generates contest_dir/tex/problemset.pdf and contest_dir/tex/solutions.pdf.
def generate_problemset_solutions(config, contest_dir):
pdf_generation_params = {
Expand Down
5 changes: 4 additions & 1 deletion p2d/polygon_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,7 @@ def download_package(key, secret, problem_id, package_id, polygon_zip):
'type': 'linux'})
with open(polygon_zip, "wb") as f:
f.write(io.BytesIO(package.content).getbuffer())


# Fetches the list of problems of the specified contest.
def get_contest_problems(key , secret, contest_id):
return call_polygon_api(key, secret, 'contest.problems', {'contestId': contest_id}).json()['result']

0 comments on commit 709a28c

Please sign in to comment.