fix: QOTD/WOTD freshness — pick within the freshest cohort, not the rotated pool
Both selectors ordered candidates least-recently-shown, then daily.seeded_order() ROTATED the whole list and took [0] — an arbitrary date-hashed item, undoing the ordering. Result: repeats (quote id 2 on 6/28+6/29; word "harmony" on 6/25+6/28), no guarantee a pool item is shown before it recurs. Fix: daily.freshest(rows) returns the freshest cohort only — every NEVER-shown item while any remain, else the oldest-shown group. quote/wotd _candidates use it; seeded_order now picks deterministically WITHIN that cohort. So every pool item is featured once before any repeat, then cycles oldest-first. Dropped the unused _NO_REPEAT_POOL window. Tests: no-repeat-until-exhausted (quote + wotd) + a freshest() unit test. 428 backend tests green. (Separate follow-up: expand the QOTD pool from 16 → 90+ vetted public-domain quotes for a longer no-repeat window.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+4
-6
@@ -25,7 +25,6 @@ from .localtime import local_today
|
||||
|
||||
DICT_BASE = "https://api.dictionaryapi.dev/api/v2/entries/en"
|
||||
_UA = {"User-Agent": "upbeatBytes/1.0 (+https://upbeatbytes.com)"}
|
||||
_NO_REPEAT_POOL = 60
|
||||
_TARGET_POOL = 30 # keep harvesting (a batch/day) until the pool reaches this
|
||||
_HARVEST_BATCH = 12
|
||||
_MIN_AUDIO_BYTES = 500
|
||||
@@ -222,11 +221,10 @@ def _candidates(conn: sqlite3.Connection, avoid: int | None = None) -> list[int]
|
||||
if featured:
|
||||
ids = [r[0] for r in featured]
|
||||
else:
|
||||
rows = conn.execute(
|
||||
"SELECT id FROM wotd_pool WHERE blocked=0 ORDER BY shown_at IS NOT NULL, shown_at, id LIMIT ?",
|
||||
(_NO_REPEAT_POOL,),
|
||||
).fetchall()
|
||||
ids = [r[0] for r in rows]
|
||||
# The freshest cohort only (never-shown, else the oldest-shown group) — picking
|
||||
# across the whole pool is what re-fed recent words day to day.
|
||||
rows = conn.execute("SELECT id, shown_at FROM wotd_pool WHERE blocked=0").fetchall()
|
||||
ids = daily.freshest(rows)
|
||||
if avoid is not None:
|
||||
ids = [i for i in ids if i != avoid] or ids
|
||||
return ids
|
||||
|
||||
Reference in New Issue
Block a user