import requests import pathlib from aoc import exceptions def download(year: int, day: int, session_token: str | None) -> bytes: url = f"https://adventofcode.com/{year}/day/{day}/input" cookies = {} if session_token is not None: cookies["session"] = session_token response = requests.get(url, cookies=cookies) if response.status_code != 200: raise exceptions.AocError( f"failed to fetch input file {year}/{day:02} (http:{response.status_code})" " - is AOC_SESSION_TOKEN environment variable set?" ) return response.content def create_input_file( year: int, day: int, session_token: str | None, path_base: pathlib.Path, force: bool = False, exist_ok: bool = False, ): path = path_base / str(year) / f"{day:02}.txt" path.parent.mkdir(parents=True, exist_ok=True) if path.exists() and exist_ok: return if path.exists() and not path.stat().st_size == 0 and not force: raise exceptions.AocError(f"input file {path} already exists") input_data = download(year, day, session_token) with open(path, "wb") as f: f.write(input_data) def get( year: int, day: int, session_token: str | None, path_base: pathlib.Path, ) -> str: path = path_base / str(year) / f"{day:02}.txt" path.parent.mkdir(parents=True, exist_ok=True) create_input_file(year, day, session_token, path_base, exist_ok=True) with open(path) as f: return f.read() def _write_file_if_not_exists( path: pathlib.Path, exist_ok: bool = False, data: bytes | None = None ) -> None: path.parent.mkdir(parents=True, exist_ok=True) if path.exists() and not exist_ok: raise exceptions.AocError(f"{path} already exists") path.touch() if data is None: return with open(path, "wb") as f: f.write(data) _CREATE_TEMPLATE: bytes = b"""\ from typing import Any def part_1(input_data: str) -> Any: # your part 1 solution here return None def part_2(input_data: str) -> Any: # your part 2 solution here return None # alternatively you can implement a "two in one solution" like this # part_1 and part_2 must be removed or commented out in this case # if tuple or list is returned elements will be printed on separate lines # def part_1_2(input_data) -> Any: # return None """ def create( year: int, day: int, solution_base: pathlib.Path, input_base: pathlib.Path, example_base: pathlib.Path, ) -> None: year_path = solution_base / f"year_{year}" year_path.mkdir(parents=True, exist_ok=True) _write_file_if_not_exists(year_path / "__init__.py", exist_ok=True) _write_file_if_not_exists(year_path / f"day_{day:02}.py", data=_CREATE_TEMPLATE) _write_file_if_not_exists(input_base / str(year) / f"{day:02}.txt") _write_file_if_not_exists(example_base / str(year) / f"{day:02}.txt")