Skip to content

Commit b73f61a

Browse files
Always use external ID in API
Fixes #2087
1 parent 6862840 commit b73f61a

File tree

147 files changed

+1359
-1583
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+1359
-1583
lines changed

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ DOMjudge Programming Contest Judging System
22

33
Version 8.4.0DEV
44
---------------------------
5+
- Get rid of 'internal' data source mode, always requiring - but auto
6+
generating - external ID's for all entities to simplify event logic.
57

68
Version 8.3.0 - 31 May 2024
79
---------------------------

doc/manual/config-advanced.rst

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,25 @@ path of your installation) as follows:
1616
- *Affiliation logos*: these will be shown with the teams that are
1717
part of the affiliation, if the ``show_affiliation_logos`` configuration
1818
option is enabled. They can be placed in
19-
`public/images/affiliations/1234.png` where *1234* is the numeric ID
19+
`public/images/affiliations/1234.png` where *1234* is the :ref:`external ID <external-ids>`
2020
of the affiliation as shown in the DOMjudge interface. There is a
2121
separate option ``show_affiliations`` that independently controls where
2222
the affiliation *names* are shown on the scoreboard. These logos should be
2323
square and be at least 64x64 pixels, but not much bigger.
2424
- *Team pictures*: a photo of the team will be shown in the team details
2525
page if `public/images/teams/456.jpg` exists, where *456* is the
26-
team's numeric ID as shown in the DOMjudge interface. DOMjudge will not
26+
team's :ref:`external ID <external-ids>` as shown in the DOMjudge interface. DOMjudge will not
2727
modify the photos in any way or form, so make sure you don't upload photos
2828
that are too big, since that will incur a lot of network traffic.
2929
- *Contest Banners*: a page-wide banner can be shown on the public scoreboard
3030
if that image is placed in `public/images/banners/1.png` where *1* is the
31-
contest's numeric ID as shown in the DOMjudge interface. Alternatively, you
31+
contest's :ref:`external ID <external-ids>` as shown in the DOMjudge interface. Alternatively, you
3232
can place a file at `public/images/banner.png` which will be used as a banner
3333
for all contests. Contest-specific banners always have priority. Contest
3434
banners usually are rectangular, having a width of around 1920 pixels and a
3535
height of around 300 pixels. Other ratio's and sizes are supported, but check
3636
the public scoreboard to see how it looks.
3737

38-
.. note::
39-
40-
The IDs for affiliations, teams and contests need to be the *external ID*
41-
if the ``data_source`` setting of DOMjudge is set to external.
42-
4338
It is also possible to load custom CSS and/or JavaScript files. To do so, place
4439
files ending in `.css` under `public/css/custom/` and/or files ending in `.js`
4540
under `public/js/custom/`. See the Config checker in the admin interface for the

doc/manual/import.rst

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ installation.
1313
To use the CLI, you need to replace ``<WEBAPP_DIR>`` with the path to
1414
the ``webapp`` directory of the DOMserver.
1515

16+
.. _external-ids:
17+
18+
External ID's
19+
-------------
20+
21+
Most entities in DOMjudge have an `eternal ID`. External ID's are used to link
22+
entities in DOMjudge to entities in an external system, e.g. the ICPC CMS. The
23+
API uses the external ID's to expose entities to other systems. When you create
24+
an entity in DOMjudge, specifying the external ID is optional; DOMjudge will
25+
use an automatically generated ID if you don't provide one. However, if this ID
26+
is not unique, you will get a message telling you that you need to provide your
27+
own external ID.
28+
29+
When importing entities in bulk as described below, the external ID will be
30+
populated with the ID as specified in the files you import.
31+
1632
Importing team categories
1733
-------------------------
1834

@@ -33,9 +49,7 @@ fields:
3349
- ``sortorder`` (defaults to ``0``): the sort order of the team category to use
3450
on the scoreboard. Categories with the same sortorder will be grouped together.
3551

36-
If the ``data_source`` setting of DOMjudge is set to external, the ``id`` field will be the
37-
ID used for the group. Otherwise, it will be exposed as ``externalid`` and a group ID will be
38-
generated by DOMjudge.
52+
The ``id`` field will be the ID used for the group.
3953

4054
Example ``groups.json``::
4155

@@ -73,9 +87,7 @@ Each of the following lines must contain the following elements separated by tab
7387
- the category ID. Must be unique
7488
- the name of the team category as shown on the scoreboard
7589

76-
If the ``data_source`` setting of DOMjudge is set to external, the category ID field will be
77-
the ID used for the group. Otherwise, it will be exposed as ``externalid`` and a group ID will
78-
be generated by DOMjudge.
90+
The ``id`` field will be the ID used for the group.
7991

