Skip to content

Commit 04407d7

Browse files
kmykkyuridenamida
authored andcommitted
Add the userscript (kyuridenamida#115)
1 parent 5577c27 commit 04407d7

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

webapp/src/index.user.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// ==UserScript==
2+
// @name atcoder-tools user script
3+
// @namespace https://github.com/kyuridenamida/atcoder-tools
4+
// @version 1.0.0
5+
// @description write the code generated by atcoder-tools into the AtCoder's textbox
6+
// @author Kimiyuki Onaka
7+
// @match *://atcoder.jp/contests/*/tasks/*
8+
// ==/UserScript==
9+
10+
import QualityResult from './models/QualityResult';
11+
import Language from './models/Language';
12+
13+
declare const $ : any; // of jQuery
14+
15+
function loadAllQualityResults(): Promise<QualityResult[]> {
16+
const apiUrl = 'https://kyuridenamida.github.io/atcoder-tools/api/all.json';
17+
18+
return new Promise<QualityResult[]>((resolve, reject) => {
19+
const xhr = new XMLHttpRequest();
20+
xhr.open('GET', apiUrl);
21+
xhr.responseType = 'json';
22+
23+
xhr.onload = () => {
24+
if (xhr.status === 200) {
25+
const qualityResult: QualityResult[] = xhr.response;
26+
resolve(qualityResult);
27+
28+
} else {
29+
reject(Error(xhr.statusText));
30+
}
31+
};
32+
xhr.onerror = () => {
33+
reject(Error("Network Error"));
34+
};
35+
36+
xhr.send();
37+
});
38+
}
39+
40+
function getContestIdAndProblemId(): [string, string] {
41+
const re = new RegExp('://atcoder\\.jp/contests/([^/]+)/tasks/([^/?&]+)');
42+
const found = window.location.href.match(re);
43+
if (found == null) {
44+
throw Error("failed to parse URL. something wrong");
45+
}
46+
const contestId = found[1];
47+
const problemId = found[2];
48+
return [contestId, problemId];
49+
}
50+
51+
function getQualityResultForCurrentProblem(allQualityResults: QualityResult[]): QualityResult {
52+
const [contestId, problemId] = getContestIdAndProblemId();
53+
for (const qualityResult of allQualityResults) {
54+
if (qualityResult.contest.contest_id === contestId && qualityResult.problem.problem_id === problemId) {
55+
return qualityResult;
56+
}
57+
}
58+
throw Error("QualityResult not found");
59+
}
60+
61+
function getLanguageFromAtCoderDisplayName(languageName: string): Language | null {
62+
if (languageName.startsWith('C++')) {
63+
return 'cpp';
64+
} else if (languageName.startsWith('Java') && ! languageName.startsWith('JavaScript')) {
65+
return 'java';
66+
} else if (languageName.startsWith('Rust')) {
67+
return 'rust';
68+
} else if (languageName.startsWith('Python3') || languageName.startsWith('PyPy3')) {
69+
return 'python';
70+
} else {
71+
return null;
72+
}
73+
}
74+
75+
function isErasableCode(code: string, qualityResult: QualityResult): boolean {
76+
if (!code.trim()) {
77+
return true;
78+
}
79+
for (const generatedCode of Object.values(qualityResult.codes)) {
80+
if (code.trim() === generatedCode.trim()) {
81+
return true;
82+
}
83+
}
84+
return false;
85+
}
86+
87+
async function main() {
88+
const textarea = document.getElementsByName('sourceCode')[0];
89+
const languageId = document.getElementsByName('data.LanguageId')[0] as HTMLSelectElement;
90+
if (textarea === undefined) {
91+
throw Error("textarea not found. are you logged in?");
92+
}
93+
94+
const allQualityResults = await loadAllQualityResults();
95+
const qualityResult = getQualityResultForCurrentProblem(allQualityResults);
96+
console.log(`QualityResult: ${qualityResult}`);
97+
98+
const editor = $(textarea).data('editor'); // of CodeMirror (https://codemirror.net/)
99+
const run = () => {
100+
if (isErasableCode(editor.getValue(), qualityResult)) {
101+
const languageName = languageId.options[languageId.selectedIndex].textContent;
102+
const language = languageName === null ? null : getLanguageFromAtCoderDisplayName(languageName);
103+
editor.setValue(language === null ? "" : qualityResult.codes[language]);
104+
}
105+
};
106+
run();
107+
editor.on('optionChange', run);
108+
}
109+
110+
main();

webapp/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"acceptance-tests",
2727
"webpack",
2828
"jest",
29-
"src/setupTests.ts"
29+
"src/setupTests.ts",
30+
"src/intex.user.ts"
3031
]
3132
}

0 commit comments

Comments
 (0)