Commit Graph
5 Commits
Author SHA1 Message Date
Ben_Kosytorz 0439071f70 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.
2026-10-07 08:03:05 +02:00
Ben_Kosytorz 2c6e7b4d34 sorter: skip hidden trees (.broken) in the plan; treat extract_manifest.jsonl as run artifact 2026-10-06 16:52:55 +02:00
Ben_Kosytorz 86fcb3aecc extract stage + system-locked matching + provenance unit mode
- tools/extract_all.py: recursive extraction of all archives (incl.
  nested) into a plain-file tree; nested archives are deleted after
  successful extraction, plain files are hardlinked, failures go to
  .broken/, extract_manifest.jsonl records archive->dest->unit.
- sorter --provenance: classify each extraction directory once under
  the archive's name (files of one archive are one unit; inner
  structure kept), so loose STLs sort with their model set.
- matching discipline: a fuzzy match never leaves the file's system;
  system-less files need CROSS_SYSTEM_MIN (0.75) for a catalog unit,
  and a same-system faction jump below 0.75 is rejected. Fixes 40k
  files landing in Middle-earth/Blood Bowl/AoS buckets.
- speed for big trees: lru_cache on keyword matchers and pair scores,
  quick_ratio pruning; keywords: night lord, csm.
2026-10-05 08:09:22 +02:00
Ben_Kosytorz 4bbaefb45a Switch library hierarchy to GW webshop taxonomy
- warhammer_data.py: GW naming throughout - Space Marine chapters are
  their own factions under a 'Space Marines' group, systems match the
  shop (Age of Sigmar, The Horus Heresy, Other Games, The Old World,
  Middle-Earth), classes are GW shop categories (Battleline, Infantry,
  Vehicle, Walker, Flyer, Monster, Mounted, Hero, Titanic), group map
  extended to AoS grand alliances / Other Games / Old World / Middle-Earth
- gwshop.py: hierarchy remap - GW depth-4 paths are system/group/faction/
  class (the shop's last level is the class layer), depth-5 sources keep
  a subfaction before it; catalog snapshot regenerated accordingly
- sorter.py: catalog entry is hierarchy-authoritative (group, class, and
  faction when GW moved a unit or keyword tables are stale); generic GW
  branches ('Unit Type') and a Battleline default never degrade a
  confident keyword classification; whole-catalog retry when the faction
  pool has no confident match (handles units GW moved between factions);
  whole-catalog matching also runs when keyword classification found no
  faction; invalid (HTML) items never fuzzy-match; default catalog is
  now data/gwshop_catalog.json
- catalogue.py: --apply moves include the group layer, same structure
  as the sorter
- docs/SORTING.md: hierarchy rewritten to GW naming with examples
- tests: expectations updated to GW naming (chapters, unit types)
- verified live: 4/4 real files in the test batch now catalog-match,
  e.g. The Twin Lance -> 40k/Xenos Armies/T'au Empire/Epic Hero (GW's
  current placement) instead of the stale Drukhari keyword
2026-10-04 22:05:31 +02:00
Ben_Kosytorz cccf10a308 Sorter: fuzzysort files into the miniset-aligned library via hardlinks
- docs/SORTING.md: target hierarchy (game > faction group > faction >
  subfaction > class > unit, miniset.net naming), canonical-name policy,
  hardlink policy, unzip outlook
- data/library_catalog.json: canonical catalog (name/aliases/subfaction/class)
- dlphelper/sorter.py: inspect (zip via zipfile, 7z via 7z l), keyword
  classification incl. inner-name voting for hash-named archives, fuzzy
  matching (difflib), plan/apply split, hardlink preferred with copy
  fallback, append-only audit, existing targets skipped, run artifacts
  filtered, HTML-page detection for bad downloads
- sorter.py CLI (plan by default, --apply to act)
2026-10-04 21:17:52 +02:00