Skip to content

Commit cc7d5d5

Browse files
authored
Merge pull request #306 from DigitalSlideArchive/redact-all
Add an --all flag to fail if all images cannot be redacted
2 parents a180e4b + 48e75c7 commit cc7d5d5

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

imagedephi/main.py

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@
7070
click.option(
7171
"-r", "--recursive", is_flag=True, help="Apply the command to images in subdirectories"
7272
),
73+
click.option(
74+
"-a",
75+
"--require-all",
76+
"--all",
77+
is_flag=True,
78+
help="Return a failure code if not all images can be redacted; do not"
79+
" redact any images in this case.",
80+
),
7381
]
7482

7583

@@ -79,7 +87,9 @@ def global_options(func):
7987
return func
8088

8189

82-
def _check_parent_params(ctx, profile, override_rules, recursive, quiet, verbose, log_file):
90+
def _check_parent_params(
91+
ctx, profile, override_rules, recursive, require_all, quiet, verbose, log_file
92+
):
8393
params = {
8494
"override_rules": (
8595
ctx.parent.params["override_rules"]
@@ -92,6 +102,9 @@ def _check_parent_params(ctx, profile, override_rules, recursive, quiet, verbose
92102
"recursive": (
93103
ctx.parent.params["recursive"] if ctx.parent.params["recursive"] else recursive
94104
),
105+
"require_all": (
106+
ctx.parent.params["require_all"] if ctx.parent.params["require_all"] else require_all
107+
),
95108
"quiet": ctx.parent.params["quiet"] if ctx.parent.params["quiet"] else quiet,
96109
"verbose": ctx.parent.params["verbose"] if ctx.parent.params["verbose"] else verbose,
97110
"log_file": ctx.parent.params["log_file"] if ctx.parent.params["log_file"] else log_file,
@@ -129,6 +142,7 @@ def imagedephi(
129142
override_rules: Path | None,
130143
profile: str,
131144
recursive: bool,
145+
require_all: bool,
132146
) -> None:
133147
"""Redact microscopy whole slide images."""
134148
if verbose or quiet or log_file:
@@ -173,6 +187,7 @@ def run(
173187
override_rules: Path | None,
174188
profile: str,
175189
recursive: bool,
190+
require_all: bool,
176191
rename: bool,
177192
quiet,
178193
verbose,
@@ -182,7 +197,9 @@ def run(
182197
file_list: Path,
183198
):
184199
"""Perform the redaction of images."""
185-
params = _check_parent_params(ctx, profile, override_rules, recursive, quiet, verbose, log_file)
200+
params = _check_parent_params(
201+
ctx, profile, override_rules, recursive, require_all, quiet, verbose, log_file
202+
)
186203
if params["verbose"] or params["quiet"] or params["log_file"]:
187204
set_logging_config(params["verbose"], params["quiet"], params["log_file"])
188205
file_contents = {}
@@ -193,6 +210,7 @@ def run(
193210
# cf_rename will only be checked if rename is false so default should be false.
194211
cf_rename: bool = False
195212
cf_recursive: bool = False
213+
cf_require_all: bool = False
196214
cf_index: int = 1
197215
if command_file:
198216
if command_file.suffix not in [".yaml", ".yml"]:
@@ -221,6 +239,9 @@ def run(
221239
cf_recursive = (
222240
bool(file_contents.get("recursive")) if "recursive" in file_contents else False
223241
)
242+
cf_require_all = (
243+
bool(file_contents.get("require_all")) if "require_all" in file_contents else False
244+
)
224245
cf_index = int(file_contents["index"]) if "index" in file_contents else 1
225246
if not input_paths and not command_inputs:
226247
raise click.BadParameter("At least one input path must be provided.")
@@ -246,6 +267,16 @@ def run(
246267
output_dir = Path.cwd()
247268
if not input_paths and not file_input_paths:
248269
raise click.BadParameter("At least one input path must be provided.")
270+
if params["require_all"] or cf_require_all:
271+
plan = show_redaction_plan(
272+
input_paths or command_inputs or file_input_paths,
273+
override_rules=params["override_rules"] or cf_override_rules,
274+
recursive=bool(params["recursive"] or cf_recursive),
275+
profile=params["profile"] or cf_profile,
276+
require_all=True,
277+
)
278+
if plan.missing_rules: # type: ignore
279+
sys.exit(1)
249280
redact_images(
250281
input_paths or command_inputs or file_input_paths,
251282
output_dir or command_output,
@@ -282,14 +313,17 @@ def plan(
282313
profile: str,
283314
override_rules: Path | None,
284315
recursive: bool,
316+
require_all: bool,
285317
quiet,
286318
verbose,
287319
log_file,
288320
command_file: Path,
289321
file_list: Path,
290322
) -> None:
291323
"""Print the redaction plan for images."""
292-
params = _check_parent_params(ctx, profile, override_rules, recursive, quiet, verbose, log_file)
324+
params = _check_parent_params(
325+
ctx, profile, override_rules, recursive, require_all, quiet, verbose, log_file
326+
)
293327

294328
# Even if the user doesn't use the verbose flag, ensure logging level is set to
295329
# show info output of this command.
@@ -331,14 +365,14 @@ def plan(
331365
if not input_paths and not file_input_paths:
332366
raise click.BadParameter("At least one input path must be provided.")
333367

334-
show_redaction_plan(
368+
plan = show_redaction_plan(
335369
input_paths or command_inputs or file_input_paths,
336370
override_rules=(
337371
params["override_rules"] or command_params.get("override_rules")
338372
if "override_rules" in command_params
339373
else None
340374
),
341-
recursive=(
375+
recursive=bool(
342376
params["recursive"] or command_params.get("recursive")
343377
if "recursive" in command_params
344378
else False
@@ -349,6 +383,8 @@ def plan(
349383
else None
350384
),
351385
)
386+
if require_all and plan.missing_rules: # type: ignore
387+
sys.exit(1)
352388

353389

354390
@imagedephi.command

imagedephi/redact/redact.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,8 @@ def _sort_data(data):
370370
def show_redaction_plan(
371371
input_paths: list[Path],
372372
override_rules: Path | None = None,
373-
recursive=False,
373+
recursive: bool = False,
374+
require_all: bool = False,
374375
profile="",
375376
limit: int | None = None,
376377
offset: int | None = None,
@@ -425,6 +426,8 @@ def _create_redaction_plan_report():
425426
redaction_plan_report.update(redaction_plan.report_plan()) # type: ignore
426427
if not redaction_plan.is_comprehensive():
427428
missing_rules = True
429+
if require_all:
430+
break
428431

429432
if not update:
430433
global redaction_plan_report

0 commit comments

Comments
 (0)