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/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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"}
@@ -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
+ }