8092
Example ``groups.tsv``::
8193

@@ -114,9 +126,7 @@ fields:
114126
- ``formal_name``: the affiliation name as used on the scoreboard
115127
- ``country``: the country code in form of ISO 3166-1 alpha-3
116128

117-
If the ``data_source`` setting of DOMjudge is set to external, the ``id`` field will be the
118-
ID used for the affiliation. Otherwise, it will be exposed as ``externalid`` and an affiliation
119-
ID will be generated by DOMjudge.
129+
The ``id`` field will be the ID used for the affiliation.
120130

121131
Example ``organizations.json``::
122132

@@ -168,11 +178,8 @@ fields:
168178
- ``organization_id``: the ID of the team affiliation this team belongs to
169179
- ``location.description`` (optional): the location of the team
170180

171-
If the ``data_source`` setting of DOMjudge is set to external, the ``id`` field will be the
172-
ID used for the team and the ``group_ids`` and ``organization_id`` fields are the values as
173-
provided during the import of the other files listed above. Otherwise, the ``id`` will be
174-
exposed as ``externalid``, a team ID will be generated by DOMjudge and you need to use the
175-
ID's as generated by DOMjudge for ``group_ids`` as well as ``organization_id``.
181+
The ``id`` field will be the ID used for the team and the ``group_ids`` and ``organization_id``
182+
fields are the values as provided during the import of the other files listed above.
176183

177184
Example ``teams.json``::
178185

@@ -221,11 +228,8 @@ Each of the following lines must contain the following elements separated by tab
221228
- a country code in form of ISO 3166-1 alpha-3
222229
- an external institution ID, e.g. from the ICPC CMS, may be empty
223230

224-
If the ``data_source`` setting of DOMjudge is set to external, the team ID field will be the
225-
ID used for the team and the category ID field is the value as provided during the import of
226-
the other files listed above. Otherwise, the team ID will be exposed as ``externalid``, a
227-
team ID will be generated by DOMjudge and you need to use the ID as generated by DOMjudge
228-
for the category ID.
231+
The team `id` field will be the ID used for the team and the category ID field is the value
232+
as provided during the import of the other files listed above.
229233

230234
Example ``teams2.tsv``::
231235

@@ -265,10 +269,8 @@ fields:
265269
- ``name``: (optional) the full name of the account
266270
- ``ip`` (optional): IP address to link to this account
267271

268-
If the ``data_source`` setting of DOMjudge is set to external, the ``id`` field will be the ID
269-
used for the user and the ``team_id`` field is the value as provided during the team import.
270-
Otherwise, the ``id`` will be exposed as ``externalid``, a user ID will be generated by DOMjudge
271-
and you need to use the ID as generated by DOMjudge for ``team_id``.
272+
The ``id`` field will be the ID used for the user and the ``team_id`` field is the value as provided during
273+
the team import.
272274

273275
Example ``accounts.yaml``::
274276

doc/manual/shadow.rst

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,9 @@ Configuring DOMjudge
1919

2020
In the DOMjudge admin interface, go to *Configuration settings* page and modify
2121
the settings to mimic the system to shadow from. Also make sure to set
22-
*data_source* to ``configuration and live data external``. This tells DOMjudge
22+
*shadow_mode* to ``true``. This tells DOMjudge
2323
that it will be a shadow for an external system. This will:
2424

25-
* Expose external ID's in the API for both configuration and live data, i.e.
26-
problems, teams, etc. as well as submissions, judgings and runs.
2725
* Add a *Shadow Differences* and *External Contest Sources* item to the jury
2826
menu and homepage for admins.
2927
* Expose additional information in the submission overview and detail pages.

