Skip to content

Commit 2cfa6ea

Browse files
committed
Add method to scrape Hackerrank contests
1 parent faaf22e commit 2cfa6ea

File tree

2 files changed

+66
-19
lines changed

2 files changed

+66
-19
lines changed

ACedIt/util.py

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ def create_workdir_structure(site, contest):
9999

100100
workdir = data.get('workdir', None)
101101

102-
if not os.path.isdir(os.path.join(workdir,site,contest)):
103-
os.makedirs(os.path.join(workdir,site,contest))
102+
if not os.path.isdir(os.path.join(workdir, site, contest)):
103+
os.makedirs(os.path.join(workdir, site, contest))
104104

105105
@staticmethod
106106
def check_cache(site, contest, problem):
@@ -212,17 +212,18 @@ def handle_kbd_interrupt(args):
212212
print 'Interrupted manually. Cleaning up...'
213213

214214
if args['problem'] is not None:
215-
path = os.path.join(Utilities.cache_dir, args['site'], args['contest'], args['problem'])
215+
path = os.path.join(Utilities.cache_dir, args['site'], args[
216+
'contest'], args['problem'])
216217
if os.path.isdir(path):
217218
rmtree(path)
218219
else:
219-
path = os.path.join(Utilities.cache_dir, args['site'], args['contest'])
220+
path = os.path.join(Utilities.cache_dir, args[
221+
'site'], args['contest'])
220222
if os.path.isdir(path):
221223
rmtree(path)
222224

223225
print 'Done. Exiting gracefully.'
224226

225-
226227
@staticmethod
227228
def run_solution(problem):
228229
"""
@@ -423,8 +424,8 @@ def parse_html(self, req):
423424
pre = re.sub('<[^<]+?>', '', pre)
424425
formatted_outputs += [pre]
425426

426-
print 'Inputs', formatted_inputs
427-
print 'Outputs', formatted_outputs
427+
# print 'Inputs', formatted_inputs
428+
# print 'Outputs', formatted_outputs
428429

429430
return formatted_inputs, formatted_outputs
430431

@@ -452,6 +453,7 @@ def scrape_problem(self):
452453
inputs, outputs = self.parse_html(req)
453454
Utilities.store_files(self.site, self.contest,
454455
self.problem, inputs, outputs)
456+
print 'Done.'
455457

456458
def scrape_contest(self):
457459
"""
@@ -462,8 +464,7 @@ def scrape_contest(self):
462464
req = Utilities.get_html(url)
463465
links = self.get_problem_links(req)
464466

465-
print 'Found problems'
466-
print '\n'.join(links)
467+
print 'Found %d problems..' % (len(links))
467468

