Files
aoc-template-py/aoc/input_file.py
2025-11-17 00:18:45 -03:00

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")