mirror of
https://github.com/kuhyx/steam-backlog-enforcer.git
synced 2026-11-10 19:27:04 +01:00
LeetCode bonus: a day paid from banked credits counts (earned_time 0.17.0)
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d2c4ea7ace
commit
55cf19fae4
@ -13,10 +13,10 @@ dependencies = [
|
||||
# transitively via howlongtobeatpy and websockets was undeclared — both
|
||||
# are declared here so a clean install imports the package.
|
||||
"aiohttp==3.14.5",
|
||||
"websockets==17.2",
|
||||
"websockets==17.3",
|
||||
# The earner registry (gaming budget terms); stdlib-only, so the root
|
||||
# daemon imports it from the desktop user's site-packages.
|
||||
"earned-time @ git+https://github.com/kuhyx/utils@earned-time-v0.16.0#subdirectory=earned_time",
|
||||
"earned-time @ git+https://github.com/kuhyx/utils@earned-time-v0.17.0#subdirectory=earned_time",
|
||||
# The shared /proc game scan and the signed leisure facts (shadow budget,
|
||||
# contract C4); stdlib-only, imported by root from the user site like
|
||||
# earned-time.
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
aiohttp==3.14.5
|
||||
bandit==1.9.4
|
||||
codespell==2.4.3
|
||||
coverage==7.16.2
|
||||
earned-time @ git+https://github.com/kuhyx/utils@earned-time-v0.16.0#subdirectory=earned_time
|
||||
coverage==7.17.0
|
||||
earned-time @ git+https://github.com/kuhyx/utils@earned-time-v0.17.0#subdirectory=earned_time
|
||||
howlongtobeatpy==1.0.24
|
||||
leisure-watch @ git+https://github.com/kuhyx/leisure-watch@leisure-watch-v0.2.1
|
||||
mcp==2.3.0
|
||||
@ -19,6 +19,6 @@ pytest-sugar==1.1.1
|
||||
pytest-timeout==2.4.0
|
||||
pytest-xdist==3.8.0
|
||||
requests==2.34.2
|
||||
ruff==0.17.1
|
||||
ruff==0.17.2
|
||||
types-requests==2.33.0.20261006
|
||||
websockets==17.2
|
||||
websockets==17.3
|
||||
|
||||
@ -20,10 +20,9 @@ rather than a permission problem -- this daemon runs as root, so it already has
|
||||
strictly more access than the endpoint does. Both carry the same staleness (see
|
||||
below); the fallback is not a fresher source.
|
||||
|
||||
**Known staleness, accepted.** leetcode-guard only writes credits from its lock
|
||||
window's poll loop, so a *voluntary extra* solve made after the day is settled
|
||||
never reaches the ledger and earns nothing. The bonus tracks what the day's
|
||||
gate run recorded.
|
||||
**Staleness.** leetcode-guard's one-minute harvester credits a solve within
|
||||
about a minute, even with no lock window up. A day paid ahead from banked
|
||||
credits counts like a solve (``earned_time`` >= 0.17.0, kuhy 2026-10-23).
|
||||
|
||||
Reading and verifying the ledger itself lives in
|
||||
:mod:`steam_backlog_enforcer._leetcode_ledger`; this module owns the two
|
||||
@ -60,7 +59,8 @@ def _fetch_leetcode_today(url: str) -> bool:
|
||||
url: The status endpoint, e.g. ``http://127.0.0.1:8771/api/status``.
|
||||
|
||||
Returns:
|
||||
Whether an accepted submission is recorded for today.
|
||||
Whether an accepted submission is recorded for today, or today was
|
||||
paid from banked credits.
|
||||
|
||||
Raises:
|
||||
OSError: The endpoint could not be reached.
|
||||
@ -73,7 +73,9 @@ def _fetch_leetcode_today(url: str) -> bool:
|
||||
# The server answered, but said it could not look. That is not a "no".
|
||||
msg = f"leetcode-guard could not check: {block.get('reason', 'no reason')}"
|
||||
raise ValueError(msg)
|
||||
return bool(block["solved_today"])
|
||||
# A day paid ahead from banked credits earns the hour like a solve
|
||||
# (leetcode-guard >= 2026-10-23); an older server has no such field.
|
||||
return bool(block["solved_today"]) or bool(block.get("settled_by_credit"))
|
||||
|
||||
|
||||
def leetcode_solved_today(config: Config) -> bool | None:
|
||||
|
||||
@ -140,3 +140,24 @@ class TestFetchLeetcodeToday:
|
||||
)
|
||||
is True
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("block", "expected"),
|
||||
[
|
||||
({"solved_today": False, "settled_by_credit": True}, True),
|
||||
({"solved_today": False, "settled_by_credit": False}, False),
|
||||
# A leetcode-guard older than the field: the solve alone decides.
|
||||
({"solved_today": False}, False),
|
||||
],
|
||||
)
|
||||
def test_a_day_paid_from_banked_credit_counts(
|
||||
self, block: dict[str, bool], *, expected: bool
|
||||
) -> None:
|
||||
"""Working ahead earns the hour (kuhy, 2026-10-23)."""
|
||||
payload = json.dumps({"leetcode": {"checked": True, **block}}).encode()
|
||||
with patch(f"{_API}.http.client.HTTPConnection") as conn:
|
||||
resp = conn.return_value.getresponse.return_value
|
||||
resp.status = 200
|
||||
resp.read.return_value = payload
|
||||
url = "http://127.0.0.1:8771/api/status"
|
||||
assert _leetcode_bonus._fetch_leetcode_today(url) is expected
|
||||
|
||||
Loading…
Reference in New Issue
Block a user