77"""
88
99from datetime import datetime
10- from pathlib import Path
1110from time import sleep
1211
1312from bs4 import BeautifulSoup
1413from loguru import logger
1514import requests
15+ from requests import Request , Session
1616
1717from aoc .models .authenticator import Authenticator
1818
@@ -26,10 +26,11 @@ class File:
2626 """
2727
2828 @staticmethod
29- def download_puzzle_input (day : int ) -> str :
29+ def download_puzzle_input (year : int , day : int ) -> str :
3030 """Download the puzzle input for a specific day from Advent of Code.
3131
3232 Args:
33+ year: The year of the puzzle (2024, 2025, etc.)
3334 day: The day number (1-25) of the puzzle.
3435
3536 Returns
@@ -41,28 +42,32 @@ def download_puzzle_input(day: int) -> str:
4142 Year is determined from the project directory name.
4243 """
4344 session = Authenticator .get_session ()
44- path_obj = Path (Authenticator .get_path ())
45- year = path_obj .parts [- 1 ].split ("-" )[- 1 ]
46-
4745 headers = Authenticator .get_headers ()
46+
4847 headers ["Referer" ] = f"https://adventofcode.com/{ year } /day/{ day } "
4948 headers ["Cookie" ] = f"session={ session } "
5049
5150 url = f"https://adventofcode.com/{ year } /day/{ day } /input"
5251 method = "GET"
53- request = requests . Request (method , url , headers = headers )
52+ request = Request (method , url , headers = headers )
5453 prepped_request = request .prepare ()
5554
56- with requests .Session () as sess :
55+ logger .debug (f"URL: { url } " )
56+ logger .debug (f"Headers: { headers } " )
57+ logger .debug (f"Session token length: { len (session )} " )
58+
59+ with Session () as sess :
5760 response = sess .send (prepped_request )
61+ logger .debug (response .status_code )
5862 response .raise_for_status ()
5963 return response .text
6064
6165 @staticmethod
62- def download_test_input (day : int , part_num : int ) -> str | None :
66+ def download_test_input (year : int , day : int , part_num : int ) -> str | None :
6367 """Download test input from the puzzle description for a specific day and part.
6468
6569 Args:
70+ year: The year of the puzzle (2024, 2025, etc.)
6671 day: The day number (1-25) of the puzzle.
6772 part_num: The puzzle part number (1 or 2).
6873
@@ -75,10 +80,8 @@ def download_test_input(day: int, part_num: int) -> str | None:
7580 Part number determines which code block to use.
7681 """
7782 session = Authenticator .get_session ()
78- path_obj = Path (Authenticator .get_path ())
79- year = path_obj .parts [- 1 ].split ("-" )[- 1 ]
80-
8183 headers = Authenticator .get_headers ()
84+
8285 headers ["Referer" ] = f"https://adventofcode.com/{ year } /day/{ day } "
8386 headers ["Cookie" ] = f"session={ session } "
8487
@@ -97,7 +100,7 @@ def download_test_input(day: int, part_num: int) -> str | None:
97100 return None
98101
99102 @staticmethod
100- def add_day (day : int ) -> None :
103+ def add_day (year : int , day : int ) -> None :
101104 """Set up the file structure for a new puzzle day.
102105
103106 Creates solution file from template and downloads puzzle input when available.
@@ -112,7 +115,7 @@ def add_day(day: int) -> None:
112115 - `data/dayXX/puzzle_input.txt`
113116 """
114117 path = Authenticator .get_path ()
115- solution_path = path / f"solutions/day{ day :02} .py"
118+ solution_path = path / str ( year ) / f"solutions/day{ day :02} .py"
116119
117120 if not solution_path .exists ():
118121 sample_file = path / "templates/solutions/sample.py"
@@ -121,7 +124,7 @@ def add_day(day: int) -> None:
121124 solution_path .write_text (content )
122125 logger .info (f"Created file: { solution_path } " )
123126
124- folder_path = path / f"data/day{ day :02} "
127+ folder_path = path / str ( year ) / f"data/day{ day :02} "
125128 folder_path .mkdir (parents = True , exist_ok = True )
126129
127130 file_path = folder_path / "puzzle_input.txt"
@@ -146,25 +149,26 @@ def add_day(day: int) -> None:
146149 now = datetime .now ()
147150
148151 logger .info ("Downloading puzzle input..." )
149- file_path .write_text (File .download_puzzle_input (day ))
152+ file_path .write_text (File .download_puzzle_input (year , day ))
150153 logger .info (f"Downloaded puzzle input to: { file_path } " )
151154
152155 @staticmethod
153- def add_test_input (day : int , part_num : int ) -> None :
156+ def add_test_input (year : int , day : int , part_num : int ) -> None :
154157 """Set up and download test input for a specific puzzle part.
155158
156159 Creates test input file and downloads content when available.
157160 Waits for puzzle unlock time (5:00 UTC) if necessary.
158161
159162 Args:
163+ year: The year of the puzzle (2024, 2025, etc.)
160164 day: The day number (1-25) of the puzzle.
161165 part_num: The puzzle part number (1 or 2).
162166
163167 Note:
164168 Creates file at: `tests/data/dayXX/test_XX_input.txt`
165169 """
166170 path = Authenticator .get_path ()
167- folder_path = path / f"tests/data/day{ day :02} "
171+ folder_path = path / str ( year ) / f"tests/data/day{ day :02} "
168172 folder_path .mkdir (parents = True , exist_ok = True )
169173
170174 file_path = folder_path / f"test_{ part_num :02d} _input.txt"
@@ -191,18 +195,19 @@ def add_test_input(day: int, part_num: int) -> None:
191195 logger .info ("Downloading test input..." )
192196
193197 # Use the method's return value
194- test_input = File .download_test_input (day , part_num )
198+ test_input = File .download_test_input (year , day , part_num )
195199
196200 # Only write if test input is not None
197201 if test_input is not None :
198202 file_path .write_text (test_input )
199203 logger .info (f"Downloaded test input to: { file_path } " )
200204
201205 @staticmethod
202- def add_test_file (day : int ) -> None :
206+ def add_test_file (year : int , day : int ) -> None :
203207 """Create a test file for a specific puzzle day from template.
204208
205209 Args:
210+ year: The year of the puzzle (2024, 2025, etc.)
206211 day: The day number (1-25) to create test file for.
207212
208213 Note:
@@ -215,7 +220,7 @@ def add_test_file(day: int) -> None:
215220 FileNotFoundError: If the template file is not found.
216221 """
217222 path = Authenticator .get_path ()
218- test_path = path / f"tests/test_{ day :02} .py"
223+ test_path = path / str ( year ) / f"tests/test_{ day :02} .py"
219224
220225 logger .info (f"Test file path: { test_path } " )
221226
0 commit comments