Skip to content

Commit 4445b45

Browse files
The change is coming
1 parent 418e54f commit 4445b45

File tree

7 files changed

+482
-69
lines changed

7 files changed

+482
-69
lines changed

.gitignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
.DS_Store
22
npm-debug.log
33
node_modules
4-
todo.txt
54
main.py
5+
backup.js
6+
todo.txt
67
rough.js
8+
rough1.js
79
rough2.js
810
rough3.js
9-
backup.js
11+
codeforces-scraper.js

lib/config.js

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,50 @@
22

33
export default {
44
codeforcesHandle: {
5-
title: 'Codeforces Handle',
6-
order: 1,
7-
type: 'string',
8-
default: 'blue_edge'
5+
title: 'Codeforces Handle',
6+
order: 1,
7+
type: 'string',
8+
default: 'blue_edge'
99
},
1010

1111
programmingLanguage: {
12-
title: 'Programming Language',
13-
order: 2,
14-
description: 'The chosen language will only be used for submitting a source file.',
15-
type: 'integer',
16-
default: 31,
17-
enum: [
18-
{ value: 43, description: 'GNU GCC C11 5.1.0' },
19-
{ value: 54, description: 'GNU G++17 7.3.0' },
20-
{ value: 31, description: 'Python 3.7.2' },
21-
{ value: 41, description: 'PyPy 3.6 (7.2.0)' }
22-
]
12+
title: 'Programming Language',
13+
order: 2,
14+
description: 'The chosen language will only be used for submitting a source file.',
15+
type: 'integer',
16+
default: 31,
17+
enum: [{
18+
value: 43,
19+
description: 'GNU GCC C11 5.1.0'
20+
},
21+
{
22+
value: 54,
23+
description: 'GNU G++17 7.3.0'
24+
},
25+
{
26+
value: 31,
27+
description: 'Python 3.7.2'
28+
},
29+
{
30+
value: 41,
31+
description: 'PyPy 3.6 (7.2.0)'
32+
}
33+
]
2334
},
2435

25-
compilationCommand: {
26-
title: 'Compilation Command',
27-
order: 3,
28-
description: 'Remember to also adjust the executable file name in the file structure settings if necessary.',
29-
type: 'string',
30-
default: 'python'
36+
refreshinterval: {
37+
title: 'Autorefresh interval',
38+
order: 3,
39+
description: 'Refresh interval of standings and submission',
40+
type: 'integer',
41+
default: 5
3142
},
3243

3344
workingDirectory: {
34-
title: 'Working directory',
35-
order: 4,
36-
description: 'Where your source files will be stored during contest',
37-
type: 'string',
38-
default: 'C:/Users/'
45+
title: 'Working directory',
46+
order: 4,
47+
description: 'Where your source files will be stored during contest',
48+
type: 'string',
49+
default: 'C:/Users/'
3950
}
4051
}

lib/view/actions.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ export default class Actions extends React.PureComponent {
99
prob: props.prob,
1010
outputs: props.outputs,
1111
tests: props.tests,
12-
runexamples: props.runexamples
12+
runexamples: props.runexamples,
13+
submitsolution: props.submitsolution
1314
}
1415
}
1516

@@ -18,7 +19,8 @@ export default class Actions extends React.PureComponent {
1819
prob: nextProps.prob,
1920
outputs: nextProps.outputs,
2021
tests: nextProps.tests,
21-
runexamples: nextProps.runexamples
22+
runexamples: nextProps.runexamples,
23+
submitsolution: nextProps.submitsolution
2224
});
2325
}
2426

@@ -35,6 +37,11 @@ export default class Actions extends React.PureComponent {
3537
}
3638

