Skip to content

Commit 4faaf8c

Browse files
committed
Add calendar module
1 parent eed148e commit 4faaf8c

File tree

6 files changed

+58
-18
lines changed

6 files changed

+58
-18
lines changed

src/main/python/aoc/calendar.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from datetime import datetime
2+
3+
from dateutil import tz
4+
5+
AOC_TZ = tz.gettz("America/New_York")
6+
7+
8+
def get_now_aoc() -> datetime:
9+
return datetime.now(tz=AOC_TZ)
10+
11+
12+
def get_now_utc() -> datetime:
13+
return datetime.now(tz=tz.UTC)
14+
15+
16+
def valid_years() -> range:
17+
aoc_now = get_now_aoc()
18+
return range(2015, aoc_now.year + int(aoc_now.month == 12))
19+
20+
21+
def is_valid_year(year: int) -> bool:
22+
return year in valid_years()
23+
24+
25+
def get_days(year: int) -> int:
26+
if not is_valid_year(year):
27+
raise AssertionError
28+
return 25 if year < 2025 else 12
29+
30+
31+
def is_ranked_year(year: int) -> bool:
32+
if not is_valid_year(year):
33+
raise AssertionError
34+
return year < 2025
35+
36+
37+
def is_valid_day(year: int, day: int) -> bool:
38+
valid_day = is_valid_year(year) and day in range(1, get_days(year) + 1)
39+
aoc_now = get_now_aoc()
40+
if year == aoc_now.year:
41+
return valid_day and day <= aoc_now.day
42+
return valid_day

src/main/python/aoc/implementation_tables/implementation_tables.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
from pathlib import Path
77
from typing import IO
88

9+
import aoc.calendar as calendar
10+
911
if __name__ == "__main__":
1012
from config import Row # type:ignore[import-not-found]
1113
from config import config
@@ -28,7 +30,7 @@ def _build_row(days: list[str]) -> str:
2830

2931
def _print_year(year: int, rows: list[Row], f: IO[str]) -> None:
3032
log.debug("Adding %s", year)
31-
days = 12 if year >= 2025 else 25
33+
days = calendar.get_days(year)
3234
print("| " + _build_row([str(day) for day in range(1, days + 1)]), file=f)
3335
print("| ---" + _build_row(["---" for day in range(1, days + 1)]), file=f)
3436
for row in rows:

src/main/python/aoc/runner/listener.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
from abc import abstractmethod
66
from collections.abc import Iterable
77
from collections.abc import Iterator
8-
from datetime import datetime
98
from typing import NamedTuple
109
from typing import cast
1110

12-
from dateutil import tz
11+
from aoc import calendar
1312
from junitparser import Attr
1413
from junitparser import Error
1514
from junitparser import Failure
@@ -270,7 +269,7 @@ def _format_time(self, time: int, timeout: float) -> str:
270269
class JUnitXmlListener(Listener):
271270
def __init__(self) -> None:
272271
self.suite = TestSuite("Advent of Code")
273-
self.suite.timestamp = datetime.now(tz.UTC)
272+
self.suite.timestamp = calendar.get_now_utc()
274273
self.suite.hostname = socket.gethostname()
275274
TestCase.year = IntAttr("year")
276275
TestCase.day = IntAttr("day")

src/main/python/aoc/runner/runner.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@
3030
from collections.abc import Callable
3131
from collections.abc import Generator
3232
from contextlib import contextmanager
33-
from datetime import datetime
3433
from pathlib import Path
3534
from typing import Any
3635

3736
import pebble
38-
from dateutil.tz import gettz
37+
38+
from aoc import calendar
3939

4040
from . import Result
4141
from .aocd import AocdHelper
@@ -55,7 +55,6 @@
5555
from .rust import Rust
5656

5757
DEFAULT_TIMEOUT = config.default_timeout
58-
AOC_TZ = gettz("America/New_York")
5958
log = logging.getLogger(__name__)
6059
all_plugins = OrderedDict(
6160
{
@@ -70,8 +69,7 @@
7069

7170

7271
def main() -> None:
73-
aoc_now = datetime.now(tz=AOC_TZ)
74-
years = range(2015, aoc_now.year + int(aoc_now.month == 12))
72+
years = calendar.valid_years()
7573
days = range(1, 26)
7674
users = AocdHelper.load_users()
7775
parser = ArgumentParser(description="AoC runner")
@@ -102,7 +100,7 @@ def main() -> None:
102100
nargs="+",
103101
choices=days,
104102
default=days,
105-
help="AoC days to run. Runs all 1-25 by default.",
103+
help="AoC days to run. Runs all days by default.",
106104
)
107105
parser.add_argument(
108106
"-u",
@@ -274,11 +272,10 @@ def run_for(
274272
autosubmit: bool,
275273
listener: Listener,
276274
) -> int:
277-
aoc_now = datetime.now(tz=AOC_TZ)
278275
it = itertools.product(years, days, plugins.items(), datasets)
279276
n_incorrect = 0
280277
for year, day, plugin, user_id in it:
281-
if year == aoc_now.year and day > aoc_now.day:
278+
if not calendar.is_valid_day(year, day):
282279
continue
283280
token = datasets[user_id]
284281
puzzle = Puzzle.create(token, year, day, autosubmit)

src/main/python/aoc/stats/input.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import re
44
from datetime import timedelta
55

6+
from aoc import calendar
67
from tqdm import tqdm
78

89
from . import LeaderBoard
@@ -86,7 +87,7 @@ def _scrape_leaderboard(year: int) -> dict[int, LeaderBoard]:
8687
continue
8788
splits = line.split()
8889
day = int(splits[0])
89-
if year >= 2025:
90+
if not calendar.is_ranked_year(year):
9091
time_first = html.unescape(splits[1]) if splits[1] != "-" else None
9192
rank_first = None
9293
score_first = None
@@ -112,7 +113,7 @@ def _scrape_leaderboard(year: int) -> dict[int, LeaderBoard]:
112113

113114

114115
def get_leaderboard(year: int) -> dict[int, LeaderBoard]:
115-
if year < 2025:
116+
if calendar.is_ranked_year(year):
116117
try:
117118
return _get_aocd_leaderboard(year)
118119
except AttributeError:

src/main/python/aoc/stats/stats.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
import datetime
21
import sys
32

4-
import dateutil
3+
from aoc import calendar
54

65
from . import input as stats_input
76
from . import output as stats_output
87

98

109
def main(args: list[str]) -> None:
11-
now = datetime.datetime.now(tz=dateutil.tz.gettz("America/New_York"))
1210
if len(args) == 0:
13-
if now.month == 12:
11+
now = calendar.get_now_aoc()
12+
if calendar.is_valid_year(now.year):
1413
print_year(now.year)
1514
elif args[0] == "all":
1615
print_summary()

0 commit comments

Comments
 (0)