[web] Format and add CPP to db

This commit is contained in:
orosmatthew 2024-01-16 17:20:21 -05:00
parent 6b955857bf
commit d2d686133c
5 changed files with 104 additions and 86 deletions

View File

@ -80,6 +80,7 @@ model Team {
enum Language { enum Language {
Java Java
CSharp CSharp
CPP
} }
model ActiveTeam { model ActiveTeam {

View File

@ -36,7 +36,8 @@ export const actions = {
} }
try { try {
await db.contest.delete({ where: { id: parseInt(params.contestId) } }); await db.contest.delete({ where: { id: parseInt(params.contestId) } });
} catch { } catch (e) {
console.error(e);
return { success: false }; return { success: false };
} }
redirect(302, '/admin/contests'); redirect(302, '/admin/contests');

View File

@ -4,37 +4,37 @@ import type { Actions, PageServerLoad } from './$types';
import { fail, redirect } from '@sveltejs/kit'; import { fail, redirect } from '@sveltejs/kit';
import { genPassword } from '../../teams/util'; import { genPassword } from '../../teams/util';
export const load = (async () => { }) satisfies PageServerLoad; export const load = (async () => {}) satisfies PageServerLoad;
export type ContestImportData = { export type ContestImportData = {
Name: string, Name: string;
Problems: ProblemImportData[], Problems: ProblemImportData[];
Teams: TeamImportData[], Teams: TeamImportData[];
Submissions: SubmissionImportData[] Submissions: SubmissionImportData[];
} };
export type ProblemImportData = { export type ProblemImportData = {
ProblemName: string, ProblemName: string;
ShortName: string, ShortName: string;
SampleInput: string, SampleInput: string;
SampleOutput: string, SampleOutput: string;
RealInput: string, RealInput: string;
RealOutput: string RealOutput: string;
} };
export type TeamImportData = { export type TeamImportData = {
TeamName: string TeamName: string;
} };
export type SubmissionImportData = { export type SubmissionImportData = {
TeamName: string, TeamName: string;
ProblemShortName: string, ProblemShortName: string;
State: string, State: string;
SubmitTime: number, SubmitTime: number;
TeamOutput: string, TeamOutput: string;
Code: string | null, Code: string | null;
Language: "Java" | "C#" | "C++" | null Language: 'Java' | 'C#' | 'C++' | null;
} };
export const actions = { export const actions = {
default: async ({ request }) => { default: async ({ request }) => {
@ -45,14 +45,13 @@ export const actions = {
const formData = await request.formData(); const formData = await request.formData();
const contestJson = formData.get('jsonText')?.toString(); const contestJson = formData.get('jsonText')?.toString();
if (!contestJson) { if (!contestJson) {
return fail(400, { message: "Could not get json text" }); return fail(400, { message: 'Could not get json text' });
} }
parsedContest = JSON.parse(contestJson); parsedContest = JSON.parse(contestJson);
includeSubmissions = formData.get('includeSubmissions')?.toString() == "on"; includeSubmissions = formData.get('includeSubmissions')?.toString() == 'on';
} } catch (err) {
catch (err) { return fail(400, { message: 'Could not parse contest data: ' + err?.toString() });
return fail(400, { message: "Could not parse contest data: " + err?.toString() });
} }
try { try {
@ -62,7 +61,9 @@ export const actions = {
if (includeSubmissions && parsedContest.Submissions.length > 0) { if (includeSubmissions && parsedContest.Submissions.length > 0) {
hasSubmissions = true; hasSubmissions = true;
const maxSubmitTimeMinutes = Math.max(...parsedContest.Submissions.map(s => s.SubmitTime)); const maxSubmitTimeMinutes = Math.max(
...parsedContest.Submissions.map((s) => s.SubmitTime)
);
const now = new Date(); const now = new Date();
contestStart = new Date(now.getTime() - maxSubmitTimeMinutes * 60 * 1000); contestStart = new Date(now.getTime() - maxSubmitTimeMinutes * 60 * 1000);
} }
@ -73,24 +74,24 @@ export const actions = {
name: parsedContest.Name, name: parsedContest.Name,
startTime: contestStart, startTime: contestStart,
teams: { teams: {
connectOrCreate: parsedContest.Teams.map(team => ({ connectOrCreate: parsedContest.Teams.map((team) => ({
where: { name: team.TeamName }, where: { name: team.TeamName },
create: { create: {
name: team.TeamName, name: team.TeamName,
password: genPassword(), password: genPassword(),
language: inferTeamLanguage(parsedContest, team) ?? Language.Java language: inferTeamLanguage(parsedContest, team) ?? Language.Java
} }
})), }))
}, },
problems: { problems: {
connectOrCreate: parsedContest.Problems.map(problem => ({ connectOrCreate: parsedContest.Problems.map((problem) => ({
where: { where: {
friendlyName: problem.ProblemName, friendlyName: problem.ProblemName,
pascalName: problem.ShortName, pascalName: problem.ShortName,
sampleInput: problem.SampleInput, sampleInput: problem.SampleInput,
sampleOutput: problem.SampleOutput, sampleOutput: problem.SampleOutput,
realInput: problem.RealInput, realInput: problem.RealInput,
realOutput: problem.RealOutput, realOutput: problem.RealOutput
}, },
create: { create: {
friendlyName: problem.ProblemName, friendlyName: problem.ProblemName,
@ -100,16 +101,17 @@ export const actions = {
realInput: problem.RealInput, realInput: problem.RealInput,
realOutput: problem.RealOutput realOutput: problem.RealOutput
} }
})), }))
}, },
submissions: { submissions: {
create: hasSubmissions create: hasSubmissions
? parsedContest.Submissions.toSorted((a, b) => a.SubmitTime - b.SubmitTime).map(submission => ({ ? parsedContest.Submissions.toSorted((a, b) => a.SubmitTime - b.SubmitTime).map(
(submission) => ({
createdAt: dateFromContestMinutes(contestStart!, submission.SubmitTime), createdAt: dateFromContestMinutes(contestStart!, submission.SubmitTime),
gradedAt: dateFromContestMinutes(contestStart!, submission.SubmitTime + 1), gradedAt: dateFromContestMinutes(contestStart!, submission.SubmitTime + 1),
state: convertSubmissionState(submission), state: convertSubmissionState(submission),
actualOutput: submission.TeamOutput, actualOutput: submission.TeamOutput,
commitHash: "", commitHash: '',
problem: { problem: {
connect: { connect: {
pascalName: submission.ProblemShortName pascalName: submission.ProblemShortName
@ -120,45 +122,51 @@ export const actions = {
name: submission.TeamName name: submission.TeamName
} }
} }
})) })
)
: [] : []
} }
} }
}); });
} catch (err) { } catch (err) {
return fail(400, { message: "Error updating database: " + err?.toString() }); return fail(400, { message: 'Error updating database: ' + err?.toString() });
} }
return redirect(303, "/admin/contests"); return redirect(303, '/admin/contests');
} }
} satisfies Actions; } satisfies Actions;
function convertSubmissionState(submission: SubmissionImportData): SubmissionState { function convertSubmissionState(submission: SubmissionImportData): SubmissionState {
switch (submission.State) { switch (submission.State) {
case "Correct": case 'Correct':
return SubmissionState.Correct; return SubmissionState.Correct;
case "Incorrect": case 'Incorrect':
return SubmissionState.Incorrect; return SubmissionState.Incorrect;
default: default:
return SubmissionState.InReview; return SubmissionState.InReview;
} }
} }
function inferTeamLanguage(parsedContest: ContestImportData, team: TeamImportData): Language | null { function inferTeamLanguage(
const submissionWithCode = parsedContest.Submissions.find(s => s.TeamName == team.TeamName && s.Code != null); parsedContest: ContestImportData,
team: TeamImportData
): Language | null {
const submissionWithCode = parsedContest.Submissions.find(
(s) => s.TeamName == team.TeamName && s.Code != null
);
if (!submissionWithCode) { if (!submissionWithCode) {
return null; return null;
} }
switch (submissionWithCode.Language) { switch (submissionWithCode.Language) {
case "Java": case 'Java':
return Language.Java; return Language.Java;
case "C#": case 'C#':
return Language.CSharp; return Language.CSharp;
case "C++": case 'C++':
return Language.CPP; return Language.CPP;
default: default:
throw new Error("Unrecognized language: " + submissionWithCode.Language); throw new Error('Unrecognized language: ' + submissionWithCode.Language);
} }
} }