468469
if not self.force_download:
469470
cached_problems = os.listdir(os.path.join(
@@ -528,8 +529,8 @@ def parse_html(self, req):
528529
formatted_inputs += [inp.strip()]
529530
formatted_outputs += [out.strip()]
530531

531-
print 'Inputs', formatted_inputs
532-
print 'Outputs', formatted_outputs
532+
# print 'Inputs', formatted_inputs
533+
# print 'Outputs', formatted_outputs
533534

534535
return formatted_inputs, formatted_outputs
535536

@@ -559,6 +560,7 @@ def scrape_problem(self):
559560
inputs, outputs = self.parse_html(req)
560561
Utilities.store_files(self.site, self.contest,
561562
self.problem, inputs, outputs)
563+
print 'Done.'
562564

563565
def scrape_contest(self):
564566
"""
@@ -569,8 +571,7 @@ def scrape_contest(self):
569571
req = Utilities.get_html(url)
570572
links = self.get_problem_links(req)
571573

572-
print 'Found problems'
573-
print '\n'.join(links)
574+
print 'Found %d problems..' % (len(links))
574575

575576
if not self.force_download:
576577
cached_problems = os.listdir(os.path.join(
@@ -638,8 +639,8 @@ def parse_html(self, req):
638639
formatted_inputs += [inp.strip()]
639640
formatted_outputs += [out.strip()]
640641

641-
print 'Inputs', formatted_inputs
642-
print 'Outputs', formatted_outputs
642+
# print 'Inputs', formatted_inputs
643+
# print 'Outputs', formatted_outputs
643644

644645
return formatted_inputs, formatted_outputs
645646

@@ -653,6 +654,7 @@ def scrape_problem(self):
653654
inputs, outputs = self.parse_html(req)
654655
Utilities.store_files(self.site, self.contest,
655656
self.problem, inputs, outputs)
657+
print 'Done.'
656658

657659

658660
class Hackerrank:
@@ -663,7 +665,8 @@ class Hackerrank:
663665
def __init__(self, args):
664666
self.site = args['site']
665667
self.contest = args['contest']
666-
self.problem = '-'.join(args['problem'].split()).lower()
668+
self.problem = '-'.join(args['problem'].split()
669+
).lower() if args['problem'] is not None else None
667670
self.force_download = args['force']
668671

669672
def parse_html(self, req):
@@ -709,11 +712,23 @@ def parse_html(self, req):
709712

710713
formatted_outputs += [formatted_output.strip()]
711714

712-
print 'Inputs', formatted_inputs
713-
print 'Outputs', formatted_outputs
715+
# print 'Inputs', formatted_inputs
716+
# print 'Outputs', formatted_outputs
714717

715718
return formatted_inputs, formatted_outputs
716719

720+
def get_problem_links(self, req):
721+
"""
722+
Method to get the links for the problems
723+
in a given hackerrank contest
724+
"""
725+
data = json.loads(req.text)
726+
data = data['models']
727+
links = ['https://www.hackerrank.com/rest/contests/' + self.contest +
728+
'/challenges/' + problem['slug'] for problem in data]
729+
730+
return links
731+
717732
def scrape_problem(self):
718733
"""
719734
Method to scrape a single problem from hackerrank
@@ -725,3 +740,32 @@ def scrape_problem(self):
725740
inputs, outputs = self.parse_html(req)
726741
Utilities.store_files(self.site, self.contest,
727742
self.problem, inputs, outputs)
743+
print 'Done.'
744+
745+
def scrape_contest(self):
746+
"""
747+
Method to scrape all problems from a given hackerrank contest
748+
"""
749+
print 'Checking problems available for contest ' + self.contest + '...'
750+
url = 'https://www.hackerrank.com/rest/contests/' + self.contest + '/challenges'
751+
req = Utilities.get_html(url)
752+
links = self.get_problem_links(req)
753+
754+
print 'Found %d problems..' % (len(links))
755+
756+
if not self.force_download:
757+
cached_problems = os.listdir(os.path.join(
758+
Utilities.cache_dir, self.site, self.contest))
759+
links = [link for link in links if link.split(
760+
'/')[-1] not in cached_problems]
761+
762+
rs = (grq.get(link) for link in links)
763+
responses = grq.map(rs)
764+
765+
for response in responses:
766+
if response is not None and response.status_code == 200:
767+
inputs, outputs = self.parse_html(response)
768+
self.problem = response.url.split('/')[-1]
769+
Utilities.check_cache(self.site, self.contest, self.problem)
770+
Utilities.store_files(
771+
self.site, self.contest, self.problem, inputs, outputs)

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/coderick14/ACedIt/issues)
2+
[![Open Source Love](https://badges.frapsoft.com/os/v2/open-source.svg?v=103)](https://github.com/coderick14/ACedIt/)
3+
[![MIT Licence](https://badges.frapsoft.com/os/mit/mit.svg?v=103)](https://opensource.org/licenses/mit-license.php)
14
<h1 align="center">
25
<img src="https://github.com/coderick14/ACedIt/blob/master/images/logo.png" width="500"/><br/>
36
</h1>
4-
A command line tool to run your code against sample test cases. Without leaving the terminal :)
7+
A command line tool to run your code against sample test cases. Without leaving the terminal :)
58

69
#### Installation
710
##### Build from source

0 commit comments

Comments
 (0)