atcoder-gui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +149 -0
- package/dist/browser.d.ts +59 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +130 -0
- package/dist/browser.js.map +1 -0
- package/dist/config.d.ts +53 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +103 -0
- package/dist/config.js.map +1 -0
- package/dist/config.json5 +15 -0
- package/dist/cookie-export.d.ts +43 -0
- package/dist/cookie-export.d.ts.map +1 -0
- package/dist/cookie-export.js +151 -0
- package/dist/cookie-export.js.map +1 -0
- package/dist/main.d.ts +39 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +206 -0
- package/dist/main.js.map +1 -0
- package/dist/session.d.ts +53 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +73 -0
- package/dist/session.js.map +1 -0
- package/dist/submit.d.ts +22 -0
- package/dist/submit.d.ts.map +1 -0
- package/dist/submit.js +94 -0
- package/dist/submit.js.map +1 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +18 -0
- package/dist/utils.js.map +1 -0
- package/package.json +57 -0
package/dist/submit.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
export class SubmitManager {
|
|
3
|
+
browserManager;
|
|
4
|
+
constructor(browserManager) {
|
|
5
|
+
this.browserManager = browserManager;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Submit solution to AtCoder
|
|
9
|
+
*/
|
|
10
|
+
async submitSolution() {
|
|
11
|
+
try {
|
|
12
|
+
// Check if required files exist in current directory
|
|
13
|
+
const metadataPath = './metadata.json';
|
|
14
|
+
const mainCppPath = './main.cpp';
|
|
15
|
+
if (!existsSync(metadataPath)) {
|
|
16
|
+
console.error('Error: metadata.json not found in current directory');
|
|
17
|
+
console.log('Make sure you are in a directory created by atcoder-tools');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (!existsSync(mainCppPath)) {
|
|
21
|
+
console.error('Error: main.cpp not found in current directory');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// Parse metadata.json to get contest_id and problem_id
|
|
25
|
+
const { contestId, problemId } = this.parseMetadata(metadataPath);
|
|
26
|
+
console.log(`Contest ID: ${contestId}, Problem ID: ${problemId}`);
|
|
27
|
+
// Read main.cpp content
|
|
28
|
+
const sourceCode = this.readSourceCode(mainCppPath);
|
|
29
|
+
console.log(`Source code loaded (${sourceCode.length} characters)`);
|
|
30
|
+
// Open AtCoder submit URL
|
|
31
|
+
const submitUrl = `https://atcoder.jp/contests/${contestId}/submit?taskScreenName=${problemId}`;
|
|
32
|
+
console.log(`Opening submit page: ${submitUrl}`);
|
|
33
|
+
if (!this.browserManager.isRunning()) {
|
|
34
|
+
await this.browserManager.launch();
|
|
35
|
+
}
|
|
36
|
+
await this.browserManager.openUrl(submitUrl);
|
|
37
|
+
// Copy source code to clipboard and fill the textarea
|
|
38
|
+
await this.fillSourceCodeArea(sourceCode);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error('Error during submission:', error);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parse metadata.json to extract contest_id and problem_id
|
|
46
|
+
*/
|
|
47
|
+
parseMetadata(metadataPath) {
|
|
48
|
+
try {
|
|
49
|
+
const metadataContent = readFileSync(metadataPath, 'utf-8');
|
|
50
|
+
const metadata = JSON.parse(metadataContent);
|
|
51
|
+
const contestId = metadata.problem.contest.contest_id;
|
|
52
|
+
const problemId = metadata.problem.problem_id;
|
|
53
|
+
if (!contestId || !problemId) {
|
|
54
|
+
throw new Error('contest_id or problem_id not found in metadata.json');
|
|
55
|
+
}
|
|
56
|
+
return { contestId, problemId };
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
throw new Error(`Failed to parse metadata.json: ${error}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Read source code from main.cpp
|
|
64
|
+
*/
|
|
65
|
+
readSourceCode(mainCppPath) {
|
|
66
|
+
try {
|
|
67
|
+
return readFileSync(mainCppPath, 'utf-8');
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
throw new Error(`Failed to read main.cpp: ${error}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Fill the source code area on AtCoder submit page
|
|
75
|
+
*/
|
|
76
|
+
async fillSourceCodeArea(sourceCode) {
|
|
77
|
+
try {
|
|
78
|
+
const page = this.browserManager.getCurrentPage();
|
|
79
|
+
if (!page) {
|
|
80
|
+
throw new Error('No active page found');
|
|
81
|
+
}
|
|
82
|
+
// Find the source code textarea (common selectors for AtCoder)
|
|
83
|
+
const textareaSelector = 'textarea[name="sourceCode"], textarea#editor, .ace_text-input';
|
|
84
|
+
await page.waitForSelector(textareaSelector, { timeout: 10000 });
|
|
85
|
+
// Clear existing content and paste source code
|
|
86
|
+
await page.fill(textareaSelector, sourceCode);
|
|
87
|
+
console.log('✓ Copied!');
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error('Failed to fill source code area:', error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=submit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"submit.js","sourceRoot":"","sources":["../src/submit.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for atcoder-gui
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format date for Python LWPCookieJar format: "2026-05-22 13:20:38Z"
|
|
6
|
+
* @param date Date object to format
|
|
7
|
+
* @returns Formatted date string in LWP format
|
|
8
|
+
*/
|
|
9
|
+
export declare function formatLWPDate(date: Date): string;
|
|
10
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAShD"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for atcoder-gui
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format date for Python LWPCookieJar format: "2026-05-22 13:20:38Z"
|
|
6
|
+
* @param date Date object to format
|
|
7
|
+
* @returns Formatted date string in LWP format
|
|
8
|
+
*/
|
|
9
|
+
export function formatLWPDate(date) {
|
|
10
|
+
const year = date.getUTCFullYear();
|
|
11
|
+
const month = String(date.getUTCMonth() + 1).padStart(2, '0');
|
|
12
|
+
const day = String(date.getUTCDate()).padStart(2, '0');
|
|
13
|
+
const hours = String(date.getUTCHours()).padStart(2, '0');
|
|
14
|
+
const minutes = String(date.getUTCMinutes()).padStart(2, '0');
|
|
15
|
+
const seconds = String(date.getUTCSeconds()).padStart(2, '0');
|
|
16
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}Z`;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAE9D,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,OAAO,IAAI,OAAO,GAAG,CAAC;AACnE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "atcoder-gui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Browser automation tool for AtCoder with CLI interface",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/main.js",
|
|
7
|
+
"types": "dist/main.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"atcoder-gui": "dist/main.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist/**/*",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18.0.0"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc && cp src/config.json5 dist/",
|
|
21
|
+
"dev": "tsc --watch",
|
|
22
|
+
"test": "vitest",
|
|
23
|
+
"test:run": "vitest run",
|
|
24
|
+
"lint": "eslint src/**/*.ts",
|
|
25
|
+
"lint:fix": "eslint src/**/*.ts --fix",
|
|
26
|
+
"start": "tsx src/main.ts",
|
|
27
|
+
"start:built": "node dist/main.js",
|
|
28
|
+
"clean": "rm -rf dist",
|
|
29
|
+
"prepublishOnly": "npm run clean && npm run build && npm run test:run && npm run lint"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/firewood/atcoder-gui.git"
|
|
34
|
+
},
|
|
35
|
+
"keywords": ["atcoder", "browser-automation", "cli", "competitive-programming", "playwright", "typescript"],
|
|
36
|
+
"author": "firewood <174658+firewood@users.noreply.github.com>",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/firewood/atcoder-gui/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/firewood/atcoder-gui#readme",
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"conf": "^15.0.2",
|
|
44
|
+
"json5": "^2.2.3",
|
|
45
|
+
"playwright": "^1.56.1"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@playwright/test": "^1.56.1",
|
|
49
|
+
"@types/node": "^24.10.1",
|
|
50
|
+
"@typescript-eslint/eslint-plugin": "^8.47.0",
|
|
51
|
+
"@typescript-eslint/parser": "^8.47.0",
|
|
52
|
+
"eslint": "^9.39.1",
|
|
53
|
+
"tsx": "^4.20.6",
|
|
54
|
+
"typescript": "^5.9.3",
|
|
55
|
+
"vitest": "^4.0.13"
|
|
56
|
+
}
|
|
57
|
+
}
|