api: dedup ghost history rows (int vs string ep_id); normalize ep_id on write

This commit is contained in:
jozamudi committed 2026-08-23 21:29:01 +00:00
1 parent 8f57593002
commit d39ee838ff
2 files changed
+32 -4

No files matched your search

+17 -2
View File
@@ -125,9 +125,17 @@ HIST_DIR = Path(os.environ.get("ANIWEB_DATA", Path(__file__).parent / "data")) /
def _load_hist(user: str):
try:
return json.loads((HIST_DIR / f"{user}.json").read_text())
entries = json.loads((HIST_DIR / f"{user}.json").read_text())
except (FileNotFoundError, json.JSONDecodeError):
return []
# ponytail: dedup legacy ghost rows — the same episode was stored with ep_id
# as int AND string; keep the newest per (slug_id, str(ep_id))
best = {}
for e in entries:
k = (str(e.get("slug_id")), str(e.get("ep_id")))
if e.get("t", 0) >= best.get(k, {"t": 0})["t"]:
best[k] = e
return sorted(best.values(), key=lambda e: e.get("t", 0), reverse=True)
def _save_hist(user: str, entries):
@@ -162,11 +170,18 @@ def api_history_delete(request: Request, slug_id: str, ep_id: str):
def api_history_post(entry: dict = Body(...), request: Request = None):
if "ep_id" not in entry:
raise HTTPException(422, "ep_id required")
# normalize: ghost rows were born when ep_id arrived as str against an
# int row (or vice versa) — int() makes the stored type stable
try:
entry["ep_id"] = int(entry["ep_id"])
except (TypeError, ValueError):
raise HTTPException(422, "ep_id must be an integer")
entry["t"] = time.time()
u = request.state.user
entries = _load_hist(u)
for i, e in enumerate(entries):
if e.get("slug_id") == entry.get("slug_id") and e.get("ep_id") == entry.get("ep_id"):
# loose str() match: merge onto a legacy ghost row of the other type
if e.get("slug_id") == entry.get("slug_id") and str(e.get("ep_id")) == str(entry["ep_id"]):
entries[i] = {**e, **entry}
break
else: