feat(export): 支持把原父目录名作为文件名前缀
新增 --prefix-parent:复制时把图片原来的父目录名拼到文件名前 (grease/abc.png -> grease_abc.png)。导出后目录只剩簇号,来源信息本来会丢失, 加前缀能留住它,人工核对时一眼看出某张图原本在哪个目录。 - 重名检查改为按**目标文件名**判重:加前缀后原本会撞车的文件可能就不撞了; 不加前缀而撞车时,报错会提示可以试试这个开关 - manifest.json 记下 prefix_parent,导出的 file 字段也用实际写出的文件名 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6e543660ce
commit
9b31473b27
@@ -4,6 +4,7 @@ import csv
|
||||
import filecmp
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -78,6 +79,67 @@ def test_exports_real_files_with_original_names(cluster_run, tmp_path, monkeypat
|
||||
assert filecmp.cmp(original, by_name[original.name], shallow=False)
|
||||
|
||||
|
||||
def test_prefix_parent_prepends_source_folder(cluster_run, tmp_path, monkeypatch):
|
||||
"""--prefix-parent 把原父目录名拼到文件名前,导出后仍能看出图来自哪个目录。"""
|
||||
_, work_dir, files = cluster_run
|
||||
data_root = tmp_path / "data"
|
||||
|
||||
assert run(["--work-dir", str(work_dir), "--data-root", str(data_root), "--prefix-parent"],
|
||||
monkeypatch) == 0
|
||||
|
||||
out = data_root / "film_r18_cluster_k2"
|
||||
exported = {p.name for p in out.rglob("*.png")}
|
||||
assert exported == {f"{f.parent.name}_{f.name}" for f in files}
|
||||
assert all(name.startswith(("grease_", "wrinkle_")) for name in exported)
|
||||
|
||||
# 仍然是真实文件、内容不变
|
||||
for path in out.rglob("*.png"):
|
||||
assert not path.is_symlink() and path.is_file()
|
||||
|
||||
manifest = json.loads((out / "manifest.json").read_text("utf-8"))
|
||||
assert manifest["prefix_parent"] is True
|
||||
for entries in manifest["files"].values():
|
||||
for entry in entries:
|
||||
source = Path(entry["source"])
|
||||
assert entry["file"] == f"{source.parent.name}_{source.name}"
|
||||
|
||||
|
||||
def test_without_prefix_names_are_unchanged(cluster_run, tmp_path, monkeypatch):
|
||||
_, work_dir, files = cluster_run
|
||||
data_root = tmp_path / "data"
|
||||
run(["--work-dir", str(work_dir), "--data-root", str(data_root)], monkeypatch)
|
||||
|
||||
exported = {p.name for p in (data_root / "film_r18_cluster_k2").rglob("*.png")}
|
||||
assert exported == {f.name for f in files}
|
||||
|
||||
|
||||
def test_prefix_parent_resolves_same_name_across_folders(cluster_run, tmp_path, monkeypatch):
|
||||
"""不同子目录的同名文件,不加前缀会撞车报错,加了前缀就能共存。"""
|
||||
source, work_dir, _ = cluster_run
|
||||
twin = source / "wrinkle" / "grease_0.png" # 与 grease/grease_0.png 同名
|
||||
Image.fromarray(np.zeros((20, 30, 3), dtype=np.uint8)).save(twin)
|
||||
|
||||
rows = list(csv.DictReader((work_dir / "assignments.csv").open(encoding="utf-8")))
|
||||
with (work_dir / "assignments.csv").open("w", newline="", encoding="utf-8") as handle:
|
||||
writer = csv.DictWriter(handle, fieldnames=list(rows[0]))
|
||||
writer.writeheader()
|
||||
writer.writerows(rows)
|
||||
writer.writerow({**rows[0], "path": str(twin), "cluster": rows[0]["cluster"]})
|
||||
|
||||
data_root = tmp_path / "data"
|
||||
argv = ["--work-dir", str(work_dir), "--data-root", str(data_root)]
|
||||
assert run(argv, monkeypatch) == 1 # 不加前缀:撞车
|
||||
assert run([*argv, "--prefix-parent"], monkeypatch) == 0 # 加前缀:共存
|
||||
|
||||
out = data_root / "film_r18_cluster_k2"
|
||||
assert {"grease_grease_0.png", "wrinkle_grease_0.png"} <= {p.name for p in out.rglob("*.png")}
|
||||
|
||||
|
||||
def test_destination_name_helper():
|
||||
assert ec.destination_name(Path("data/raw/film/grease/abc.png")) == "abc.png"
|
||||
assert ec.destination_name(Path("data/raw/film/grease/abc.png"), True) == "grease_abc.png"
|
||||
|
||||
|
||||
def test_cluster_dirs_are_numbered_from_zero(cluster_run, tmp_path, monkeypatch):
|
||||
_, work_dir, files = cluster_run
|
||||
data_root = tmp_path / "data"
|
||||
|
||||
Reference in New Issue
Block a user