Skip to content

Commit dd3244f

Browse files
Rename contest 'text' property to 'problemset' (document) to be more clear.
Also do the same for problem text -> statement. Note we do not change the database property, since for problems it's also called text.
1 parent 9c84e0b commit dd3244f

33 files changed

+360
-316
lines changed

misc-tools/import-contest.in

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ def import_contest_banner(cid: str):
114114
else:
115115
print('Skipping contest banner import.')
116116

117-
def import_contest_text(cid: str):
118-
"""Import the contest text"""
117+
def import_contest_problemset_document(cid: str):
118+
"""Import the contest problemset document"""
119119

120120
files = ['contest.pdf', 'contest-web.pdf', 'contest.html', 'contest.txt']
121121

@@ -127,7 +127,7 @@ def import_contest_text(cid: str):
127127

128128
if text_file:
129129
if dj_utils.confirm(f'Import {text_file} for contest?', False):
130-
dj_utils.upload_file(f'contests/{cid}/text', 'text', text_file)
130+
dj_utils.upload_file(f'contests/{cid}/problemset', 'text', text_file)
131131
print('Contest text imported.')
132132
else:
133133
print('Skipping contest text import.')
@@ -172,7 +172,7 @@ else:
172172
if cid is not None:
173173
print(f' -> cid={cid}')
174174
import_contest_banner(cid)
175-
import_contest_text(cid)
175+
import_contest_problemset_document(cid)
176176

177177
# Problem import is also special: we need to upload each individual problem and detect what they are
178178
if os.path.exists('problems.yaml') or os.path.exists('problems.json') or os.path.exists('problemset.yaml'):

