Tool to convert a set of problems prepared in Polygon into a DOMjudge contest.
The whole process is automated: downloading the Polygon package, converting it into a DOMjudge package (which is a descendant of the Problem Package Format), and uploading the DOMjudge package to a DOMjudge server.
This tool offers the command p2d
.
Its main features are:
- Download, with a caching mechanism, the most recent Polygon package of a problem through Polygon APIs.
- Upload, with a caching mechanism, the converted DOMjudge package of a problem into a DOMjudge server.
- Handling many problems as a contest.
- Convert a Polygon package into a DOMjudge package without human intervention (with the possibility to tweak time and memory limit in the process).
- Generation of the statement (here is an example of statement) in pdf with the option to add some custom features to it (e.g., the contest name, a balloon with the color of the problem, time limit and memory limit, etc..). The samples' explanations are detected from the notes section in Polygon through the use of special markers.
- Generation of a pdf with the complete problem set of a contest featuring a custom front page. Same for the pdf of the solutions of the problems.
- Checkers using testlib.h are supported transparently (by using a modified
testlib.h
which is DOMjudge compatible). - Through the
Judging verifier
feature of DOMjudge, it enforces that the submissions present in Polygon get the correct result also in DOMjudge.
This project was born as a refactoring of polygon2domjudge and evolved into something more. It was used for SWERC 2021-2022.
The tool pipx
is like pip
(so it allows to install python packages in the local system) but uses virtual-environments transparently to avoid polluting the global python environment.
Run
$ pipx install git+https://github.com/dario2994/pol2dom
This provides you with the command p2d
available in any shell terminal.
Clone the repository with git clone https://github.com/dario2994/pol2dom
and run the command with ./p2d.sh
directly from the repository directory.
Running
p2d contest_directory --polygon --convert --domjudge --pdf-contest
downloads the packages of the problems of the contest from Polygon, converts them to DOMjudge packages, and uploads them to the DOMjudge server, and generates the pdf of the whole problem set and of the solutions.
The list of the problems, as well as the credentials to access Polygon and the DOMjudge server are contained in the configuration file contest_directory/config.yaml
. The content and the format of config.yaml
are described in Structure of config.yaml.
Let us describe the four, almost independent, fundamental operations that can be performed by p2d
:
--polygon
: For each problem, download its latest valid package from Polygon. The package must be a full package (and the linux version will be downloaded). A caching mechanism is employed to avoid downloading a package which is already up to date locally. For this to work,config.yaml
must contain the credentials to access Polygon APIs. For each problem, the directorycontest_directory/polygon/problem_name/
is generated. Such directory contains the Polygon package (extracted) as well as its zip (namedproblem_name.zip
).--convert
: For each problem (which was previously, possibly during a different execution, downloaded from Polygon), convert it to a DOMjudge package, adding the information needed by DOMjudge but absent in Polygon (i.e., the label, the color, the statement in pdf, possibly changing time and memory limit) as described inconfig.yaml
. A caching mechanism is employed to avoid converting problems that were converted previously and whose Polygon package did not change in the meanwhile. For each problem, the directorycontest_directory/domjudge/problem_name
is generated. Such directory contains the DOMjudge package (extracted) as well as its zip (namedproblem_name.zip
). For each problem, alsocontest_directory/tex/problem_name-statement.pdf
andcontest_directory/tex/problem_name-solution.pdf
are generated.--domjudge
: For each problem, upload its package to the DOMjudge server. A caching mechanism is employed to avoid uploading a package which is already up to date in the DOMjudge server. For this to work,config.yaml
must contain the credentials to access DOMjudge APIs.--from-contest <contest-id>
: Fetch the problems of an existing Polygon contest. The configuration fileconfig.yaml
will be updated with the problems from the contest that were not present before (some fields, such ascolor
andauthor
, are to be set manually). The problem packages will not be downloaded unless the--polygon
flag is specified.--pdf-contest
: Generate incontest_directory/tex/
the full problem setproblemset.pdf
and the editorial of the contestsolutions.pdf
. The problems that will appear in these files are those that were ever converted to a valid DOMjudge package by the command (even in a previous execution).
Here is a schematic description of the structure of contest_directory
after the execution of the command (the user needs only to create a properly set up config.yaml
):
config.yaml
polygon/
problem_name/
the content of the package.
problem_name.zip = the zipped package itself
domjudge/
problem_name/
the content of the package
problem_name.zip = the zipped package itself
tex/
samples/ (containing all the samples)
images/ (containing all the images, for statements and solutions)
problemset.pdf
solutions.pdf
For each problem:
problem_name-statement.pdf
problem_name-solution.pdf
Let us describe some additional flags:
--problems <problem_name> [<problem_name> [...]]
: Process only the specified problems.--no-cache
: Ignore the cache for a single run.--clear-dir
: Clear the directorycontest_directory
(without removingconfig.yaml
) and permanently delete the cache.--clear-domjudge-ids
: Clear the DOMjudge IDs assigned to the problems when importing them in DOMjudge. This is necessary if the DOMjudge instance changes, or if the DOMjudge instance is reset, or if the DOMjudge contest is changed inconfig.yaml
.--help
: Show a list of the available flags, with their descriptions.
The file config.yaml
must be present in the contest directory to instruct p2d
on the properties of the contest.
It must be a valid yaml
file containing the following top-level keys:
contest_name
(mandatory): The name of the contest. It appears in the statements of the problems (and in the solutions).front_page_problemset
: Absolute path of the single-page pdf to use for the front page of the full problem set. This key is not mandatory, if it is not provided then the pdf with the problem set will not have a front page.front_page_solutions
: Absolute path of the single-page pdf to use for the front page of the editorial containing the solutions to all the problems. This key is not mandatory, if it is not provided then the pdf with the solutions will not have a front page.polygon
: A dictionary containing the credentials to use Polygon's APIs. This is necessary only if you want to usep2d
to download the problem packages from Polygon. It must have the keyskey
andsecret
. The credentials can be generated in the menusettings
in Polygon.domjudge
: A dictionary containing the credentials to use DOMjudge's APIs. This is necessary only if you want to usep2d
to upload the problems in a DOMjudge instance (i.e., if you want to use the flag--domjudge
). This subdictionary must contain the following keys:server
: Address of the server hosting the DOMjudge instance.username
: The username of an admin user of the DOMjudge instance.password
: The password of the abovementioned user.contest_id
: The external ID of the DOMjudge contest.
problems
: This is a list of problems. A problem is a dictionary with the following keys:name
(mandatory): Short-name, in Polygon, of the problem. This is used as identifier of the problem (denoted above asproblem_name
).polygon_id
: The problem id in Polygon. Can be found in the right-side menu after opening the problem in Polygon. It is necessary to download the Polygon package.label
: The label -- usually an uppercase letter -- used to identify the problem in the DOMjudge scoreboard. Problems will be appear in DOMjudge sorted according to this label.color
: Color of the problem in DOMjudge. It can be either the name of an HTML color (see the list https://htmlcolorcodes.com/color-names/) or the hexadecimal representation of a color (e.g., '#FF12AB'). If the hexadecimal representation is used, it must start with # and it must be enclosed in single or double quotes.author
: The author of the problem. Used in the pdf of the solutions.preparation
: The person who prepared the problems. Used in the pdf of the solutions.override_time_limit
: Value (in seconds) of the time limit of the problem in DOMjudge. If this is present the value set in Polygon is ignored.override_memory_limit
: Value (in MiB) of the memory limit of the problem in DOMjudge. If this is present the value set in Polygon is ignored.
Some more keys are added (and managed) by p2d
for caching purposes. Namely each problem will also contain the additional keys: polygon_version
, domjudge_local_version
, domjudge_server_version
.
These additional keys are managed by p2d
and should not be created or modified by the user. In order to clear entirely the keys related to caching, use the flag --clear-dir
(which will also clear the directory of the contest).
Moreover, each problem (after being uploaded for the first time on DOMjudge) is assigned a domjudge_id
(a number) and a domjudge_externalid
(which corresponds to the external ID of the problem in DOMjudge).
In order to clear the DOMjudge IDs, use the flag --clear-domjudge-ids
.
See this example for a valid config.yaml
file.
In Polygon the explanation of samples (when present) is contained in the Notes section without a specific structure. Since we want to parse the explanations "sample-wise", we need to add some structure.
The explanation of the i-th sample shall be preceded by the line %BEGIN i
and followed by the line %END
. For example:
BLAH BLAH BLAH
\textbf{Explanation of the first sample}
%BEGIN 1
There are $3$ people and...
%END
In the second sample
%BEGIN 2
there are $5$ people and...
%END
Notice that only the explanation itself shall be among the two magic lines, and not the title. The first letter of the explanation of each sample will be capitalized.
We provide a description of the process which generates the tex source of the statement, so that if someone wants to customize the final result (by modifying resources/statement_template.tex
or resources/document_template.tex
) it should have no troubles doing it. The same applies for the LaTeX of the solutions (whose template is resources/solution_template.tex
).
The statement is generated starting from resources/statement_template.tex
by performing the following operations:
- Replace the strings
??LABEL??
,??TITLE??
,??TIMELIMIT??
,??MEMORYLIMIT??
with the corresponding metadata. - Replace the string
??LEGEND??
,??INPUT??
,??OUTPUT??
,??INTERACTION??
with the content of the corresponding sections in the Polygon statement (if present); - Generate an initially empty string
samples
. For each problem sample, create two filessample_id.in
andsample_id.out
and append to the stringsamples
the code\sample{sample_id}
. If the sample has an explanation (see Samples explanation detection), append also\sampleexplanation{Content of the sample explanation.}
. - Replace the string
??SAMPLES??
with the stringsamples
generated in the previous step.
It is clear from the operations performed that resources/statement_template.tex
contains the placeholders ??LABEL??
, ??TITLE??
, ??TIMELIMIT??
, ??MEMORYLIMIT??
, ??LEGEND??
, ??INPUT??
, ??OUTPUT??
, ??SAMPLES??
.
Then, the tex source code generated is inserted in resources/document_template.tex
(by replacing the string ??DOCUMENTCONTENT??
). Finally the string ??CONTEST??
is replaced with the corresponding metadata (given by the argument --contest
).
The tex file resources/document_template.tex
implements the commands: \problemlabel
, \problemtitle
, \timelimit
, \memorylimit
, \problemheader
, \inputsection
, \outputsection
, \samplessection
, \sample
, \smallsample
, \bigsample
, \sampleexplanation
.