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
@@ -21,6 +21,7 @@ from copienator import (
|
||||
target_parser,
|
||||
workspace_from_target,
|
||||
)
|
||||
from copienator.copy_errors import clear_copy_error, mark_copy_error, marked_copy_paths
|
||||
from copienator.platform import open_path
|
||||
from copienator.utils import natural_key, read_all_labels
|
||||
|
||||
@@ -307,6 +308,7 @@ class ImageViewer:
|
||||
self.forward_stack = []
|
||||
self.current_pil_image = None
|
||||
self.failed = False
|
||||
self.skipped_copies = set()
|
||||
|
||||
from config import PLOTTING_KB
|
||||
|
||||
@@ -314,6 +316,7 @@ class ImageViewer:
|
||||
self.root.bind(PLOTTING_KB["OK"], self.on_enter)
|
||||
self.root.bind(PLOTTING_KB["previous"], self.on_previous)
|
||||
self.root.bind("P", self.on_previous)
|
||||
self.root.bind("!", self.on_skip)
|
||||
self.root.bind(PLOTTING_KB["edit"], self.on_edit)
|
||||
self.root.bind(PLOTTING_KB["open pdf"], self.on_open_pdf)
|
||||
self.root.bind(PLOTTING_KB["open original pdf"], self.on_open_ori_pdf)
|
||||
@@ -345,6 +348,10 @@ class ImageViewer:
|
||||
self.root.quit()
|
||||
return
|
||||
|
||||
if metadata["copie"] in self.skipped_copies:
|
||||
self.root.after(0, self.poll_queue)
|
||||
return
|
||||
|
||||
# Check if we switched to a new "Copie" group
|
||||
if self.active_copie_name != metadata["copie"]:
|
||||
self.save_current_batch() # Write previous group to disk
|
||||
@@ -361,8 +368,21 @@ class ImageViewer:
|
||||
"""Writes the accumulated data to the main JSON file."""
|
||||
if self.active_copie_name and self.accumulated_results:
|
||||
main_json_path = self.base_dir / "Copies" / f"{self.active_copie_name}.json"
|
||||
accepted = [item[2] for item in self.history
|
||||
if item[3] == self.active_copie_name]
|
||||
parts = {item["part"] for item in accepted}
|
||||
expected = (set(range(1, len(accepted[-1]["schema"]["columns_per_file"]) + 1))
|
||||
if accepted else set())
|
||||
if not expected or parts != expected:
|
||||
mark_copy_error(self.workspace, main_json_path.with_suffix(".pdf"),
|
||||
"Vérification des labels incomplète", source="plotting")
|
||||
self.failed = True
|
||||
self.accumulated_results = None
|
||||
return
|
||||
print(f"Writing aggregated result to {main_json_path}")
|
||||
atomic_write_json(main_json_path, self.accumulated_results)
|
||||
clear_copy_error(self.workspace, main_json_path.with_suffix(".pdf"),
|
||||
source="plotting")
|
||||
self.accumulated_results = None
|
||||
|
||||
def close(self):
|
||||
@@ -467,6 +487,21 @@ class ImageViewer:
|
||||
self.is_viewing = False
|
||||
self.label.config(image="", text="Loading next...")
|
||||
|
||||
def on_skip(self, _event=None):
|
||||
if not self.is_viewing:
|
||||
return
|
||||
copie = self.current_meta["copie"]
|
||||
mark_copy_error(self.workspace, self.workspace.copies_dir / f"{copie}.pdf",
|
||||
"Problème repéré pendant la vérification des labels", source="plotting")
|
||||
self.failed = True
|
||||
self.skipped_copies.add(copie)
|
||||
# Discard accepted parts of this copy without replacing its previous result.
|
||||
self.accumulated_results = None
|
||||
self.history = [item for item in self.history if item[3] != copie]
|
||||
self.forward_stack = [item for item in self.forward_stack if item[2]["copie"] != copie]
|
||||
self.is_viewing = False
|
||||
self.label.config(image="", text="Copie signalée. Chargement de la suivante…")
|
||||
|
||||
def on_open_pdf(self, event):
|
||||
if self.is_viewing and self.current_json_path:
|
||||
a = self.current_json_path.stem.split('_')[0] + ".pdf"
|
||||
@@ -530,17 +565,24 @@ def _selected_images(workspace: EvaluationWorkspace, target: Path) -> list[Path]
|
||||
return sorted(workspace.cutleft_dir.glob("*.jpg"), key=natural_key)
|
||||
|
||||
|
||||
def run(workspace: EvaluationWorkspace, target: Path) -> ExitCode:
|
||||
def run(workspace: EvaluationWorkspace, target: Path, *, marked: bool = False) -> ExitCode:
|
||||
workspace.require_files("labels")
|
||||
all_labels = read_all_labels(workspace.root)
|
||||
files_to_process = _selected_images(workspace, target)
|
||||
if marked:
|
||||
copies = marked_copy_paths(workspace)
|
||||
if not copies:
|
||||
print("No flagged copies to verify.")
|
||||
return ExitCode.SUCCESS
|
||||
files_to_process = [image for pdf in copies for image in _selected_images(workspace, pdf)]
|
||||
else:
|
||||
files_to_process = _selected_images(workspace, target)
|
||||
if not files_to_process:
|
||||
print(f"No Cutleft images found for {target}")
|
||||
return ExitCode.PARTIAL
|
||||
|
||||
print(
|
||||
"o to open pdf, O original pdf, e to edit part, p to go back, "
|
||||
"i to open the statement, click for coordinates"
|
||||
"i to open the statement, ! to flag and skip the copy, click for coordinates"
|
||||
)
|
||||
input_queue = queue.Queue(maxsize=5)
|
||||
worker = threading.Thread(
|
||||
@@ -556,7 +598,9 @@ def run(workspace: EvaluationWorkspace, target: Path) -> ExitCode:
|
||||
|
||||
|
||||
def build_parser() -> argparse.ArgumentParser:
|
||||
return target_parser("Interactively verify detected label coordinates")
|
||||
parser = target_parser("Interactively verify detected label coordinates")
|
||||
parser.add_argument("--marked", action="store_true", help="Verify only copies with remaining flags")
|
||||
return parser
|
||||
|
||||
|
||||
def main(argv: Sequence[str] | None = None) -> int:
|
||||
@@ -564,7 +608,7 @@ def main(argv: Sequence[str] | None = None) -> int:
|
||||
|
||||
def handle(args: argparse.Namespace) -> ExitCode:
|
||||
workspace, target = workspace_from_target(args)
|
||||
return run(workspace, target)
|
||||
return run(workspace, target, marked=args.marked)
|
||||
|
||||
return execute(parser, argv, handle)
|
||||
|
||||
|
||||
Reference in new issue
Block a user