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 importlib
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -8,6 +10,7 @@ import traceback
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
|
YEAR = 2019
|
||||||
PATH = pathlib.Path(__file__).parent
|
PATH = pathlib.Path(__file__).parent
|
||||||
INPUT_PATH = PATH / 'input'
|
INPUT_PATH = PATH / 'input'
|
||||||
|
|
||||||
|
@ -96,19 +99,22 @@ parser.add_argument('-d', '--day',
|
||||||
metavar='DAY[-DAY]',
|
metavar='DAY[-DAY]',
|
||||||
help='solve puzzle of day DAY or of range 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',
|
action='store',
|
||||||
type=str,
|
type=str,
|
||||||
metavar='INPUT',
|
metavar='INPUT',
|
||||||
default=INPUT_PATH,
|
default=INPUT_PATH,
|
||||||
help='use INPUT as puzzle input')
|
help='use INPUT as puzzle input')
|
||||||
|
|
||||||
|
group.add_argument('-t', '--test',
|
||||||
|
|
||||||
parser.add_argument('-t', '--test',
|
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help="run tests")
|
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):
|
def parse_day_arg(s, mind, maxd):
|
||||||
"""Parses day argument. Returns a list of days."""
|
"""Parses day argument. Returns a list of days."""
|
||||||
split = s.split('-')
|
split = s.split('-')
|
||||||
|
@ -158,6 +164,65 @@ def main():
|
||||||
day = days[0]
|
day = days[0]
|
||||||
inputs[day] = args.input
|
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
|
#Solve days
|
||||||
for d in days:
|
for d in days:
|
||||||
print("=" * 6 + " Day {} ".format(d) + "=" * 6)
|
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