From 149da572c2464ee011adc417d4bfdbbd808af1ca Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Tue, 28 Dec 2021 12:50:37 +0100 Subject: [PATCH] auto input-download and answer-submit --- tools/aoc.py | 122 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 91 insertions(+), 31 deletions(-) diff --git a/tools/aoc.py b/tools/aoc.py index 5151f65..e465131 100644 --- a/tools/aoc.py +++ b/tools/aoc.py @@ -1,4 +1,11 @@ import os +import re +import time +import webbrowser + +import requests +from bs4 import BeautifulSoup +from tools.datafiles import JSONFile from tools.stopwatch import StopWatch from typing import Any, Callable, Dict, List, Tuple, Type, Union from .tools import get_script_dir @@ -43,7 +50,8 @@ class AOCDay: if solution is None: printSolution(self.day, part + 1, answer, solution, case_count, exec_time) - # FIXME: self._submit(part + 1, answer) + if answer not in {u"", b"", None, b"None", u"None"}: + self._submit(part + 1, answer) else: if verbose or answer != solution: printSolution(self.day, part + 1, answer, solution, case_count, exec_time) @@ -62,50 +70,102 @@ class AOCDay: self.runPart(1, verbose, measure_runtime, timeit_number) def _loadInput(self, filename): + file_path = os.path.join(INPUTS_PATH, filename) + if not os.path.exists(file_path): + self._downloadInput(file_path) + with open(os.path.join(INPUTS_PATH, filename)) as f: self.input = f.read().splitlines() def _downloadInput(self, filename: str): - pass + # FIXME: implement wait time for current day before 06:00:00 ? + session_id = open(".session", "r").readlines()[0].strip() + response = requests.get( + "https://adventofcode.com/%d/day/%d/input" % (self.year, self.day), + cookies={'session': session_id} + ) + print(response) + print(response.content) + if response.status_code != 200: + print("FAIL") + with open(filename, "wb") as f: + f.write(response.content) + f.flush() + def _submit(self, part: int, answer: Any): - pass + answer_cache = JSONFile("answer_cache.json", create=True) + print(answer_cache) + str_day = str(self.day) + str_part = str(part) + if str_day not in answer_cache: + answer_cache[str_day] = {} - def test_part1(self, silent: bool = False) -> bool: - live_input = self.input.copy() - for case, solution in enumerate(self.inputs_p1): - with open(os.path.join(INPUTS_PATH, "test_input%02d_1_%d" % (self.day, case))) as f: - self.input = f.read().splitlines() + if str_part not in answer_cache[str_day]: + answer_cache[str_day][str_part] = { + 'wrong': [], + 'correct': None + } - check = self.part1() - if not silent: - printSolution(self.day, 1, check, solution, case) + if answer in answer_cache[str_day][str_part]['wrong']: + print("Already tried %s. It was WRONG." % answer) + return - if check != solution: - if silent: - printSolution(self.day, 1, check, solution, case) - return False + if answer_cache[str_day][str_part]['correct'] is not None: + if answer == answer_cache[str_day][str_part]['correct']: + print("Already submitted %s. It was CORRECT." % answer) + return + else: + print("Already submitted an answer, but another one") + print("CORRECT was: %s" % answer_cache[str_day][str_part]['correct']) + print("Your answer: %s" % answer) + return - self.input = live_input - return True + return + print("Submitting %s as answer for %d part %d" % (answer, self.day, part)) + session_id = open(".session", "r").readlines()[0].strip() + response = requests.post( + "https://adventofcode.com/%d/day/%d/answer" % (self.year, self.day), + cookies={'session': session_id}, + data={'level': part, 'answer': answer} + ) - def test_part2(self, silent: bool = False) -> bool: - live_input = self.input.copy() - for case, solution in enumerate(self.inputs_p2): - with open(os.path.join(INPUTS_PATH, "test_input%02d_2_%d" % (self.day, case))) as f: - self.input = f.read().splitlines() + if not response.ok: + print("Failed to submit answer: (%s) %s" % (response.status_code, response.text)) - check = self.part2() - if not silent: - printSolution(self.day, 2, check, solution, case) + soup = BeautifulSoup(response.text, "html.parser") + message = soup.article.text + if "That's the right answer" in message: + answer_cache[str_day][str_part]['correct'] = answer + print("That's correct!") + webbrowser.open("https://adventofcode.com/%d/day/%d#part2" % (self.year, self.day)) + elif "That's not the right answer" in message: + answer_cache[str_day][str_part]['wrong'].append(answer) + print("That's WRONG!") + elif "You gave an answer too recently" in message: + # WAIT and retry + wait_pattern = r"You have (?:(\d+)m )?(\d+)s left to wait" + try: + [(minutes, seconds)] = re.findall(wait_pattern, message) + except ValueError: + print("wait_pattern unable to find wait_time in:") + print(message) + return - if check != solution: - if silent: - printSolution(self.day, 2, check, solution, case) - return False + seconds = int(seconds) + if minutes: + seconds *= int(minutes) * 60 - self.input = live_input - return True + print("TOO SOON. Waiting %d seconds until auto-retry." % seconds) + time.sleep(seconds) + self._submit(part, answer) + return + else: + print("I don't know what this means:") + print(message) + return + + answer_cache.save() def getInput(self) -> Union[str, List]: if len(self.input) == 1: