From 3f362836e5ccf450a9bfceaf84b16a741e681c24 Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Sun, 5 Nov 2023 21:20:24 +0100 Subject: [PATCH 1/2] Remove all extra '/' from shadow sources --- webapp/src/Entity/ExternalContestSource.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/Entity/ExternalContestSource.php b/webapp/src/Entity/ExternalContestSource.php index 5f04102e67..06f6e1ca69 100644 --- a/webapp/src/Entity/ExternalContestSource.php +++ b/webapp/src/Entity/ExternalContestSource.php @@ -99,7 +99,7 @@ public function getSource(): string public function setSource(string $source): ExternalContestSource { - if (str_ends_with($source, '/')) { + while (str_ends_with($source, '/')) { $source = substr($source, 0, -1); } $this->source = $source; From 1fb4acc5372705dd2ee4dc025c59df9769bc7709 Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Sun, 5 Nov 2023 21:20:57 +0100 Subject: [PATCH 2/2] Allow setting externalContestSource for contests Useful for mostly us but documented in the manual. Doing this in the API doc is non trivial for now. Co-authored-by: Nicky Gerritsen --- doc/manual/shadow.rst | 14 ++++++++++++++ webapp/src/Service/ImportExportService.php | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/doc/manual/shadow.rst b/doc/manual/shadow.rst index 5e504b8785..d5e9f0d850 100644 --- a/doc/manual/shadow.rst +++ b/doc/manual/shadow.rst @@ -54,6 +54,20 @@ In the DOMjudge admin interface, go to the *External Contest Sources* page and create an external contest source. Select the contest to import into and enter the source you want to import from. +Another alternative is to use these DOMjudge only keys in the `contest.yaml`:: + + shadow: + type: contest-api + source: http(s)://url_to_external_system/api/contests/ + username: user_in_external_system + password: password_for_user + +or:: + + shadow: + type: contest-archive + source: /path/on/domjudge/filestem/to/clics/compliant/archive + Running the event feed import command ------------------------------------- diff --git a/webapp/src/Service/ImportExportService.php b/webapp/src/Service/ImportExportService.php index a642bbf883..61d53337d3 100644 --- a/webapp/src/Service/ImportExportService.php +++ b/webapp/src/Service/ImportExportService.php @@ -5,6 +5,7 @@ use App\Entity\Configuration; use App\Entity\Contest; use App\Entity\ContestProblem; +use App\Entity\ExternalContestSource; use App\Entity\Problem; use App\Entity\Role; use App\Entity\Team; @@ -251,6 +252,22 @@ public function importContestData(mixed $data, ?string &$errorMessage = null, st } $this->em->persist($contest); + + $shadow = $data['shadow'] ?? null; + if ($shadow) { + $externalSource = $this->em->getRepository(ExternalContestSource::class)->findOneBy(['contest' => $contest]) ?: new ExternalContestSource(); + $externalSource->setContest($contest); + foreach ($shadow as $field => $value) { + // Overwrite the existing value if the property is defined in the data: $externalSource-setSource($data['shadow']['source']) + $fieldFunc = 'set'.ucwords($field); + $fieldArgs = [$value]; + if (method_exists($externalSource, $fieldFunc)) { + $externalSource->$fieldFunc(...$fieldArgs); + } + } + $this->em->persist($externalSource); + } + $this->em->flush(); $penaltyTime = $data['penalty_time'] ?? $data['penalty-time'] ?? $data['penalty'] ?? null;