sorter: drop non-warhammer game systems (default: Middle-Earth)
The collection is warhammer-only; everything else stays in _unsorted even when names match the catalog. The catalog snapshot keeps all systems - the filter is a sorter default (DROPPED_SYSTEMS, applied in load_catalog and after keyword classification), adjustable with --drop-system/--keep-system.
This commit is contained in:
+26
-2
@@ -32,9 +32,15 @@ UNSORTED = "_unsorted"
|
||||
UNCLASSIFIED_CLASS = "Unclassified"
|
||||
# A file whose system the keyword tables could not identify only gets a
|
||||
# catalog unit when the fuzzy hit is strong - otherwise it would wander
|
||||
# into other games' sections (Middle-earth, Blood Bowl, ...) on a guess.
|
||||
# into other games' sections (Blood Bowl, ...) on a guess.
|
||||
CROSS_SYSTEM_MIN = 0.75
|
||||
|
||||
# Game systems whose sections the sorter must never place into. The
|
||||
# collection is warhammer-only: everything else (Middle-earth proxies,
|
||||
# ...) stays in _unsorted even when a name matches the catalog. The
|
||||
# catalog snapshot itself keeps all systems; the filter lives here.
|
||||
DROPPED_SYSTEMS = frozenset({"Middle-Earth"})
|
||||
|
||||
# Weak acceptance tier: when nothing reached the normal threshold, a hit
|
||||
# at least this strong is accepted but flagged low confidence ("[w]" in
|
||||
# the plan, confidence field in the audit, listed in
|
||||
@@ -178,9 +184,14 @@ def classify_item(item: SortItem) -> None:
|
||||
# faction group layer (GW naming, shared with warhammer_data)
|
||||
|
||||
|
||||
def load_catalog(path: Path) -> list[dict]:
|
||||
def load_catalog(path: Path,
|
||||
dropped: frozenset[str] | None = DROPPED_SYSTEMS) -> list[dict]:
|
||||
"""Load catalog entries, dropping non-collected game systems by default
|
||||
(pass dropped=frozenset() to keep everything)."""
|
||||
data = json.loads(path.read_text(encoding="utf-8"))
|
||||
entries = data["entries"] if isinstance(data, dict) else data
|
||||
if dropped:
|
||||
entries = [e for e in entries if e.get("system") not in dropped]
|
||||
for e in entries:
|
||||
e["_clean"] = _clean_name(e["name"])
|
||||
e["_clean_aliases"] = [_clean_name(a) for a in e.get("aliases", [])]
|
||||
@@ -672,6 +683,17 @@ def _display_name(unit: str) -> str:
|
||||
# plan / apply
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _drop_dropped_system(item: SortItem) -> None:
|
||||
"""Dropped systems (see DROPPED_SYSTEMS) count as unclassified: the
|
||||
collection does not cover them, so their names must not place files
|
||||
into those sections. Called after keyword classification, before
|
||||
matching - the item can still be re-homed by other signals."""
|
||||
if item.system in DROPPED_SYSTEMS:
|
||||
item.system = "Unknown"
|
||||
item.group = item.faction = UNSORTED
|
||||
item.subfaction = None
|
||||
|
||||
|
||||
def sort_plan(
|
||||
files: list[Path],
|
||||
library: Path,
|
||||
@@ -716,6 +738,7 @@ def sort_plan(
|
||||
if unit_name is None:
|
||||
item = inspect(f)
|
||||
classify_item(item)
|
||||
_drop_dropped_system(item)
|
||||
match_catalog(item, catalog, threshold)
|
||||
if root is not None:
|
||||
# manual trees: let the real ancestor dir names compete
|
||||
@@ -741,6 +764,7 @@ def sort_plan(
|
||||
clean=_clean_name(unit_name), inner_names=listing,
|
||||
)
|
||||
classify_item(probe)
|
||||
_drop_dropped_system(probe)
|
||||
match_catalog(probe, catalog, threshold)
|
||||
fields = {k: getattr(probe, k) for k in (
|
||||
"system", "group", "faction", "subfaction", "klass",
|
||||
|
||||
Reference in New Issue
Block a user