[extension] Fix submitting

This commit is contained in:
orosmatthew 2023-10-17 12:50:13 -04:00
parent 8bf0ec5d97
commit cb7383a437
3 changed files with 166 additions and 171 deletions

View File

@ -5,6 +5,7 @@ import { extensionSettings } from './extension';
import { runJava } from './run/java';
import { join } from 'path';
import { TeamData } from './SidebarProvider';
import { submitProblem } from './submit';
export type ProblemData = {
id: number;
@ -17,7 +18,8 @@ export type ProblemData = {
export type MessageType =
| { msg: 'onRequestProblemData' }
| { msg: 'onRun'; data: { problemId: number; input: string } }
| { msg: 'onKill' };
| { msg: 'onKill' }
| { msg: 'onSubmit'; data: { problemId: number } };
export type WebviewMessageType =
| { msg: 'onProblemData'; data: ProblemData }
| { msg: 'onRunning' }
@ -91,11 +93,124 @@ export class BWPanel {
this.panel.webview.postMessage(m);
}
private async handleSubmit(problemId: number) {
if (this.problemData === undefined) {
console.error('Problem data undefined');
return;
}
const problem = this.problemData.find((p) => p.id === problemId);
if (problem === undefined) {
console.error('Invalid problem Id');
return;
}
const sessionToken = this.context.globalState.get<string>('token');
if (sessionToken === undefined) {
console.error('No session token');
return;
}
const teamData = this.context.globalState.get<TeamData>('teamData');
if (teamData === undefined) {
console.error('No team data');
return;
}
await vscode.workspace.saveAll();
const ans = await vscode.window.showInformationMessage(
`Are you sure you want to submit ${problem.name}?`,
'Yes',
'No'
);
if (ans !== 'Yes') {
return;
}
submitProblem(sessionToken, teamData.contestId, teamData.teamId, problemId).then((result) => {
if (result.success === true) {
vscode.window.showInformationMessage('Submitted!');
} else {
vscode.window.showErrorMessage(`Error: ${result.message}`);
}
});
}
private async handleRun(problemId: number, input: string) {
const teamData: TeamData | undefined = this.context.globalState.get('teamData');
if (teamData === undefined) {
return;
}
if (this.problemData === undefined) {
return;
}
if (this.runningProgram !== undefined) {
vscode.window.showErrorMessage('Already Running');
return;
}
const problem = this.problemData.find((p) => (p.id = problemId));
if (problem === undefined) {
return;
}
await vscode.workspace.saveAll();
const repoDir = extensionSettings().repoClonePath;
const outputBuffer: string[] = [];
this.webviewPostMessage({ msg: 'onRunning' });
this.webviewPostMessage({ msg: 'onRunningOutput', data: '[Compiling...]' });
const killFunc = await runJava(
join(
repoDir,
'BWContest',
teamData.contestId.toString(),
teamData.teamId.toString(),
problem.pascalName
),
join(
repoDir,
'BWContest',
teamData.contestId.toString(),
teamData.teamId.toString(),
problem.pascalName,
`${problem.pascalName}.java`
),
problem.pascalName,
input,
(data: string) => {
outputBuffer.push(data);
this.webviewPostMessage({ msg: 'onRunningOutput', data: outputBuffer.join('') });
},
() => {
this.runningProgram = undefined;
this.webviewPostMessage({ msg: 'onRunningDone' });
}
);
if (killFunc !== undefined) {
this.runningProgram = {
problemId: problemId,
outputBuffer: outputBuffer,
kill: killFunc
};
} else {
this.webviewPostMessage({ msg: 'onRunningDone' });
}
}
private async handleRequestProblemData() {
const token: string | undefined = this.context.globalState.get('token');
if (token !== undefined) {
const res = await fetch(urlJoin(this.webUrl, `/api/contest/${token}`));
const data = await res.json();
if (data.success === true) {
this.problemData = data.problems;
this.webviewPostMessage({
msg: 'onProblemData',
data: data.problems
});
}
}
}
private async update() {
const webview = this.panel.webview;
this.panel.webview.html = this._getHtmlForWebview(webview);
webview.onDidReceiveMessage(async (m: MessageType) => {
webview.onDidReceiveMessage((m: MessageType) => {
switch (m.msg) {
case 'onKill': {
if (this.runningProgram !== undefined) {
@ -104,124 +219,18 @@ export class BWPanel {
}
break;
}
// this.kill();
// }
// case 'onSubmit': {
// await vscode.workspace.saveAll();
// if (!data.value) {
// return;
// }
// const ans = await vscode.window.showInformationMessage(
// `Are you sure you want to submit ${data.value.problemName}?`,
// 'Yes',
// 'No'
// );
// if (ans !== 'Yes') {
// break;
// }
// try {
// await submitProblem(
// data.value.sessionToken,
// data.value.contestId,
// data.value.teamId,
// data.value.problemId
// );
// } catch (err: any) {
// vscode.window.showErrorMessage(err.message ?? 'Submission unsuccessful');
// break;
// }
// vscode.window.showInformationMessage('Submitted!');
// break;
// }
case 'onSubmit': {
this.handleSubmit(m.data.problemId);
break;
}
case 'onRun': {
const teamData: TeamData | undefined = this.context.globalState.get('teamData');
if (teamData === undefined) {
return;
}
if (this.problemData === undefined) {
return;
}
if (this.runningProgram !== undefined) {
vscode.window.showErrorMessage('Already Running');
return;
}
const problem = this.problemData.find((p) => (p.id = m.data.problemId));
if (problem === undefined) {
return;
}
await vscode.workspace.saveAll();
const repoDir = extensionSettings().repoClonePath;
const outputBuffer: string[] = [];
this.webviewPostMessage({ msg: 'onRunning' });
this.webviewPostMessage({ msg: 'onRunningOutput', data: '[Compiling...]' });
const killFunc = await runJava(
join(
repoDir,
'BWContest',
teamData.contestId.toString(),
teamData.teamId.toString(),
problem.pascalName
),
join(
repoDir,
'BWContest',
teamData.contestId.toString(),
teamData.teamId.toString(),
problem.pascalName,
`${problem.pascalName}.java`
),
problem.pascalName,
m.data.input,
(data: string) => {
outputBuffer.push(data);
this.webviewPostMessage({ msg: 'onRunningOutput', data: outputBuffer.join('') });
},
() => {
this.runningProgram = undefined;
this.webviewPostMessage({ msg: 'onRunningDone' });
}
);
if (killFunc !== undefined) {
this.runningProgram = {
problemId: m.data.problemId,
outputBuffer: outputBuffer,
kill: killFunc
};
} else {
this.webviewPostMessage({ msg: 'onRunningDone' });
}
this.handleRun(m.data.problemId, m.data.input);
break;
}
case 'onRequestProblemData': {
const token: string | undefined = this.context.globalState.get('token');
if (token !== undefined) {
const res = await fetch(urlJoin(this.webUrl, `/api/contest/${token}`));
const data = await res.json();
if (data.success === true) {
this.problemData = data.problems;
this.webviewPostMessage({
msg: 'onProblemData',
data: data.problems
});
}
}
this.handleRequestProblemData();
break;
}
// case 'onInfo': {
// if (!data.value) {
// return;
// }
// vscode.window.showInformationMessage(data.value);
// break;
// }
// case 'onError': {
// if (!data.value) {
// return;
// }
// vscode.window.showErrorMessage(data.value);
// break;
// }
}
});
}

View File

@ -1,63 +1,58 @@
import { extensionSettings } from './extension';
import { exec } from 'child_process';
import util = require('node:util');
import axios from 'axios';
const execPromise = util.promisify(exec);
import * as fs from 'fs-extra';
import git from 'isomorphic-git';
import path = require('path');
import http from 'isomorphic-git/http/node';
import urlJoin from 'url-join';
export async function submitProblem(
sessionToken: string,
contestId: number,
teamId: number,
problemId: number
) {
): Promise<{ success: true } | { success: false; message: string }> {
const repoClonePath = extensionSettings().repoClonePath;
console.log(repoClonePath);
const clonedRepoPath = `${repoClonePath}/BWContest/${contestId.toString()}/${teamId.toString()}`;
const repoDir = path.join(repoClonePath, 'BWContest', contestId.toString(), teamId.toString());
await git.add({ fs, dir: repoDir, filepath: '.' });
let output: { stdout: string; stderr: string };
output = await execPromise(`git add .`, {
cwd: clonedRepoPath
const hash = await git.commit({
fs,
dir: repoDir,
author: { name: `Team ${teamId}` },
message: `Submit problem ${problemId}`
});
if (output.stderr) {
console.error(output.stderr);
try {
const result = await git.push({
fs,
http,
dir: repoDir
});
if (result.ok !== true) {
return { success: false, message: 'Push failure' };
}
} catch (error) {
return { success: false, message: 'Unable to push' };
}
output = await execPromise(`git commit -m "Submit problem ${problemId}"`, {
cwd: clonedRepoPath
});
if (output.stderr) {
console.error(output.stderr);
}
output = await execPromise(`git push`, {
cwd: clonedRepoPath
});
if (output.stderr) {
console.error(output.stderr);
}
output = await execPromise(`git rev-parse HEAD`, {
cwd: clonedRepoPath
});
if (output.stderr) {
console.error(output.stderr);
}
const commitHash = output.stdout.toString().replace('\n', '');
const res = await axios.post(`http://localhost:5173/api/team/${sessionToken}/submit`, {
commitHash: commitHash,
problemId: problemId
});
const res = await fetch(
urlJoin(extensionSettings().webUrl, '/api/team', sessionToken, '/submit'),
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
commitHash: hash,
problemId: problemId
})
}
);
if (res.status !== 200) {
throw Error('Failed to post submission');
return { success: false, message: 'Submission POST failure' };
}
if (!res.data.success) {
throw Error(res.data.message ?? 'Unknown error');
const resData = await res.json();
if (resData.success !== true) {
return { success: false, message: resData.message };
}
return { success: true };
}

View File

@ -50,18 +50,9 @@
}
function onSubmit() {
// if (teamId && contestId && sessionToken) {
// postMessage({
// type: 'onSubmit',
// value: {
// sessionToken: sessionToken,
// contestId: contestId,
// teamId: teamId,
// problemId: activeProblem.id,
// problemName: activeProblem.pascalName
// }
// });
// }
if (problemData !== undefined) {
postMessage({ msg: 'onSubmit', data: { problemId: problemData[activeProblemIndex].id } });
}
}
function onKill() {