opton to skip visual check in cutleft
This commit is contained in:
1 parent
5b7d4b611e
commit
2f8422f6d5
5 files changed
+112
-3
No files matched your search
@@ -384,6 +384,7 @@ def run(
|
||||
target: Path,
|
||||
*,
|
||||
fullpage: bool = False,
|
||||
no_visual_check: bool = False,
|
||||
marked: bool = False,
|
||||
) -> ExitCode:
|
||||
files = marked_copy_paths(workspace) if marked else _selected_files(workspace, target)
|
||||
@@ -392,6 +393,30 @@ def run(
|
||||
return ExitCode.SUCCESS
|
||||
workspace.cutleft_dir.mkdir(parents=True, exist_ok=True)
|
||||
_get_pdf_pages_cached.cache_clear()
|
||||
if fullpage and no_visual_check:
|
||||
had_errors = False
|
||||
for pdf_path in files:
|
||||
result = process_single_pdf(pdf_path, max_per_file=1)
|
||||
if result is None:
|
||||
mark_copy_error(
|
||||
workspace,
|
||||
pdf_path,
|
||||
"Échec de la conversion en pages entières",
|
||||
)
|
||||
had_errors = True
|
||||
continue
|
||||
try:
|
||||
save_results(result, pdf_path, workspace.cutleft_dir)
|
||||
clear_copy_error(workspace, pdf_path)
|
||||
except Exception as exc: # noqa: BLE001 - continue with remaining copies
|
||||
mark_copy_error(
|
||||
workspace,
|
||||
pdf_path,
|
||||
f"Échec de l’enregistrement : {exc}",
|
||||
)
|
||||
print(f"[Copie signalée] {pdf_path.name}: {exc}")
|
||||
had_errors = True
|
||||
return ExitCode.PARTIAL if had_errors else ExitCode.SUCCESS
|
||||
reviewer = ImageReviewer(
|
||||
files,
|
||||
workspace.cutleft_dir,
|
||||
@@ -410,6 +435,11 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
action="store_true",
|
||||
help="Use each complete page instead of cropping the label margin",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-visual-check",
|
||||
action="store_true",
|
||||
help="Save full pages without opening the visual reviewer (requires --fullpage)",
|
||||
)
|
||||
return parser
|
||||
|
||||
|
||||
@@ -418,7 +448,13 @@ def main(argv: Sequence[str] | None = None) -> int:
|
||||
|
||||
def handle(args: argparse.Namespace) -> ExitCode:
|
||||
workspace, target = workspace_from_target(args)
|
||||
return run(workspace, target, fullpage=args.fullpage, marked=args.marked)
|
||||
return run(
|
||||
workspace,
|
||||
target,
|
||||
fullpage=args.fullpage,
|
||||
no_visual_check=args.no_visual_check,
|
||||
marked=args.marked,
|
||||
)
|
||||
|
||||
return execute(parser, argv, handle)
|
||||
|
||||
|
||||
@@ -285,6 +285,13 @@ def build_workflow(show_personal_steps: bool) -> list[StepDefinition]:
|
||||
"--fullpage",
|
||||
help="Désactive la découpe habituelle de la marge gauche et transmet chaque page entière à la détection des labels.",
|
||||
),
|
||||
ArgumentSpec(
|
||||
"no_visual_check",
|
||||
"et ne pas vérifier visuellement",
|
||||
"bool",
|
||||
"--no-visual-check",
|
||||
help="Avec « Toujours utiliser la page entière », enregistre directement les images sans ouvrir la fenêtre de vérification.",
|
||||
),
|
||||
ArgumentSpec(
|
||||
"marked",
|
||||
"Copies signalées uniquement",
|
||||
|
||||
@@ -51,6 +51,24 @@ class GuiConvenienceTests(unittest.TestCase):
|
||||
start.assert_not_called()
|
||||
self.assertEqual(self.app.state_store.step(step.id)["status"], "success")
|
||||
|
||||
def test_cutleft_visual_check_option_is_below_and_off_by_default(self):
|
||||
step = self.app.step_by_id["cutleft"]
|
||||
self.app.current_step = step
|
||||
self.app._render_step()
|
||||
|
||||
labels = {
|
||||
child.cget("text"): child
|
||||
for child in self.app.form.winfo_children()
|
||||
if isinstance(child, ttk.Label)
|
||||
}
|
||||
fullpage = labels["Toujours utiliser la page entière ⓘ"]
|
||||
no_visual_check = labels["et ne pas vérifier visuellement ⓘ"]
|
||||
self.assertGreater(
|
||||
int(no_visual_check.grid_info()["row"]),
|
||||
int(fullpage.grid_info()["row"]),
|
||||
)
|
||||
self.assertFalse(self.app.arg_vars["no_visual_check"].get())
|
||||
|
||||
@staticmethod
|
||||
def _label_texts(widget):
|
||||
return [
|
||||
|
||||
+19
-1
@@ -566,7 +566,11 @@ class StandardCliTests(unittest.TestCase):
|
||||
"cutleft": (
|
||||
"cutleft",
|
||||
"default",
|
||||
{"target": evaluation, "fullpage": True},
|
||||
{
|
||||
"target": evaluation,
|
||||
"fullpage": True,
|
||||
"no_visual_check": True,
|
||||
},
|
||||
),
|
||||
"splitting_int": (
|
||||
"splitting",
|
||||
@@ -757,6 +761,20 @@ class StandardCliTests(unittest.TestCase):
|
||||
self.assertEqual(output_dir, evaluation / "Cutleft")
|
||||
self.assertEqual(reviewer.call_args.kwargs["default_max_per_file"], 1)
|
||||
|
||||
result = (Mock(), [Mock()], {})
|
||||
with patch.object(module, "ImageReviewer") as reviewer, patch.object(
|
||||
module, "process_single_pdf", return_value=result
|
||||
) as process, patch.object(module, "save_results") as save:
|
||||
self.assertEqual(
|
||||
module.main(
|
||||
[str(copy_pdf), "--fullpage", "--no-visual-check"]
|
||||
),
|
||||
0,
|
||||
)
|
||||
reviewer.assert_not_called()
|
||||
process.assert_called_once_with(copy_pdf, max_per_file=1)
|
||||
save.assert_called_once_with(result, copy_pdf, evaluation / "Cutleft")
|
||||
|
||||
def test_cutleft_atomic_save_removes_only_obsolete_copy_outputs(self) -> None:
|
||||
module = self.modules["cutleft"]
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
|
||||
@@ -4,7 +4,7 @@ import threading
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from queue import Queue
|
||||
from unittest.mock import Mock, patch
|
||||
from unittest.mock import Mock, call, patch
|
||||
|
||||
from PIL import Image
|
||||
|
||||
@@ -157,6 +157,36 @@ class MarkedCopiesTests(unittest.TestCase):
|
||||
self.assertEqual(cutleft.main([str(self.workspace.root), "--marked"]), expected)
|
||||
self.assertEqual(reviewer.call_args.args[0], [self.files[1]])
|
||||
|
||||
def test_fullpage_processes_every_copy_without_opening_the_reviewer(self):
|
||||
for path in self.files:
|
||||
mark_copy_error(self.workspace, path, "Review needed")
|
||||
image = Image.new("RGB", (8, 8), "white")
|
||||
result = (image, [image], {"columns_per_file": [1]})
|
||||
|
||||
with patch.object(
|
||||
cutleft, "process_single_pdf", side_effect=[result, None]
|
||||
) as process, patch.object(cutleft, "save_results") as save, patch.object(
|
||||
cutleft, "ImageReviewer"
|
||||
) as reviewer:
|
||||
status = cutleft.run(
|
||||
self.workspace,
|
||||
self.workspace.root,
|
||||
fullpage=True,
|
||||
no_visual_check=True,
|
||||
)
|
||||
|
||||
self.assertEqual(status, ExitCode.PARTIAL)
|
||||
reviewer.assert_not_called()
|
||||
self.assertEqual(
|
||||
process.call_args_list,
|
||||
[
|
||||
call(self.files[0], max_per_file=1),
|
||||
call(self.files[1], max_per_file=1),
|
||||
],
|
||||
)
|
||||
save.assert_called_once_with(result, self.files[0], self.workspace.cutleft_dir)
|
||||
self.assertEqual(set(copy_errors(self.workspace)), {"Copie02.pdf"})
|
||||
|
||||
|
||||
@unittest.skipUnless(os.environ.get("DISPLAY"), "Tk requires a display")
|
||||
class MarkedCopiesGuiTests(unittest.TestCase):
|
||||
|
||||
Reference in new issue
Block a user