Allow signaling issues in label verification
This commit is contained in:
1 parent
3754c0c11a
commit
9925362352
21 files changed
+1347
-36
No files matched your search
+40
-14
@@ -1,4 +1,4 @@
|
||||
"""Persistent copy flags shared by page splitting, margin review and the GUI."""
|
||||
"""Persistent per-step copy flags shared by repair commands and the GUI."""
|
||||
from pathlib import Path
|
||||
|
||||
from copienator import CliError, EvaluationWorkspace, atomic_update_json, read_json
|
||||
@@ -8,31 +8,57 @@ def _path(workspace: EvaluationWorkspace) -> Path:
|
||||
return workspace.metadata_dir / "copy_errors.json"
|
||||
|
||||
|
||||
def _validate(value) -> dict[str, str]:
|
||||
if not isinstance(value, dict) or any(
|
||||
not isinstance(name, str) or not isinstance(reason, str)
|
||||
or "/" in name or "\\" in name or Path(name).suffix.casefold() != ".pdf"
|
||||
for name, reason in value.items()
|
||||
):
|
||||
raise CliError("Invalid copy_errors.json: expected PDF filenames and error descriptions")
|
||||
return value
|
||||
def _validate(value) -> dict[str, dict[str, str]]:
|
||||
if not isinstance(value, dict):
|
||||
raise CliError("Invalid copy_errors.json: expected PDF filenames and step flags")
|
||||
normalized = {}
|
||||
for name, flags in value.items():
|
||||
if (not isinstance(name, str) or "/" in name or "\\" in name
|
||||
or Path(name).suffix.casefold() != ".pdf"):
|
||||
raise CliError("Invalid copy_errors.json: invalid PDF filename")
|
||||
# Older versions only reported errors from margin cropping.
|
||||
if isinstance(flags, str):
|
||||
flags = {"cutleft": flags}
|
||||
if (not isinstance(flags, dict) or not flags
|
||||
or any(step not in {"cutleft", "plotting"} or not isinstance(reason, str)
|
||||
for step, reason in flags.items())):
|
||||
raise CliError("Invalid copy_errors.json: invalid step flags")
|
||||
normalized[name] = dict(flags)
|
||||
return normalized
|
||||
|
||||
|
||||
def copy_errors(workspace: EvaluationWorkspace) -> dict[str, str]:
|
||||
return _validate(read_json(_path(workspace), default={}))
|
||||
"""Return a summary per copy, preserving the existing GUI-facing API."""
|
||||
flags = _validate(read_json(_path(workspace), default={}))
|
||||
return {name: "; ".join(reasons.values()) for name, reasons in flags.items()}
|
||||
|
||||
|
||||
def mark_copy_error(workspace: EvaluationWorkspace, pdf: Path, reason: str) -> None:
|
||||
def mark_copy_error(workspace: EvaluationWorkspace, pdf: Path, reason: str,
|
||||
*, source: str = "cutleft") -> None:
|
||||
if source not in {"cutleft", "plotting"}:
|
||||
raise ValueError(f"Unknown copy flag source: {source}")
|
||||
def update(errors):
|
||||
_validate(errors)[pdf.name] = reason
|
||||
normalized = _validate(errors)
|
||||
normalized.setdefault(pdf.name, {})[source] = reason
|
||||
errors.clear()
|
||||
errors.update(normalized)
|
||||
atomic_update_json(_path(workspace), update, default_factory=dict)
|
||||
|
||||
|
||||
def clear_copy_error(workspace: EvaluationWorkspace, pdf: Path) -> None:
|
||||
def clear_copy_error(workspace: EvaluationWorkspace, pdf: Path,
|
||||
*, source: str = "cutleft") -> None:
|
||||
if source not in {"cutleft", "plotting"}:
|
||||
raise ValueError(f"Unknown copy flag source: {source}")
|
||||
if not _path(workspace).exists():
|
||||
return
|
||||
def update(errors):
|
||||
_validate(errors).pop(pdf.name, None)
|
||||
normalized = _validate(errors)
|
||||
flags = normalized.get(pdf.name, {})
|
||||
flags.pop(source, None)
|
||||
if not flags:
|
||||
normalized.pop(pdf.name, None)
|
||||
errors.clear()
|
||||
errors.update(normalized)
|
||||
atomic_update_json(_path(workspace), update, default_factory=dict)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user