webapp/migrations/Version20240322100827.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,23 @@ final class Version20240322100827 extends AbstractMigration
1414
{
1515
public function getDescription(): string
1616
{
17-
return 'Add contest text table and type to contests.';
17+
return 'Add contest problemset table and type to contests.';
1818
}
1919

2020
public function up(Schema $schema): void
2121
{
2222
// this up() migration is auto-generated, please modify it to your needs
23-
$this->addSql('CREATE TABLE contest_text_content (cid INT UNSIGNED NOT NULL COMMENT \'Contest ID\', content LONGBLOB NOT NULL COMMENT \'Text content(DC2Type:blobtext)\', PRIMARY KEY(cid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'Stores contents of contest texts\' ');
24-
$this->addSql('ALTER TABLE contest_text_content ADD CONSTRAINT FK_6680FE6A4B30D9C4 FOREIGN KEY (cid) REFERENCES contest (cid) ON DELETE CASCADE');
25-
$this->addSql('ALTER TABLE contest ADD contest_text_type VARCHAR(4) DEFAULT NULL COMMENT \'File type of contest text\'');
23+
$this->addSql('CREATE TABLE contest_problemset_content (cid INT UNSIGNED NOT NULL COMMENT \'Contest ID\', content LONGBLOB NOT NULL COMMENT \'Problemset document content(DC2Type:blobtext)\', PRIMARY KEY(cid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'Stores contents of contest problemset documents\' ');
24+
$this->addSql('ALTER TABLE contest_problemset_content ADD CONSTRAINT FK_6680FE6A4B30D9C4 FOREIGN KEY (cid) REFERENCES contest (cid) ON DELETE CASCADE');
25+
$this->addSql('ALTER TABLE contest ADD contest_problemset_type VARCHAR(4) DEFAULT NULL COMMENT \'File type of contest problemset document\'');
2626
}
2727

2828
public function down(Schema $schema): void
2929
{
3030
// this down() migration is auto-generated, please modify it to your needs
31-
$this->addSql('ALTER TABLE contest_text_content DROP FOREIGN KEY FK_6680FE6A4B30D9C4');
32-
$this->addSql('DROP TABLE contest_text_content');
33-
$this->addSql('ALTER TABLE contest DROP contest_text_type');
31+
$this->addSql('ALTER TABLE contest_problemset_content DROP FOREIGN KEY FK_6680FE6A4B30D9C4');
32+
$this->addSql('DROP TABLE contest_problemset_content');
33+
$this->addSql('ALTER TABLE contest DROP contest_problemset_type');
3434
}
3535

3636
public function isTransactional(): bool
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DoctrineMigrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
/**
11+
* Auto-generated Migration: Please modify to your needs!
12+
*/
13+
final class Version20240323101404 extends AbstractMigration
14+
{
15+
public function getDescription(): string
16+
{
17+
return 'Rename problem text to statement';
18+
}
19+
20+
public function up(Schema $schema): void
21+
{
22+
// this up() migration is auto-generated, please modify it to your needs
23+
$this->addSql('CREATE TABLE problem_statement_content (probid INT UNSIGNED NOT NULL COMMENT \'Problem ID\', content LONGBLOB NOT NULL COMMENT \'Statement content(DC2Type:blobtext)\', PRIMARY KEY(probid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'Stores contents of problem statement\' ');
24+
$this->addSql('ALTER TABLE problem_statement_content ADD CONSTRAINT FK_8A666422EF049279 FOREIGN KEY (probid) REFERENCES problem (probid) ON DELETE CASCADE');
25+
$this->addSql('INSERT INTO problem_statement_content (probid, content) SELECT probid, content FROM problem_text_content');
26+
$this->addSql('DROP TABLE problem_text_content');
27+
$this->addSql('ALTER TABLE problem CHANGE problemtext_type problemstatement_type VARCHAR(4) DEFAULT NULL COMMENT \'File type of problem statement\'');
28+
}
29+
30+
public function down(Schema $schema): void
31+
{
32+
// this down() migration is auto-generated, please modify it to your needs
33+
$this->addSql('CREATE TABLE problem_text_content (probid INT UNSIGNED NOT NULL COMMENT \'Problem ID\', content LONGBLOB NOT NULL COMMENT \'Text content(DC2Type:blobtext)\', PRIMARY KEY(probid)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'Stores contents of problem texts\' ');
34+
$this->addSql('ALTER TABLE problem_text_content ADD CONSTRAINT FK_21B6AD6BEF049279 FOREIGN KEY (probid) REFERENCES problem (probid) ON DELETE CASCADE');
35+
$this->addSql('INSERT INTO problem_text_content (probid, content) SELECT probid, content FROM problem_statement_content');
36+
$this->addSql('DROP TABLE problem_statement_content');
37+
$this->addSql('ALTER TABLE problem CHANGE problemstatement_type problemtext_type VARCHAR(4) DEFAULT NULL COMMENT \'File type of problem text\'');
38+
}
39+
40+
public function isTransactional(): bool
41+
{
42+
return false;
43+
}
44+
}

webapp/src/Controller/API/ContestController.php

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -264,17 +264,17 @@ public function setBannerAction(Request $request, string $cid, ValidatorInterfac
264264
}
265265

266266
/**
267-
* Delete the text for the given contest.
267+
* Delete the problemset document for the given contest.
268268
*/
269269
#[IsGranted('ROLE_ADMIN')]
270-
#[Rest\Delete('/{cid}/text', name: 'delete_contest_text')]
271-
#[OA\Response(response: 204, description: 'Deleting text succeeded')]
270+
#[Rest\Delete('/{cid}/problemset', name: 'delete_contest_problemset')]
271+
#[OA\Response(response: 204, description: 'Deleting problemset document succeeded')]
272272
#[OA\Parameter(ref: '#/components/parameters/cid')]
273-
public function deleteTextAction(Request $request, string $cid): Response
273+
public function deleteProblemsetAction(Request $request, string $cid): Response
274274
{
275275
$contest = $this->getContestAndCheckIfLocked($request, $cid);
276-
$contest->setClearContestText(true);
277-
$contest->processContestText();
276+
$contest->setClearContestProblemset(true);
277+
$contest->processContestProblemset();
278278
$this->em->flush();
279279

280280
$this->eventLogService->log('contests', $contest->getCid(), EventLogService::ACTION_UPDATE,
@@ -284,50 +284,50 @@ public function deleteTextAction(Request $request, string $cid): Response
284284
}
285285

286286
/**
287-
* Set the text for the given contest.
287+
* Set the problemset document for the given contest.
288288
*/
289289
#[IsGranted('ROLE_ADMIN')]
290-
#[Rest\Post("/{cid}/text", name: 'post_contest_text')]
291-
#[Rest\Put("/{cid}/text", name: 'put_contest_text')]
290+
#[Rest\Post("/{cid}/problemset", name: 'post_contest_problemset')]
291+
#[Rest\Put("/{cid}/problemset", name: 'put_contest_problemset')]
292292
#[OA\RequestBody(
293293
required: true,
294294
content: new OA\MediaType(
295295
mediaType: 'multipart/form-data',
296296
schema: new OA\Schema(
297-
required: ['text'],
297+
required: ['problemset'],
298298
properties: [
299299
new OA\Property(
300300
property: 'text',
301-
description: 'The text to use, as either text/html, text/plain or application/pdf.',
301+
description: 'The problemset document to use, as either text/html, text/plain or application/pdf.',
302302
type: 'string',
303303
format: 'binary'
304304
),
305305
]
306306
)
307307
)
308308
)]
309-
#[OA\Response(response: 204, description: 'Setting text succeeded')]
309+
#[OA\Response(response: 204, description: 'Setting problemset document succeeded')]
310310
#[OA\Parameter(ref: '#/components/parameters/cid')]
311-
public function setTextAction(Request $request, string $cid, ValidatorInterface $validator): Response
311+
public function setProblemsetAction(Request $request, string $cid, ValidatorInterface $validator): Response
312312
{
313313
$contest = $this->getContestAndCheckIfLocked($request, $cid);
314314

315-
/** @var UploadedFile|null $text */
316-
$text = $request->files->get('text');
317-
if (!$text) {
318-
return new JsonResponse(['title' => 'Validation failed', 'errors' => ['Please supply a text']], Response::HTTP_BAD_REQUEST);
315+
/** @var UploadedFile|null $problemset */
316+
$problemset = $request->files->get('problemset');
317+
if (!$problemset) {
318+
return new JsonResponse(['title' => 'Validation failed', 'errors' => ['Please supply a problemset document']], Response::HTTP_BAD_REQUEST);
319319
}
320-
if (!in_array($text->getMimeType(), ['text/html', 'text/plain', 'application/pdf'])) {
321-
return new JsonResponse(['title' => 'Validation failed', 'errors' => ['Invalid text type']], Response::HTTP_BAD_REQUEST);
320+
if (!in_array($problemset->getMimeType(), ['text/html', 'text/plain', 'application/pdf'])) {
321+
return new JsonResponse(['title' => 'Validation failed', 'errors' => ['Invalid problemset document type']], Response::HTTP_BAD_REQUEST);
322322
}
323323

324-
$contest->setContestTextFile($text);
324+
$contest->setContestProblemsetFile($problemset);
325325

326326
if ($errorResponse = $this->responseForErrors($validator->validate($contest), true)) {
327327
return $errorResponse;
328328
}
329329

330-
$contest->processContestText();
330+
$contest->processContestProblemset();
331331
$this->em->flush();
332332

333333
$this->eventLogService->log('contests', $contest->getCid(), EventLogService::ACTION_UPDATE,
@@ -337,20 +337,20 @@ public function setTextAction(Request $request, string $cid, ValidatorInterface
337337
}
338338

339339
/**
340-
* Get the text for the given contest.
340+
* Get the problemset document for the given contest.
341341
*/
342-
#[Rest\Get('/{cid}/text', name: 'contest_text')]
342+
#[Rest\Get('/{cid}/problemset', name: 'contest_problemset')]
343343
#[OA\Response(
344344
response: 200,
345-
description: 'Returns the given contest text in PDF, HTML or TXT format',
345+
description: 'Returns the given contest problemset document in PDF, HTML or TXT format',
346346
content: [
347347
new OA\MediaType(mediaType: 'application/pdf'),
348348
new OA\MediaType(mediaType: 'text/plain'),
349349
new OA\MediaType(mediaType: 'text/html'),
350350
]
351351
)]
352352
#[OA\Parameter(ref: '#/components/parameters/cid')]
353-
public function textAction(Request $request, string $cid): Response
353+
public function problemsetAction(Request $request, string $cid): Response
354354
{
355355
/** @var Contest|null $contest */
356356
$contest = $this->getQueryBuilder($request)
@@ -371,11 +371,11 @@ public function textAction(Request $request, string $cid): Response
371371
throw new NotFoundHttpException(sprintf('Object with ID \'%s\' not found', $cid));
372372
}
373373

374-
if (!$contest->getContestTextType()) {
375-
throw new NotFoundHttpException(sprintf('Contest with ID \'%s\' has no text', $cid));
374+
if (!$contest->getContestProblemsetType()) {
375+
throw new NotFoundHttpException(sprintf('Contest with ID \'%s\' has no problemset text', $cid));
376376
}
377377

378-
return $contest->getContestTextStreamedResponse();
378+
return $contest->getContestProblemsetStreamedResponse();
379379
}
380380

381381
/**

webapp/src/Controller/API/ProblemController.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ public function singleAction(Request $request, string $id): Response
407407
public function statementAction(Request $request, string $id): Response
408408
{
409409
$queryBuilder = $this->getQueryBuilder($request)
410-
->leftJoin('p.problemTextContent', 'content')
410+
->leftJoin('p.problemStatementContent', 'content')
411411
->addSelect('content')
412412
->setParameter('id', $id)
413413
->andWhere(sprintf('%s = :id', $this->getIdField()));
@@ -425,11 +425,11 @@ public function statementAction(Request $request, string $id): Response
425425
/** @var ContestProblem $contestProblem */
426426
$contestProblem = $contestProblemData[0];
427427

428-
if ($contestProblem->getProblem()->getProblemtextType() !== 'pdf') {
428+
if ($contestProblem->getProblem()->getProblemstatementType() !== 'pdf') {
429429
throw new NotFoundHttpException(sprintf('Problem with ID \'%s\' has no PDF statement', $id));
430430
}
431431

432-
return $contestProblem->getProblem()->getProblemTextStreamedResponse();
432+
return $contestProblem->getProblem()->getProblemStatementStreamedResponse();
433433
}
434434

435435
protected function getQueryBuilder(Request $request): QueryBuilder

webapp/src/Controller/Jury/ContestController.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ public function indexAction(Request $request): Response
147147
}
148148

149149
// Create action links
150-
if ($contest->getContestTextType()) {
150+
if ($contest->getContestProblemsetType()) {
151151
$contestactions[] = [
152-
'icon' => 'file-' . $contest->getContestTextType(),
153-
'title' => 'view contest description',
154-
'link' => $this->generateUrl('jury_contest_text', [
152+
'icon' => 'file-' . $contest->getContestProblemsetType(),
153+
'title' => 'view contest problemset document',
154+
'link' => $this->generateUrl('jury_contest_problemset', [
155155
'cid' => $contest->getCid(),
156156
])
157157
];
@@ -1031,14 +1031,14 @@ public function publicScoreboardDataZipAction(
10311031
return $this->dj->getScoreboardZip($request, $requestStack, $contest, $scoreboardService, $type === 'unfrozen');
10321032
}
10331033

1034-
#[Route(path: '/{cid<\d+>}/text', name: 'jury_contest_text')]
1035-
public function viewTextAction(int $cid): StreamedResponse
1034+
#[Route(path: '/{cid<\d+>}/problemset', name: 'jury_contest_problemset')]
1035+
public function viewProblemsetAction(int $cid): StreamedResponse
10361036
{
10371037
$contest = $this->em->getRepository(Contest::class)->find($cid);
10381038
if (!$contest) {
10391039
throw new NotFoundHttpException(sprintf('Contest with ID %s not found', $cid));
10401040
}
10411041

1042-
return $contest->getContestTextStreamedResponse();
1042+
return $contest->getContestProblemsetStreamedResponse();
10431043
}
10441044
}

webapp/src/Controller/Jury/ProblemController.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,11 @@ public function indexAction(): Response
121121
}
122122

123123
// Create action links
124-
if ($p->getProblemtextType()) {
124+
if ($p->getProblemstatementType()) {
125125
$problemactions[] = [
126-
'icon' => 'file-' . $p->getProblemtextType(),
127-
'title' => 'view all problem statements of the contest',
128-
'link' => $this->generateUrl('jury_problem_text', [
126+
'icon' => 'file-' . $p->getProblemstatementType(),
127+
'title' => 'view problem statement',
128+
'link' => $this->generateUrl('jury_problem_statement', [
129129
'probId' => $p->getProbid(),
130130
])
131131
];
@@ -265,7 +265,7 @@ public function exportAction(int $problemId): StreamedResponse
265265
$problem = $this->em->createQueryBuilder()
266266
->from(Problem::class, 'p')
267267
->leftJoin('p.contest_problems', 'cp', Join::WITH, 'cp.contest = :contest')
268-
->leftJoin('p.problemTextContent', 'content')
268+
->leftJoin('p.problemStatementContent', 'content')
269269
->select('p', 'cp', 'content')
270270
->andWhere('p.probid = :problemId')
271271
->setParameter('problemId', $problemId)
@@ -323,9 +323,9 @@ public function exportAction(int $problemId): StreamedResponse
323323
$zip->addFromString('domjudge-problem.ini', $iniString);
324324
$zip->addFromString('problem.yaml', $yamlString);
325325

326-
if (!empty($problem->getProblemtext())) {
327-
$zip->addFromString('problem.' . $problem->getProblemtextType(),
328-
$problem->getProblemtext());
326+
if (!empty($problem->getProblemstatement())) {
327+
$zip->addFromString('problem.' . $problem->getProblemstatementType(),
328+
$problem->getProblemstatement());
329329
}
330330

331331
$compareExecutable = null;
@@ -515,15 +515,15 @@ public function viewAction(Request $request, SubmissionService $submissionServic
515515
return $this->render('jury/problem.html.twig', $data);
516516
}
517517

518-
#[Route(path: '/{probId<\d+>}/text', name: 'jury_problem_text')]
518+
#[Route(path: '/{probId<\d+>}/statement', name: 'jury_problem_statement')]
519519
public function viewTextAction(int $probId): StreamedResponse
520520
{
521521
$problem = $this->em->getRepository(Problem::class)->find($probId);
522522
if (!$problem) {
523523
throw new NotFoundHttpException(sprintf('Problem with ID %s not found', $probId));
524524
}
525525

526-
return $problem->getProblemTextStreamedResponse();
526+
return $problem->getProblemStatementStreamedResponse();
527527
}
528528

529529
#[Route(path: '/{probId<\d+>}/testcases', name: 'jury_problem_testcases')]

webapp/src/Controller/PublicController.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,8 @@ public function problemsAction(): Response
168168
$this->dj->getTwigDataForProblemsAction($this->stats));
169169
}
170170

171-
#[Route(path: '/problems/{probId<\d+>}/text', name: 'public_problem_text')]
172-
public function problemTextAction(int $probId): StreamedResponse
171+
#[Route(path: '/problems/{probId<\d+>}/statement', name: 'public_problem_statement')]
172+
public function problemStatementAction(int $probId): StreamedResponse
173173
{
174174
return $this->getBinaryFile($probId, function (
175175
int $probId,
@@ -179,22 +179,22 @@ public function problemTextAction(int $probId): StreamedResponse
179179
$problem = $contestProblem->getProblem();
180180

181181
try {
182-
return $problem->getProblemTextStreamedResponse();
182+
return $problem->getProblemStatementStreamedResponse();
183183
} catch (BadRequestHttpException $e) {
184184
$this->addFlash('danger', $e->getMessage());
185185
return $this->redirectToRoute('public_problems');
186186
}
187187
});
188188
}
189189

190-
#[Route(path: '/contest-text', name: 'public_contest_text')]
191-
public function contestTextAction(): StreamedResponse
190+
#[Route(path: '/problemset', name: 'public_contest_problemset')]
191+
public function contestProblemsetAction(): StreamedResponse
192192
{
193193
$contest = $this->dj->getCurrentContest(onlyPublic: true);
194194
if (!$contest->getFreezeData()->started()) {
195-
throw new NotFoundHttpException('Contest text not found or not available');
195+
throw new NotFoundHttpException('Contest problemset not found or not available');
196196
}
197-
return $contest->getContestTextStreamedResponse();
197+
return $contest->getContestProblemsetStreamedResponse();
198198
}
199199

200200
/**

0 commit comments

Comments
 (0)