114 lines
2.9 KiB
Python
114 lines
2.9 KiB
Python
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")
|