1414
1515
1616class File :
17+ """
18+ Utility class for managing Advent of Code file operations and puzzle input retrieval.
19+
20+ This class provides static methods for handling file paths, session management,
21+ downloading puzzle/test inputs, and setting up solution files. It manages the
22+ directory structure and timing for puzzle input availability.
23+ """
24+
1725 @staticmethod
1826 def get_path () -> str :
27+ """
28+ Get the absolute path to the project directory.
29+
30+ Returns:
31+ str: Absolute path to either the directory containing the script or
32+ the script's directory if it is itself a directory.
33+ """
1934 return (
2035 path
2136 if os .path .isdir (path := os .path .realpath (sys .argv [0 ]))
@@ -24,6 +39,15 @@ def get_path() -> str:
2439
2540 @staticmethod
2641 def get_session () -> str :
42+ """
43+ Retrieve the Advent of Code session token from a local file.
44+
45+ Returns:
46+ str: The session token stripped of whitespace.
47+
48+ Note:
49+ Expects a file named `aoc_session` in the project root directory.
50+ """
2751 session = ""
2852 path = File .get_path ()
2953 session_path = os .path .realpath (f"{ path } /aoc_session" )
@@ -35,6 +59,15 @@ def get_session() -> str:
3559
3660 @staticmethod
3761 def get_headers () -> Dict [str , str ]:
62+ """
63+ Load HTTP headers configuration from a JSON file.
64+
65+ Returns:
66+ Dict[str, str]: Dictionary of HTTP headers for AoC API requests.
67+
68+ Note:
69+ Expects a file named `aoc_headers.json` in the project root directory.
70+ """
3871 headers = {}
3972 path = File .get_path ()
4073 headers_config_path = os .path .realpath (f"{ path } /aoc_headers.json" )
@@ -46,6 +79,19 @@ def get_headers() -> Dict[str, str]:
4679
4780 @staticmethod
4881 def download_puzzle_input (day : int ) -> str :
82+ """
83+ Download the puzzle input for a specific day from Advent of Code.
84+
85+ Args:
86+ day (int): The day number (1-25) of the puzzle.
87+
88+ Returns:
89+ str: The puzzle input content.
90+
91+ Note:
92+ Requires valid session token and headers configuration.
93+ Year is determined from the project directory name.
94+ """
4995 session = File .get_session ()
5096 year = File .get_path ().split (os .sep )[- 1 ].split ("-" )[- 1 ]
5197
@@ -65,6 +111,20 @@ def download_puzzle_input(day: int) -> str:
65111
66112 @staticmethod
67113 def download_test_input (day : int , part_num : int ) -> str | None :
114+ """
115+ Download test input from the puzzle description for a specific day and part.
116+
117+ Args:
118+ day (int): The day number (1-25) of the puzzle.
119+ part_num (int): The puzzle part number (1 or 2).
120+
121+ Returns:
122+ str | None: The test input content if found, `None` if download fails.
123+
124+ Note:
125+ Extracts test input from code blocks in the puzzle description.
126+ Part number determines which code block to use.
127+ """
68128 session = File .get_session ()
69129 year = File .get_path ().split (os .sep )[- 1 ].split ("-" )[- 1 ]
70130
@@ -91,6 +151,20 @@ def download_test_input(day: int, part_num: int) -> str | None:
91151
92152 @staticmethod
93153 def add_day (day : int ) -> None :
154+ """
155+ Set up the file structure for a new puzzle day.
156+
157+ Creates solution file from template and downloads puzzle input when available.
158+ Waits for puzzle unlock time (5:00 UTC) if necessary.
159+
160+ Args:
161+ day (int): The day number (1-25) to set up.
162+
163+ Note:
164+ Creates following structure:
165+ - `solutions/dayXX.py` (from template)
166+ - `data/dayXX/puzzle_input.txt`
167+ """
94168 path = File .get_path ()
95169 solution = os .path .realpath (f"{ path } /solutions/day{ day :02} .py" )
96170 solution_path = Path (solution )
@@ -141,6 +215,19 @@ def add_day(day: int) -> None:
141215
142216 @staticmethod
143217 def add_test_input (day : int , part_num : int ) -> None :
218+ """
219+ Set up and download test input for a specific puzzle part.
220+
221+ Creates test input file and downloads content when available.
222+ Waits for puzzle unlock time (5:00 UTC) if necessary.
223+
224+ Args:
225+ day (int): The day number (1-25) of the puzzle.
226+ part_num (int): The puzzle part number (1 or 2).
227+
228+ Note:
229+ Creates file at: `data/dayXX/test_XX_input.txt`
230+ """
144231 path = File .get_path ()
145232 folder = os .path .realpath (f"{ path } /data/day{ day :02} " )
146233 folder_path = Path (folder )
@@ -179,6 +266,19 @@ def add_test_input(day: int, part_num: int) -> None:
179266
180267 @staticmethod
181268 def add_test_file (day : int ) -> None :
269+ """
270+ Create a test file for a specific puzzle day from template.
271+
272+ Args:
273+ day (int): The day number (1-25) to create test file for.
274+
275+ Note:
276+ Creates test file at: `tests/test_XX.py` using template from `templates/tests/sample.txt`
277+ Replaces placeholders in template with actual day number.
278+
279+ Raises:
280+ FileNotFoundError: If the template file is not found.
281+ """
182282 path = File .get_path ()
183283 test = os .path .realpath (f"{ path } /tests/test_{ day :02} .py" )
184284
@@ -197,7 +297,6 @@ def add_test_file(day: int) -> None:
197297 if content :
198298 logger .info ("Content loaded successfully" )
199299
200- # Replace placeholders with actual values
201300 content = content .format (day = day )
202301 with open (test , "w+" ) as f :
203302 f .write (content )
0 commit comments