View File

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import { enhance } from '$app/forms';
import { goto } from '$app/navigation'; import { goto } from '$app/navigation';
import FormAlert from '$lib/FormAlert.svelte'; import FormAlert from '$lib/FormAlert.svelte';
import type { Actions } from './$types'; import type { Actions } from './$types';
@ -48,7 +49,7 @@
<FormAlert /> <FormAlert />
<form method="POST"> <form method="POST" use:enhance>
<div class="mb-4"> <div class="mb-4">
<h3>Contest JSON:</h3> <h3>Contest JSON:</h3>
<textarea <textarea
@ -57,7 +58,9 @@
class="form-control" class="form-control"
rows="10" rows="10"
bind:value={jsonText} bind:value={jsonText}
style="{parsesCorrectly == null ? "" : `border: 2px solid ${parsesCorrectly ? 'green' : 'red'}`}" style={parsesCorrectly == null
? ''
: `border: 2px solid ${parsesCorrectly ? 'green' : 'red'}`}
/> />
</div> </div>

View File

@ -73,7 +73,12 @@
<textarea use:stretchTextarea class="code mb-3 form-control" disabled>{data.output}</textarea> <textarea use:stretchTextarea class="code mb-3 form-control" disabled>{data.output}</textarea>
<h3>Diff</h3> <h3>Diff</h3>
<div class="mt-3" id="diff" class:d2h-dark-color-scheme={$theme === 'dark'} class:d2h-light-color-scheme={$theme === 'light'}/> <div
class="mt-3"
id="diff"
class:d2h-dark-color-scheme={$theme === 'dark'}
class:d2h-light-color-scheme={$theme === 'light'}
/>
<form method="POST" action="?/submit" use:enhance> <form method="POST" action="?/submit" use:enhance>
<h5>Message</h5> <h5>Message</h5>