Skip to content

Commit 008260f

Browse files
committed
Add 'submission' command.
Signed-off-by: Eric Wang <[email protected]>
1 parent a15ef6c commit 008260f

File tree

5 files changed

+114
-8
lines changed

5 files changed

+114
-8
lines changed

lib/commands/submission.js

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
var _ = require('underscore');
2+
var chalk = require('chalk');
3+
var fs = require('fs');
4+
5+
var sprintf = require('sprintf-js').sprintf;
6+
7+
var core = require('../core');
8+
var h = require('../helper');
9+
10+
var cmd = {
11+
command: 'submission <keyword>',
12+
desc: 'Retrieve earlier submission by name or index',
13+
builder: {
14+
// TODO: retrieve all?? That would be very time costing...
15+
}
16+
};
17+
18+
cmd.handler = function(argv) {
19+
core.getProblem(argv.keyword, function(e, problem) {
20+
if (e) return console.log('ERROR:', e);
21+
22+
core.getSubmissions(problem, function(e, submissions) {
23+
if (e) return console.log('ERROR:', e);
24+
25+
console.log('Total: %s submissions', chalk.yellow(submissions.length));
26+
27+
// Find the latest accepted one
28+
var submission = _.find(submissions, function(x) {
29+
// TODO: select by lang? or always select the latest one?
30+
return x.state === 'Accepted';
31+
});
32+
33+
if (!submission) {
34+
console.log('No Accepted found?');
35+
return;
36+
}
37+
38+
core.getSubmission(submission, function(e, submission) {
39+
if (e) return console.log('ERROR:', e);
40+
41+
var f = problem.key + '.' + submission.id + h.langToExt(submission.lang);
42+
fs.writeFileSync(f, submission.code);
43+
44+
console.log(sprintf('Saved: %s', chalk.yellow.underline(f)));
45+
});
46+
});
47+
});
48+
};
49+
50+
module.exports = cmd;

lib/commands/version.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ cmd.handler = function(argv) {
3636
var sprintf = require('sprintf-js').sprintf;
3737
console.log('\n[Configuration]');
3838
Object.getOwnPropertyNames(config).sort().forEach(function(k) {
39-
console.log(sprintf('%-13s %s', k + ':', config[k]));
39+
console.log(sprintf('%-16s %s', k + ':', config[k]));
4040
});
4141
};
4242

lib/config.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ var h = require('./helper');
44

55
var DEFAULT_CONFIG = {
66
// usually you don't wanna change those
7-
URL_BASE: 'https://leetcode.com',
8-
URL_LOGIN: 'https://leetcode.com/accounts/login/',
9-
URL_PROBLEMS: 'https://leetcode.com/api/problems/algorithms/',
10-
URL_PROBLEM: 'https://leetcode.com/problems/$id',
11-
URL_TEST: 'https://leetcode.com/problems/$key/interpret_solution/',
12-
URL_SUBMIT: 'https://leetcode.com/problems/$key/submit/',
13-
URL_VERIFY: 'https://leetcode.com/submissions/detail/$id/check/',
7+
URL_BASE: 'https://leetcode.com',
8+
URL_LOGIN: 'https://leetcode.com/accounts/login/',
9+
URL_PROBLEMS: 'https://leetcode.com/api/problems/algorithms/',
10+
URL_PROBLEM: 'https://leetcode.com/problems/$id',
11+
URL_TEST: 'https://leetcode.com/problems/$key/interpret_solution/',
12+
URL_SUBMIT: 'https://leetcode.com/problems/$key/submit/',
13+
URL_SUBMISSIONS: 'https://leetcode.com/problems/$key/submissions/',
14+
URL_SUBMISSION: 'https://leetcode.com/submissions/detail/$id/',
15+
URL_VERIFY: 'https://leetcode.com/submissions/detail/$id/check/',
1416

1517
// but you will want change these
1618
LANG: 'cpp', // avail: [c,cpp,csharp,golang,java,javascript,python,ruby,swift]

lib/core.js

+8
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ core.getProblem = function(keyword, cb) {
4242
});
4343
};
4444

45+
core.getSubmissions = function(problem, cb) {
46+
client.getSubmissions(problem, cb);
47+
};
48+
49+
core.getSubmission = function(submission, cb) {
50+
client.getSubmission(submission, cb);
51+
};
52+
4553
core.testProblem = function(problem, cb) {
4654
client.testProblem(problem, cb);
4755
};

lib/leetcode_client.js

+46
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
var _ = require('underscore');
12
var cheerio = require('cheerio');
23
var request = require('request');
34

@@ -137,6 +138,51 @@ leetcodeClient.getProblem = function(problem, cb) {
137138
});
138139
};
139140

141+
leetcodeClient.getSubmissions = function(problem, cb) {
142+
var opts = makeOpts();
143+
opts.url = config.URL_SUBMISSIONS.replace('$key', problem.key);
144+
145+
request(opts, function(e, resp, body) {
146+
e = checkError(e, resp, 200);
147+
// FIXME: if session expired, this will still return 200
148+
if (e) return cb(e);
149+
150+
var $ = cheerio.load(body);
151+
var submissions = $('table[id="result-testcases"] tbody tr')
152+
.map(function() {
153+
var tds = $(this).children();
154+
var submission = {
155+
path: $(tds[2]).children('a').attr('href'),
156+
state: $(tds[2]).children('a').children('strong').text(),
157+
runtime: $(tds[3]).text().trim(),
158+
lang: $(tds[4]).text()
159+
};
160+
161+
submission.id = _.last(_.compact(submission.path.split('/')));
162+
163+
return submission;
164+
}).get();
165+
166+
return cb(null, submissions);
167+
});
168+
};
169+
170+
leetcodeClient.getSubmission = function(submission, cb) {
171+
var opts = makeOpts();
172+
opts.url = config.URL_SUBMISSION.replace('$id', submission.id);
173+
174+
request(opts, function(e, resp, body) {
175+
e = checkError(e, resp, 200);
176+
if (e) return cb(e);
177+
178+
var re = body.match(/submissionCode:\s('[^']*')/);
179+
if (re) {
180+
submission.code = eval(re[1]);
181+
}
182+
return cb(null, submission);
183+
});
184+
};
185+
140186
leetcodeClient.login = function(user, cb) {
141187
request(config.URL_LOGIN, function(e, resp, body) {
142188
e = checkError(e, resp, 200);

0 commit comments

Comments
 (0)