diff --git a/extension/bwcontest/src/SidebarProvider.ts b/extension/bwcontest/src/SidebarProvider.ts
index 4631dfb..a6a4dbe 100644
--- a/extension/bwcontest/src/SidebarProvider.ts
+++ b/extension/bwcontest/src/SidebarProvider.ts
@@ -27,7 +27,7 @@ export class SidebarProvider implements vscode.WebviewViewProvider {
switch (data.type) {
case 'onTestAndSubmit': {
if (this._context) {
- BWPanel.createOrShow(this._context?.extensionUri, this._context);
+ BWPanel.createOrShow(this._context);
}
break;
}
diff --git a/extension/bwcontest/src/extension.ts b/extension/bwcontest/src/extension.ts
index fc1fd1a..b8a3fd5 100644
--- a/extension/bwcontest/src/extension.ts
+++ b/extension/bwcontest/src/extension.ts
@@ -98,7 +98,7 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
vscode.commands.registerCommand('bwcontest.helloWorld', () => {
- BWPanel.createOrShow(context.extensionUri, context);
+ BWPanel.createOrShow(context);
})
);
diff --git a/extension/bwcontest/src/problemPanel.ts b/extension/bwcontest/src/problemPanel.ts
index ac4dffe..7e09e6c 100644
--- a/extension/bwcontest/src/problemPanel.ts
+++ b/extension/bwcontest/src/problemPanel.ts
@@ -3,6 +3,7 @@ import { getNonce } from './getNonce';
import { runJava } from './run/java';
import { extensionSettings } from './extension';
import { join } from 'path';
+import { submitProblem } from './submit';
export class BWPanel {
/**
@@ -17,7 +18,7 @@ export class BWPanel {
private _disposables: vscode.Disposable[] = [];
private static _context?: vscode.ExtensionContext;
- public static createOrShow(extensionUri: vscode.Uri, context: vscode.ExtensionContext) {
+ public static createOrShow(context: vscode.ExtensionContext) {
this._context = context;
const column = vscode.window.activeTextEditor
? vscode.window.activeTextEditor.viewColumn
@@ -26,7 +27,6 @@ export class BWPanel {
// If we already have a panel, show it.
if (BWPanel.currentPanel) {
BWPanel.currentPanel._panel.reveal(column);
- BWPanel.currentPanel._update();
return;
}
@@ -43,13 +43,13 @@ export class BWPanel {
// And restrict the webview to only loading content from our extension's `media` directory.
localResourceRoots: [
- vscode.Uri.joinPath(extensionUri, 'media'),
- vscode.Uri.joinPath(extensionUri, 'out/compiled')
+ vscode.Uri.joinPath(context.extensionUri, 'media'),
+ vscode.Uri.joinPath(context.extensionUri, 'out/compiled')
]
}
);
- BWPanel.currentPanel = new BWPanel(panel, extensionUri);
+ BWPanel.currentPanel = new BWPanel(panel, context.extensionUri);
}
public static kill() {
@@ -64,34 +64,13 @@ export class BWPanel {
private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
this._panel = panel;
this._extensionUri = extensionUri;
-
- // Set the webview's initial html content
this._update();
-
- // Listen for when the panel is disposed
- // This happens when the user closes the panel or when the panel is closed programatically
this._panel.onDidDispose(() => this.dispose(), null, this._disposables);
-
- // // Handle messages from the webview
- // this._panel.webview.onDidReceiveMessage(
- // (message) => {
- // switch (message.command) {
- // case "alert":
- // vscode.window.showErrorMessage(message.text);
- // return;
- // }
- // },
- // null,
- // this._disposables
- // );
}
public dispose() {
BWPanel.currentPanel = undefined;
-
- // Clean up our resources
this._panel.dispose();
-
while (this._disposables.length) {
const x = this._disposables.pop();
if (x) {
@@ -106,12 +85,39 @@ export class BWPanel {
this._panel.webview.html = this._getHtmlForWebview(webview);
webview.onDidReceiveMessage(async (data) => {
switch (data.type) {
+ case 'onSubmit': {
+ 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 (reason) {
+ vscode.window.showErrorMessage('Unable to submit');
+ console.error(reason);
+ break;
+ }
+ vscode.window.showInformationMessage('Submitted!');
+ break;
+ }
case 'onRun': {
if (!data.value) {
return;
}
const repoDir = extensionSettings().repoClonePath;
- const output = await runJava(
+ runJava(
join(
repoDir,
'BWContest',
@@ -129,8 +135,9 @@ export class BWPanel {
),
data.value.problemPascalName,
data.value.input
- );
- this._panel.webview.postMessage({ type: 'onOutput', value: output });
+ ).then((output) => {
+ this._panel.webview.postMessage({ type: 'onOutput', value: output });
+ });
break;
}
case 'onStartup': {
diff --git a/extension/bwcontest/src/submit.ts b/extension/bwcontest/src/submit.ts
new file mode 100644
index 0000000..614df6b
--- /dev/null
+++ b/extension/bwcontest/src/submit.ts
@@ -0,0 +1,63 @@
+import { extensionSettings } from './extension';
+import { exec } from 'child_process';
+import util = require('node:util');
+import axios from 'axios';
+
+const execPromise = util.promisify(exec);
+
+export async function submitProblem(
+ sessionToken: string,
+ contestId: number,
+ teamId: number,
+ problemId: number
+) {
+ const repoClonePath = extensionSettings().repoClonePath;
+ console.log(repoClonePath);
+
+ const clonedRepoPath = `${repoClonePath}/BWContest/${contestId.toString()}/${teamId.toString()}`;
+
+ let output: { stdout: string; stderr: string };
+ output = await execPromise(`git add .`, {
+ cwd: clonedRepoPath
+ });
+
+ if (output.stderr) {
+ console.error(output.stderr);
+ }
+
+ 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
+ });
+ if (res.status !== 200) {
+ throw Error('Failed to post submission');
+ }
+ if (!res.data.success) {
+ throw Error('Submission post unsuccessful');
+ }
+}
diff --git a/extension/bwcontest/webviews/components/ProblemPanel.svelte b/extension/bwcontest/webviews/components/ProblemPanel.svelte
index 4c15cd2..04b14c0 100644
--- a/extension/bwcontest/webviews/components/ProblemPanel.svelte
+++ b/extension/bwcontest/webviews/components/ProblemPanel.svelte
@@ -55,6 +55,12 @@
}
}
+ function onSubmit() {
+ if (teamId && contestId && sessionToken) {
+ postMessage({type: 'onSubmit', value: {sessionToken: sessionToken, contestId: contestId, teamId: teamId, problemId: activeProblem.id, problemName: activeProblem.pascalName}})
+ }
+ }
+
async function fetchProblemData() {
if (sessionToken) {
const res = await fetch(`http://localhost:5173/api/contest/${sessionToken}`);
@@ -122,6 +128,7 @@
+
{/if}