-
Notifications
You must be signed in to change notification settings - Fork 55
/
utils.py
65 lines (60 loc) · 2.04 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import errno
import os
import sys
import time
import tzlocal
from datetime import datetime
from itertools import cycle
from dateutil.tz import gettz
AOC_TZ = gettz("America/New_York")
def _ensure_intermediate_dirs(fname):
parent = os.path.dirname(os.path.expanduser(fname))
try:
os.makedirs(parent, exist_ok=True)
except TypeError:
# exist_ok not avail on Python 2
try:
os.makedirs(parent)
except (IOError, OSError) as err:
if err.errno != errno.EEXIST:
raise
def blocker(quiet=False, dt=0.1, datefmt="%-I:%M %p", until=None):
"""
This function just blocks until the next puzzle unlocks.
Pass `quiet=True` to disable the spinner etc.
Pass `dt` (seconds) to update the status txt more/less frequently.
Pass until=(year, day) to block until some other unlock date.
"""
aoc_now = datetime.now(tz=AOC_TZ)
month = 12
if until is not None:
year, day = until
else:
year = aoc_now.year
day = aoc_now.day + 1
if aoc_now.month < 12:
day = 1
elif aoc_now.day >= 25:
day = 1
year += 1
unlock = datetime(year, month, day, tzinfo=AOC_TZ)
if datetime.now(tz=AOC_TZ) > unlock:
# it should already be unlocked - nothing to do
return
spinner = cycle(r"\|/-")
localzone = tzlocal.get_localzone()
while datetime.now(tz=AOC_TZ) < unlock:
local_unlock = unlock.astimezone(tz=localzone)
msg = "{} Unlock day {} at {:%s} ({} remaining)" % datefmt
remaining = unlock - datetime.now(tz=AOC_TZ)
remaining = str(remaining).split(".")[0] # trim microseconds
if not quiet:
sys.stdout.write(msg.format(next(spinner), unlock.day, local_unlock, remaining))
sys.stdout.flush()
time.sleep(dt)
if not quiet:
sys.stdout.write("\r")
if not quiet:
# clears the "Unlock day" countdown line from the terminal
sys.stdout.write("\r".ljust(80) + "\n")
sys.stdout.flush()