etc/db-config.yaml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -355,17 +355,11 @@
355355
enum_class: App\Utils\EventFeedFormat
356356
public: false
357357
description: Format of the event feed to use. See [current draft](https://ccs-specs.icpc.io/draft/contest_api#event-feed) and [versions available](https://ccs-specs.icpc.io/).
358-
- name: data_source
359-
type: int
360-
default_value: 0
358+
- name: shadow_mode
359+
type: bool
360+
default_value: false
361361
public: false
362-
description: "Source of data: used to indicate whether internal or external IDs are exposed in the API. `configuration data external` is typically used when loading configuration data from the ICPC CMS, and `configuration and live data external` when running DOMjudge as \"shadow system\"."
363-
options:
364-
0: all local
365-
1: configuration data external
366-
2: configuration and live data external
367-
regex: /^\d+$/
368-
error_message: A value between 0 and 2 is required.
362+
description: Is this system running as a shadow system?
369363
docdescription: See :doc:`the chapter on running DOMjudge as a shadow system<shadow>` for more information.
370364
- name: external_contest_sources_allow_untrusted_certificates
371365
type: bool

gitlab/ci/integration.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
- set -eux
66
- if [ -z ${PHPVERSION+x} ]; then export PHPVERSION=8.3; fi
77
- if [ "$TEST" = "E2E" ]; then exit 0; fi
8-
- if [ "$CRAWL_DATASOURCES" != "0" ]; then exit 0; fi
8+
- if [ "$CRAWL_SHADOW_MODE" != "0" ]; then exit 0; fi
99
- timeout --signal=15 40m ./gitlab/integration.sh $PHPVERSION
1010
artifacts:
1111
when: always
@@ -29,7 +29,7 @@ integration_mysql:
2929
MYSQL_REQUIRE_PRIMARY_KEY: 1
3030
PIN_JUDGEDAEMON: 1
3131
TEST: "Unit"
32-
CRAWL_DATASOURCES: "0"
32+
CRAWL_SHADOW_MODE: "0"
3333

3434
integration_mariadb_pr:
3535
except:
@@ -61,4 +61,4 @@ integration_unpinned_judgehost:
6161
MARIADB_PORT_3306_TCP_ADDR: sqlserver
6262
PIN_JUDGEDAEMON: 0
6363
TEST: "Unit"
64-
CRAWL_DATASOURCES: "0"
64+
CRAWL_SHADOW_MODE: "0"

gitlab/ci/template.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
matrix:
5454
- PHPVERSION: ["8.1","8.2","8.3"]
5555
TEST: ["E2E","Unit"]
56-
CRAWL_DATASOURCES: ["0","1","2"]
56+
CRAWL_SHADOW_MODE: ["0","1"]
5757

5858
.phpsupported_job_pr:
5959
script:
@@ -62,4 +62,4 @@
6262
matrix:
6363
- PHPVERSION: ["8.3"]
6464
TEST: ["E2E","Unit"]
65-
CRAWL_DATASOURCES: ["0"]
65+
CRAWL_SHADOW_MODE: ["0"]

gitlab/ci/unit.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
- set -eux
1313
- if [ -z ${PHPVERSION+x} ]; then export PHPVERSION=8.1; fi
1414
- if [ -z ${TEST+x} ]; then export TEST="UNIT"; fi
15-
- if [ "$TEST" = "UNIT" ] && [ "$CRAWL_DATASOURCES" != "0" ]; then exit 0; fi
16-
- if [ "$TEST" = "E2E" ] && [ "$CRAWL_DATASOURCES" != "0" ] && [ "$CI_COMMIT_BRANCH" != "main" ]; then exit 0; fi
17-
- export CRAWL_DATASOURCES
15+
- if [ "$TEST" = "UNIT" ] && [ "$CRAWL_SHADOW_MODE" != "0" ]; then exit 0; fi
16+
- if [ "$TEST" = "E2E" ] && [ "$CRAWL_SHADOW_MODE" != "0" ] && [ "$CI_COMMIT_BRANCH" != "main" ]; then exit 0; fi
17+
- export CRAWL_SHADOW_MODE
1818
- ./gitlab/unit-tests.sh $PHPVERSION $TEST
1919
artifacts:
2020
when: always
@@ -48,4 +48,4 @@ run unit tests (MySQL):
4848
parallel:
4949
matrix:
5050
- TEST: ["E2E","Unit"]
51-
CRAWL_DATASOURCES: ["0"]
51+
CRAWL_SHADOW_MODE: ["0"]

gitlab/integration.sh

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ fi
155155
if [ $cgroupv1 -ne 0 ]; then
156156
section_start start_judging "Start judging"
157157
cd /opt/domjudge/judgehost/
158-
158+
159159
sudo -u domjudge bin/judgedaemon $PINNING |& tee /tmp/judgedaemon.log &
160160
sleep 5
161161
section_end start_judging
@@ -178,7 +178,7 @@ for i in hello_kattis different guess; do
178178
cd "$i"
179179
zip -r "../${i}.zip" -- *
180180
)
181-
curl --fail -X POST -n -N -F zip=@${i}.zip http://localhost/domjudge/api/contests/1/problems
181+
curl --fail -X POST -n -N -F zip=@${i}.zip http://localhost/domjudge/api/contests/demo/problems
182182
done
183183
section_end submitting
184184

@@ -195,21 +195,21 @@ curl $CURLOPTS -c $COOKIEJAR -F "_csrf_token=$CSRFTOKEN" -F "_username=admin" -F
195195
# Send a general clarification to later test if we see the event.
196196
curl $CURLOPTS -F "sendto=" -F "problem=1-" -F "bodytext=Testing" -F "submit=Send" \
197197
"http://localhost/domjudge/jury/clarifications/send" -o /dev/null
198-
198+
199199
section_end curlcookie
200200

