Remove-from-catalog: a third durable curation store
Titles that aren't games (misread box art, out-of-scope items) can now be removed outright: a danger button in the catalog's edit panel posts /api/remove-title, which drops the line's matches rows (veto'd ones too — removal is the human explicitly discarding the line), records the decision photo-scoped in data/title_removals.json, and replays titles.json. Every rebuild filters removed sightings after edits and before dedupe, so re-extraction cannot resurrect them; undo by deleting the record from the store. The three stores now share one scoped-record parser and recorder. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
This commit is contained in:
@@ -24,6 +24,7 @@ from bggpipe.extract import (
|
||||
replay_titles,
|
||||
run_extract,
|
||||
)
|
||||
from bggpipe.normalize import normalize_title
|
||||
|
||||
|
||||
def _write_image(path, size=(400, 300), fmt="JPEG", color=(200, 30, 30)):
|
||||
@@ -234,6 +235,22 @@ def test_edits_chain_and_target_photos():
|
||||
assert entries[1] == _entry("Wiz-War", "b.jpg") # untargeted copy untouched
|
||||
|
||||
|
||||
def test_removals_filter_rebuilds_photo_scoped():
|
||||
from bggpipe.extract import apply_title_removals
|
||||
|
||||
entries = [
|
||||
_entry("Not A Game", "a.jpg"),
|
||||
_entry("Not A Game", "b.jpg"),
|
||||
_entry("Catan", "a.jpg"),
|
||||
]
|
||||
removals = [{"norm": normalize_title("Not A Game"), "photos": {"a.jpg"}}]
|
||||
kept = apply_title_removals(entries, removals)
|
||||
assert [(e["title_raw"], e["source_photos"]) for e in kept] == [
|
||||
("Not A Game", ["b.jpg"]), # other sighting untouched
|
||||
("Catan", ["a.jpg"]),
|
||||
]
|
||||
|
||||
|
||||
def test_stores_roundtrip_and_replay_from_raw(tmp_path):
|
||||
cfg = Config(data_dir=tmp_path / "data", photos_dir=tmp_path / "photos")
|
||||
raw = cfg.extract_raw_dir
|
||||
|
||||
Reference in New Issue
Block a user