Added code to download user input by session key
parent
699631a3c1
commit
01d64b9061
75
main.py
75
main.py
|
@ -1,5 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env pypy3
|
||||
|
||||
from scrapper import AdventSession
|
||||
from getpass import getpass
|
||||
import importlib
|
||||
import os
|
||||
import re
|
||||
|
@ -8,6 +10,7 @@ import traceback
|
|||
|
||||
from argparse import ArgumentParser
|
||||
|
||||
YEAR = 2019
|
||||
PATH = pathlib.Path(__file__).parent
|
||||
INPUT_PATH = PATH / 'input'
|
||||
|
||||
|
@ -96,19 +99,22 @@ parser.add_argument('-d', '--day',
|
|||
metavar='DAY[-DAY]',
|
||||
help='solve puzzle of day DAY or of range DAY-DAY')
|
||||
|
||||
parser.add_argument('-i', '--input',
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument('-i', '--input',
|
||||
action='store',
|
||||
type=str,
|
||||
metavar='INPUT',
|
||||
default=INPUT_PATH,
|
||||
help='use INPUT as puzzle input')
|
||||
|
||||
|
||||
|
||||
parser.add_argument('-t', '--test',
|
||||
group.add_argument('-t', '--test',
|
||||
action='store_true',
|
||||
help="run tests")
|
||||
|
||||
group.add_argument('--fetch-session',
|
||||
action='store_true',
|
||||
help='fetch puzzle inputs and solutions for session key')
|
||||
|
||||
def parse_day_arg(s, mind, maxd):
|
||||
"""Parses day argument. Returns a list of days."""
|
||||
split = s.split('-')
|
||||
|
@ -158,6 +164,65 @@ def main():
|
|||
day = days[0]
|
||||
inputs[day] = args.input
|
||||
|
||||
#Fetch inputs of session
|
||||
if args.fetch_session:
|
||||
answer = input('Fetch puzzle input and solutions for session key?\n' +
|
||||
'The session key will not be stored. [Y/n]: ')
|
||||
if 'n' in answer.lower():
|
||||
return
|
||||
key = getpass('Session key: ')
|
||||
sess = AdventSession(key)
|
||||
anon_pattern = re.compile(r'\(anonymous user #(\d+)\)')
|
||||
user = sess.get_user()
|
||||
print('Fetching inputs for {}'.format(user))
|
||||
|
||||
anon_match = anon_pattern.fullmatch(user)
|
||||
if anon_match == None:
|
||||
dir_name = 'user_{}'.format(user.replace(' ', '-'))
|
||||
else:
|
||||
dir_name = 'anon_{}'.format(anon_match.group(1))
|
||||
|
||||
if not os.path.exists(dir_name):
|
||||
os.makedirs(dir_name)
|
||||
mssg = 'Choose directory name or press ENTER for [{}]: '.format(dir_name)
|
||||
r = input(mssg)
|
||||
if r != '':
|
||||
dir_name = r
|
||||
path = PATH / pathlib.Path(dir_name)
|
||||
sol_fn = 'solutions'
|
||||
#Create / overwrite solution file
|
||||
open(path / sol_fn, 'a').close()
|
||||
with open(path / sol_fn, 'w') as f:
|
||||
f.write('')
|
||||
|
||||
input_format = 'day{0:0>2}.txt'
|
||||
for d in days:
|
||||
print('[{}{}] {}/25'.format('#'*d, '.'*(25-d), d), end='\r')
|
||||
try:
|
||||
puzzle_input = sess.get_input(YEAR, d)
|
||||
except e:
|
||||
print('warning : failed to fetch input for day {}'.format(d))
|
||||
print(e)
|
||||
continue
|
||||
#Create file if it doesn't exist
|
||||
fn = path / input_format.format(d)
|
||||
open(fn, 'a').close()
|
||||
with open(fn, 'w') as f:
|
||||
f.write(puzzle_input)
|
||||
|
||||
try:
|
||||
solutions = sess.get_solutions(YEAR, d)
|
||||
except e:
|
||||
print('warning : failed to fetch solutions for day {}'.format(d))
|
||||
print(e)
|
||||
continue
|
||||
|
||||
with open(path / sol_fn, 'a') as f:
|
||||
f.write(' '.join(solutions) + '\n')
|
||||
|
||||
print('\nDone')
|
||||
return
|
||||
|
||||
#Solve days
|
||||
for d in days:
|
||||
print("=" * 6 + " Day {} ".format(d) + "=" * 6)
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from urllib import request
|
||||
import gzip
|
||||
import re
|
||||
|
||||
host = 'https://adventofcode.com/'
|
||||
sol_path = '{year}/day/{day}'
|
||||
input_path = sol_path + '/input'
|
||||
|
||||
sol_pattern = re.compile(r'Your puzzle answer was <code>(.*?)</code>')
|
||||
user_pattern = re.compile(r'<div class="user">(.*?)</div>')
|
||||
|
||||
|
||||
class BadRequest(Exception):
|
||||
pass
|
||||
|
||||
class AdventSession(object):
|
||||
def __init__(self, session_key):
|
||||
head = 'session='
|
||||
if session_key.startswith(head):
|
||||
session = session_key
|
||||
else:
|
||||
session = head + session_key
|
||||
self.headers = {'Cookie' : session,
|
||||
'Accept-Encoding' : 'gzip'}
|
||||
|
||||
def get(self, url):
|
||||
req = request.Request(url, headers=self.headers)
|
||||
res = request.urlopen(req)
|
||||
text = gzip.decompress(res.read()).decode('utf-8')
|
||||
if res.status != 200:
|
||||
raise BadRequest(text)
|
||||
return text
|
||||
|
||||
def get_user(self):
|
||||
text = self.get(host)
|
||||
return user_pattern.search(text).group(1)
|
||||
|
||||
def get_input(self, year, day):
|
||||
text = self.get(host + input_path.format(year=year, day=day))
|
||||
return text
|
||||
|
||||
def get_solutions(self, year, day):
|
||||
text = self.get(host + sol_path.format(year=year, day=day))
|
||||
return sol_pattern.findall(text)
|
||||
|
||||
|
Loading…
Reference in New Issue