3739
togglesubmit(ele){
40+
if(ele.target.classList.length>1){
41+
if(ele.target.classList[1]=="realsubmit"){
42+
this.state.submitsolution()
43+
}
44+
}
3845
var parent = ele.target.parentElement
3946
if(parent==null) return
4047
for (var i = 1; i < parent.children.length; i++) {
@@ -103,9 +110,9 @@ export default class Actions extends React.PureComponent {
103110
<div className="task">
104111
<div className="up">
105112
<span className="icon icon-light-bulb">Submissions</span>
106-
<button onClick={this.togglesubmit} className="actionbutton" style={{display: "block"}}>Submit</button>
107-
<button onClick={this.togglesubmit} className="actionbutton realsubmit" style={{display: "none"}}>Submit</button>
108-
<button onClick={this.togglesubmit} className="actionbutton cancel" style={{display: "none"}}>Cancel</button>
113+
<button onClick={this.togglesubmit.bind(this)} className="actionbutton" style={{display: "block"}}>Submit</button>
114+
<button onClick={this.togglesubmit.bind(this)} className="actionbutton realsubmit" style={{display: "none"}}>Submit</button>
115+
<button onClick={this.togglesubmit.bind(this)} className="actionbutton cancel" style={{display: "none"}}>Cancel</button>
109116
</div>
110117
</div>
111118
</div>

lib/view/index.js

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React from 'react';
44
import Problems from './problems';
55
import config from '../config'
66
import cheerio from 'cheerio'
7+
// import CodeforcesScraper from './codeforces-scraper';
78

89
function couple(x) {
910
if(x<10){
@@ -16,21 +17,23 @@ function couple(x) {
1617
export default class Root extends React.PureComponent {
1718
constructor(props){
1819
super(props);
20+
this.state = {
21+
desc: "",
22+
id: "",
23+
finished: 0,
24+
changed: 0,
25+
timeremaining: 0,
26+
profimg: "//imgbin.com/png/LGzVdNb1/computer-icons-avatar-user-login-png"
27+
};
28+
1929
// this.state = {
20-
// desc: "",
21-
// id: "",
22-
// changed: 0,
30+
// desc: "Educational round 93",
31+
// id: 1398,
32+
// finished: 0,
33+
// changed: 2,
2334
// timeremaining: 0,
2435
// profimg: "//templates.joomla-monster.com/joomla30/jm-news-portal/components/com_djclassifieds/assets/images/default_profile.png"
2536
// };
26-
27-
this.state = {
28-
desc: "Educational round 93",
29-
id: 1398,
30-
changed: 2,
31-
timeremaining: 0,
32-
profimg: "//templates.joomla-monster.com/joomla30/jm-news-portal/components/com_djclassifieds/assets/images/default_profile.png"
33-
};
3437
}
3538

3639
timesolver(s){
@@ -49,7 +52,12 @@ export default class Root extends React.PureComponent {
4952
if(contest.phase=="BEFORE"){
5053
this.setState({timeremaining: -1*contest.relativeTimeSeconds})
5154
}else{
52-
this.setState({timeremaining: 1})
55+
if(contest.phase!="CODING"){
56+
console.log("Yes");
57+
this.setState({timeremaining: 1, finished: 1})
58+
}else{
59+
this.setState({timeremaining: 1})
60+
}
5361
}
5462
break;
5563
}
@@ -82,7 +90,10 @@ export default class Root extends React.PureComponent {
8290
return(
8391
<div className="timer">
8492
<span>Before contest</span>
85-
<span>{couple(Math.floor(sec/3600))} : {couple(Math.floor((sec%3600)/60))} : {couple(Math.floor((sec%3600)%60))}</span>
93+
<span>
94+
{couple(Math.floor(sec/3600))} :
95+
{couple(Math.floor((sec%3600)/60))} :
96+
{couple(Math.floor((sec%3600)%60))}</span>
8697
</div>
8798
)
8899
}

lib/view/problems.js

Lines changed: 91 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,37 @@ export default class Problems extends React.PureComponent {
9999
}
100100
}
101101

102+
submitsolution(){
103+
console.log("Submitting solution");
104+
const path = require('path');
105+
var prob = this.state.probs[this.state.curr]
106+
var langcode = atom.config.get("codeblue.programmingLanguage")
107+
var ext = ""
108+
if(langcode==43) ext=".c"
109+
else if(langcode==54) ext=".cpp"
110+
else ext=".py"
111+
var wd = atom.config.get("codeblue.workingDirectory")
112+
var towhere = path.join(wd,prob.index)
113+
var tosub = path.join(towhere,prob.index+ext)
114+
var proburl = "https://codeforces.com/contest/"+ this.props.contest.id +"/problem/" + prob.index
115+
116+
cmd = "oj s " + proburl + " " + tosub + " --wait=0 --yes --no-open"
117+
if(langcode==41){
118+
cmd+= " --guess-python-interpreter pypy"
119+
}
120+
121+
const { exec } = require('child_process');
122+
exec(cmd,(error, stdout, stderr)=>{
123+
if(error !== null){
124+
console.log(error);
125+
atom.notifications.addError("Error occured while submitting")
126+
}else{
127+
this.loadsubmissions()
128+
}
129+
130+
})
131+
}
132+
102133
fetch(url){
103134
return new Promise((resolve, reject) => {
104135
request(url, (error, response, body) => {
@@ -178,7 +209,7 @@ export default class Problems extends React.PureComponent {
178209
this.setState({alloutputs: alloutputs})
179210
this.setState({allverdicts: allverdicts})
180211
// console.log(this.state.allverdicts);
181-
// this.createnv()
212+
this.createnv()
182213
}
183214

184215
loadsamplecases(i){
@@ -217,7 +248,7 @@ export default class Problems extends React.PureComponent {
217248
}
218249

219250
loadmystanding(){
220-
console.log("Loading my standing");
251+
// console.log("Loading my standing");
221252
var url = "https://codeforces.com/api/contest.standings?contestId="+ this.props.contest.id +"&from=1&handles=" + atom.config.get("codeblue.codeforcesHandle")
222253
fetch(url)
223254
.then(res=> res.json())
@@ -226,7 +257,8 @@ export default class Problems extends React.PureComponent {
226257
}
227258

228259
loadsubmissions(){
229-
console.log("Loading new submissions");
260+
console.log("Refreshing");
261+
// console.log("Loading new submissions");
230262
var url = "https://codeforces.com/contest/"+this.props.contest.id
231263
this.fetch(url).then((html) => {
232264
this.scrape(html);
@@ -238,12 +270,13 @@ export default class Problems extends React.PureComponent {
238270
}
239271

240272
fetchproblems(problems){
273+
// console.log("Fetching problems", problems);
241274
var probs = []
242275
var noftests = []
243276
var allinputs = {}
244277
var alloutputs = {}
245278
var allverdicts = {}
246-
for (var problem of problems) {
279+
for (var problem of this.state.probs) {
247280
probs.push({
248281
index: problem.index,
249282
name: problem.name,
@@ -271,12 +304,20 @@ export default class Problems extends React.PureComponent {
271304
var i = 0
272305
for (var prob of this.state.probs) {
273306
probs.push(prob)
307+
if(prob.verdict=="OK") continue
308+
274309
for (var action of this.state.actions) {
275310
if(action.index==prob.index){
276-
probs[i].verdict = action.verdict
277-
probs[i].testset = action.testset
278-
probs[i].errtest = action.errtest
279-
break
311+
if(action.verdict=="OK"){
312+
probs[i].verdict = "OK"
313+
probs[i].testset = action.testset
314+
probs[i].errtest = action.errtest
315+
break
316+
}else if(prob.verdict=="NONE"){
317+
probs[i].verdict = action.verdict
318+
probs[i].testset = action.testset
319+
probs[i].errtest = action.errtest
320+
}
280321
}
281322
}
282323
i++;
@@ -293,8 +334,9 @@ export default class Problems extends React.PureComponent {
293334
else if(action.verdict=="TIME_LIMIT_EXCEEDED") icon="clock"
294335
else if(action.verdict=="RUNTIME_ERROR") icon="stop"
295336
else if(action.verdict=="COMPILATION_ERROR") icon="alert"
296-
else if(action.verdict=="TESTING") icon = "kebab-horizontal"
297337
else if(action.verdict=="MEMORY_LIMIT_EXCEEDED") icon="database"
338+
else if(action.verdict=="CHALLENGED") icon="flame"
339+
else icon = "hourglass"
298340

299341
actions.push({
300342
index: action.problem.index,
@@ -311,27 +353,58 @@ export default class Problems extends React.PureComponent {
311353
}
312354

313355
fetchactions(){
314-
console.log("Loading my actions");
356+
// console.log("Loading my actions");
315357
var url = "https://codeforces.com/api/contest.status?contestId="+ this.props.contest.id +"&handle="+ atom.config.get("codeblue.codeforcesHandle")
316358
fetch(url)
317359
.then(res=> res.json())
318360
.then(res=> this.reloadactions(res.result))
319361
.catch(err => console.log(err))
320362
}
321363

364+
scrapeproblems(html){
365+
$ = cheerio.load(html)
366+
var i = 2
367+
var probs = []
368+
while(true){
369+
var idx = $(`#pageContent > div.datatable > div:nth-child(6) > table > tbody > tr:nth-child(${i}) > td.id > a`).text().trim()
370+
var nm = $(`#pageContent > div.datatable > div:nth-child(6) > table > tbody > tr:nth-child(${i}) > td:nth-child(2) > div > div:nth-child(1) > a`).text().trim()
371+
if(idx.length==0){
372+
break;
373+
}else{
374+
probs.push({index: idx, name: nm})
375+
}
376+
i++;
377+
}
378+
379+
this.setState({probs: probs})
380+
}
381+
322382
componentWillMount(){
323-
var url = "https://codeforces.com/api/contest.standings?contestId="+this.props.contest.id+"&from=1&count=1"
324-
fetch(url)
325-
.then(res=>res.json())
326-
.then(res=> this.fetchproblems(res.result.problems))
327-
.catch(err=>console.log(err))
383+
var url = "https://codeforces.com/contest/"+this.props.contest.id
384+
this.fetch(url).then(html => {
385+
this.scrapeproblems(html);
386+
}).then(res => {
387+
this.fetchproblems()
388+
}).catch((error) => {
389+
atom.notifications.addWarning(error.reason)
390+
})
328391

329-
// setInterval(()=>{this.loadsubmissions()},10000)
392+
var intervaltime = atom.config.get("codeblue.refreshinterval")
393+
394+
if(this.props.contest.finished==0){
395+
setInterval(()=>{this.loadsubmissions()},intervaltime*1000)
396+
}
330397
}
331398

332399
hide(ele){
333400
if(ele==null) return
334-
var val = ele.target.parentElement.nextElementSibling.style.display
401+
var parent = ele.target.parentElement
402+
if(parent==null) return
403+
var tohide = parent.nextElementSibling
404+
if(tohide==null) return
405+
if(tohide.classList.length<1) return
406+
if(tohide.classList[0]!="problems") return
407+
var val = tohide.style.display
335408
if(val=="flex"){
336409
ele.target.parentElement.nextElementSibling.style.display = "none";
337410
}else{
@@ -361,6 +434,7 @@ export default class Problems extends React.PureComponent {
361434
outputs={this.state.alloutputs[this.state.probs[this.state.curr].index]}
362435
tests={this.state.allverdicts[this.state.probs[this.state.curr].index]}
363436
runexamples ={this.runexamples.bind(this)}
437+
submitsolution={this.submitsolution.bind(this)}
364438
/> : null }
365439
{this.state.probs.length ? <RecentSubmissions actions={this.state.actions}/> : null }
366440
</div>

0 commit comments

Comments
 (0)