mirror of
https://github.com/kuhyx/steam-backlog-enforcer.git
synced 2026-11-10 19:27:04 +01:00
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Has been cancelled
Tests / test (push) Has been cancelled
Tests / web-coverage (push) Has been cancelled
repo-contract / repo contract (push) Has been cancelled
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
50 lines
1.9 KiB
Python
50 lines
1.9 KiB
Python
"""Reading leetcode-guard's ledger for today's accepted submissions.
|
|
|
|
Reading and verifying is the shared reader in ``earned_time`` (kuhyx/utils),
|
|
the same one screen-locker uses; ``test_leetcode_ledger.py`` pins its HMAC
|
|
canonicalisation to a fixed vector. gatelock itself is not imported: it pulls
|
|
in tkinter, and this daemon runs headless as root.
|
|
|
|
Since earned_time 0.18.0 only today's signed ``leetcode`` ``charge`` (the day
|
|
paid in full) earns. A bare ``credit`` earns only when ``gate_off`` is true (a
|
|
free or sick day), and a ``seen`` entry is first-run seeding worth zero.
|
|
|
|
The solve time is ``detail["submitted_at"]``, LeetCode's own timestamp, not the
|
|
entry's ``day``: ``day`` is stamped by the *harvesting* run, so a problem
|
|
solved at 23:50 and harvested the next morning carries the next day's key.
|
|
|
|
Every unreadable state returns ``None``, never ``False``. "Cannot check" is not
|
|
"not solved", and only one of the two is worth waking the user about.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
from pathlib import Path
|
|
from typing import Final
|
|
|
|
import earned_time
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# The key every locker signs its state with. Root-owned, world-readable.
|
|
HMAC_KEY_FILE: Final = Path("/etc/workout-locker/hmac.key")
|
|
|
|
|
|
def read_ledger_solved_today(path: Path, *, gate_off: bool = False) -> bool | None:
|
|
"""Read leetcode-guard's ledger: was today paid in full?
|
|
|
|
Args:
|
|
path: The ledger file.
|
|
gate_off: Whether the gate stands down today (asked live). Only then
|
|
does one verified solve earn; otherwise only the signed charge
|
|
that covers the day's whole price does (earned_time 0.18.0).
|
|
|
|
Returns:
|
|
True or False when the ledger could be read and verified, ``None`` when
|
|
it could not -- which is never "nothing was solved".
|
|
"""
|
|
return earned_time.done_today(
|
|
earned_time.LEETCODE, path, HMAC_KEY_FILE, gate_off=gate_off
|
|
)
|