[extension] Fix submitting
This commit is contained in:
parent
8bf0ec5d97
commit
cb7383a437
@ -5,6 +5,7 @@ import { extensionSettings } from './extension';
|
|||||||
import { runJava } from './run/java';
|
import { runJava } from './run/java';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { TeamData } from './SidebarProvider';
|
import { TeamData } from './SidebarProvider';
|
||||||
|
import { submitProblem } from './submit';
|
||||||
|
|
||||||
export type ProblemData = {
|
export type ProblemData = {
|
||||||
id: number;
|
id: number;
|
||||||
@ -17,7 +18,8 @@ export type ProblemData = {
|
|||||||
export type MessageType =
|
export type MessageType =
|
||||||
| { msg: 'onRequestProblemData' }
|
| { msg: 'onRequestProblemData' }
|
||||||
| { msg: 'onRun'; data: { problemId: number; input: string } }
|
| { msg: 'onRun'; data: { problemId: number; input: string } }
|
||||||
| { msg: 'onKill' };
|
| { msg: 'onKill' }
|
||||||
|
| { msg: 'onSubmit'; data: { problemId: number } };
|
||||||
export type WebviewMessageType =
|
export type WebviewMessageType =
|
||||||
| { msg: 'onProblemData'; data: ProblemData }
|
| { msg: 'onProblemData'; data: ProblemData }
|
||||||
| { msg: 'onRunning' }
|
| { msg: 'onRunning' }
|
||||||
@ -91,11 +93,124 @@ export class BWPanel {
|
|||||||
this.panel.webview.postMessage(m);
|
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() {
|
private async update() {
|
||||||
const webview = this.panel.webview;
|
const webview = this.panel.webview;
|
||||||
|
|
||||||
this.panel.webview.html = this._getHtmlForWebview(webview);
|
this.panel.webview.html = this._getHtmlForWebview(webview);
|
||||||
webview.onDidReceiveMessage(async (m: MessageType) => {
|
webview.onDidReceiveMessage((m: MessageType) => {
|
||||||
switch (m.msg) {
|
switch (m.msg) {
|
||||||
case 'onKill': {
|
case 'onKill': {
|
||||||
if (this.runningProgram !== undefined) {
|
if (this.runningProgram !== undefined) {
|
||||||
@ -104,124 +219,18 @@ export class BWPanel {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// this.kill();
|
case 'onSubmit': {
|
||||||
// }
|
this.handleSubmit(m.data.problemId);
|
||||||
// case 'onSubmit': {
|
break;
|
||||||
// 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 'onRun': {
|
case 'onRun': {
|
||||||
const teamData: TeamData | undefined = this.context.globalState.get('teamData');
|
this.handleRun(m.data.problemId, m.data.input);
|
||||||
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' });
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'onRequestProblemData': {
|
case 'onRequestProblemData': {
|
||||||
const token: string | undefined = this.context.globalState.get('token');
|
this.handleRequestProblemData();
|
||||||
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
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
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;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,63 +1,58 @@
|
|||||||
import { extensionSettings } from './extension';
|
import { extensionSettings } from './extension';
|
||||||
import { exec } from 'child_process';
|
import * as fs from 'fs-extra';
|
||||||
import util = require('node:util');
|
import git from 'isomorphic-git';
|
||||||
import axios from 'axios';
|
import path = require('path');
|
||||||
|
import http from 'isomorphic-git/http/node';
|
||||||
const execPromise = util.promisify(exec);
|
import urlJoin from 'url-join';
|
||||||
|
|
||||||
export async function submitProblem(
|
export async function submitProblem(
|
||||||
sessionToken: string,
|
sessionToken: string,
|
||||||
contestId: number,
|
contestId: number,
|
||||||
teamId: number,
|
teamId: number,
|
||||||
problemId: number
|
problemId: number
|
||||||
) {
|
): Promise<{ success: true } | { success: false; message: string }> {
|
||||||
const repoClonePath = extensionSettings().repoClonePath;
|
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 };
|
const hash = await git.commit({
|
||||||
output = await execPromise(`git add .`, {
|
fs,
|
||||||
cwd: clonedRepoPath
|
dir: repoDir,
|
||||||
|
author: { name: `Team ${teamId}` },
|
||||||
|
message: `Submit problem ${problemId}`
|
||||||
});
|
});
|
||||||
|
|
||||||
if (output.stderr) {
|
try {
|
||||||
console.error(output.stderr);
|
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}"`, {
|
const res = await fetch(
|
||||||
cwd: clonedRepoPath
|
urlJoin(extensionSettings().webUrl, '/api/team', sessionToken, '/submit'),
|
||||||
});
|
{
|
||||||
|
method: 'POST',
|
||||||
if (output.stderr) {
|
headers: { 'Content-Type': 'application/json' },
|
||||||
console.error(output.stderr);
|
body: JSON.stringify({
|
||||||
}
|
commitHash: hash,
|
||||||
|
problemId: problemId
|
||||||
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
|
|
||||||
});
|
|
||||||
if (res.status !== 200) {
|
if (res.status !== 200) {
|
||||||
throw Error('Failed to post submission');
|
return { success: false, message: 'Submission POST failure' };
|
||||||
}
|
}
|
||||||
if (!res.data.success) {
|
const resData = await res.json();
|
||||||
throw Error(res.data.message ?? 'Unknown error');
|
if (resData.success !== true) {
|
||||||
|
return { success: false, message: resData.message };
|
||||||
}
|
}
|
||||||
|
return { success: true };
|
||||||
}
|
}
|
||||||
|
@ -50,18 +50,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onSubmit() {
|
function onSubmit() {
|
||||||
// if (teamId && contestId && sessionToken) {
|
if (problemData !== undefined) {
|
||||||
// postMessage({
|
postMessage({ msg: 'onSubmit', data: { problemId: problemData[activeProblemIndex].id } });
|
||||||
// type: 'onSubmit',
|
}
|
||||||
// value: {
|
|
||||||
// sessionToken: sessionToken,
|
|
||||||
// contestId: contestId,
|
|
||||||
// teamId: teamId,
|
|
||||||
// problemId: activeProblem.id,
|
|
||||||
// problemName: activeProblem.pascalName
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onKill() {
|
function onKill() {
|
||||||
|
Loading…
Reference in New Issue
Block a user