201201
if [ $cgroupv1 -ne 0 ]; then
202202
section_start judging "Waiting until all submissions are judged"
203203
# wait for and check results
204-
NUMSUBS=$(curl --fail http://admin:$ADMINPASS@localhost/domjudge/api/contests/1/submissions | python3 -mjson.tool | grep -c '"id":')
205-
204+
NUMSUBS=$(curl --fail http://admin:$ADMINPASS@localhost/domjudge/api/contests/demo/submissions | python3 -mjson.tool | grep -c '"id":')
205+
206206
# Don't spam the log.
207207
set +x
208-
208+
209209
while /bin/true; do
210210
sleep 30s
211211
curl $CURLOPTS "http://localhost/domjudge/jury/judging-verifier?verify_multiple=1" -o /dev/null
212-
212+
213213
# Check if we are done, i.e. everything is judged or something got disabled by internal error...
214214
if tail /tmp/judgedaemon.log | grep -q "No submissions in queue"; then
215215
break
@@ -219,12 +219,12 @@ if [ $cgroupv1 -ne 0 ]; then
219219
break
220220
fi
221221
done
222-
222+
223223
NUMNOTVERIFIED=$(curl $CURLOPTS "http://localhost/domjudge/jury/judging-verifier" | grep "submissions checked" | sed -r 's/^.* ([0-9]+) submissions checked.*$/\1/')
224224
NUMVERIFIED=$( curl $CURLOPTS "http://localhost/domjudge/jury/judging-verifier" | grep "submissions not checked" | sed -r 's/^.* ([0-9]+) submissions not checked.*$/\1/')
225225
NUMNOMAGIC=$( curl $CURLOPTS "http://localhost/domjudge/jury/judging-verifier" | grep "without magic string" | sed -r 's/^.* ([0-9]+) without magic string.*$/\1/')
226226
section_end judging
227-
227+
228228
# We expect
229229
# - two submissions with ambiguous outcome,
230230
# - one submissions submitted through the submit client, and thus the magic string ignored,
@@ -238,7 +238,7 @@ if [ $cgroupv1 -ne 0 ]; then
238238
echo "Of these $NUMNOMAGIC do not have the EXPECTED_RESULTS string (should be 1)."
239239
curl $CURLOPTS "http://localhost/domjudge/jury/judging-verifier?verify_multiple=1" | w3m -dump -T text/html
240240
section_end error
241-
241+
242242
section_start logfiles "All the more or less useful logfiles"
243243
for i in /opt/domjudge/judgehost/judgings/*/*/*/*/*/compile.out; do
244244
echo $i;

misc-tools/import-contest.in

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,6 @@ if os.path.exists('problems.yaml') or os.path.exists('problems.json') or os.path
197197
problems_file = 'problemset.yaml'
198198
dj_utils.upload_file(f'contests/{cid}/problems/add-data', 'data', problems_file)
199199

200-
# We might need to translate the problem external ID's into an internal ID (when we are in data source = local mode)
201-
# For this, we get the problems from the API and create a dict with the mapping
202-
problem_mapping = {problem['externalid']: problem['id']
203-
for problem in dj_utils.do_api_request(f'contests/{cid}/problems')}
204-
205200
if os.path.exists('problems.yaml'):
206201
with open('problems.yaml') as problemFile:
207202
problemData = yaml.safe_load(problemFile)
@@ -226,11 +221,10 @@ if os.path.exists('problems.yaml') or os.path.exists('problems.json') or os.path
226221
exit(3)
227222
os.system(f'cd {problem} && zip -r \'../{problem}\' -- .timelimit *')
228223

229-
problem_id = problem_mapping[problem]
230-
if ((not confirmIndividually) or dj_utils.confirm(f'Ready to import problem \'{problem}\' to probid={problem_id}. Continue?', True)):
224+
if ((not confirmIndividually) or dj_utils.confirm(f'Ready to import problem \'{problem}\' to problem={problem}. Continue?', True)):
231225
print(f'Uploading problem \'{problem}\', please be patient, this may take a while.')
232226
response = dj_utils.upload_file(
233-
f'contests/{cid}/problems', 'zip', f'{problem}.zip', {'problem': problem_id})
227+
f'contests/{cid}/problems', 'zip', f'{problem}.zip', {'problem': problem})
234228
print(json.dumps(response, indent=4))
235229
else:
236230
print('Skipping contest import.')

0 commit comments

Comments
 (0)