sorter: outer file name wins over inner archive names in fuzzy match
Best-pool scoring used to always blend the archive's inner file names into the fuzzy score (0.95 discount), which dragged clean-named files into wrong units (e.g. 'Keeper of Secrets & Shalaxi Helbane.7z' ended in Orks/Boyz). Now the outer name decides when it scores >= threshold; inner names only vote as fallback (hash-named gofile archives rely on that). Also: url/failed-list run artifacts are excluded from sorting, and two plan-inspection helpers under tools/.
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Diff old vs new sorter plans by source path -> target."""
|
||||
import json
|
||||
import sys
|
||||
|
||||
changed = 0
|
||||
same = 0
|
||||
examples = []
|
||||
for n in (1, 2, 3):
|
||||
old = {p["source"]: p for p in json.load(open(f"/tmp/plan{n}.json"))}
|
||||
new = {p["source"]: p for p in json.load(open(f"/tmp/plan{n}b.json"))}
|
||||
for src, np in new.items():
|
||||
op = old.get(src)
|
||||
if not op:
|
||||
continue
|
||||
if op["target"] != np["target"] or op["kind"] != np["kind"]:
|
||||
changed += 1
|
||||
if len(examples) < 40:
|
||||
examples.append((n, op, np))
|
||||
else:
|
||||
same += 1
|
||||
print(f"same: {same} changed: {changed}")
|
||||
for n, op, np in examples:
|
||||
print(f"\n[{n}] {op['name']} (score {op['score']} -> {np['score']})")
|
||||
print(f" old: {op['target']}")
|
||||
print(f" new: {np['target']}")
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Summarize a sorter plan JSON: match kinds, top targets, oddities."""
|
||||
import json
|
||||
import sys
|
||||
from collections import Counter
|
||||
from pathlib import Path
|
||||
|
||||
plan = json.loads(Path(sys.argv[1]).read_text())
|
||||
print(f"files: {len(plan)}")
|
||||
print("kinds:", Counter(p["kind"] for p in plan))
|
||||
print("actions:", Counter(p.get("action", "?") for p in plan))
|
||||
# system breakdown
|
||||
print("systems:", Counter(p["system"] for p in plan).most_common(10))
|
||||
# top-level targets
|
||||
roots = Counter(str(Path(p["target"]).relative_to(
|
||||
Path(p["target"]).parents[3])) if len(Path(p["target"]).parents) > 3
|
||||
else p["target"] for p in plan)
|
||||
for root, n in roots.most_common(15):
|
||||
print(f" {n:5d} {root}")
|
||||
# anything with empty target?
|
||||
empties = [p for p in plan if not p.get("target")]
|
||||
print("empty targets:", len(empties))
|
||||
Reference in New Issue
Block a user