Validate filename arguments through Click

Implement Click's callback interface and create validators for the
input/output filenames, using the logic from the Document class. This
way, we can catch user errors as early as possible.
This commit is contained in:
Alex Pyrgiotis 2022-10-11 15:52:49 +03:00 committed by Alex Pyrgiotis
parent 16555424cc
commit 4f4e716de6
4 changed files with 41 additions and 8 deletions

26
dangerzone/args.py Normal file
View file

@ -0,0 +1,26 @@
from typing import Optional
import click
from . import errors
from .document import Document
@errors.handle_document_errors
def validate_input_filename(
ctx: click.Context, param: str, value: Optional[str]
) -> Optional[str]:
if value is None:
return None
Document.validate_input_filename(value)
return value
@errors.handle_document_errors
def validate_output_filename(
ctx: click.Context, param: str, value: Optional[str]
) -> Optional[str]:
if value is None:
return None
Document.validate_output_filename(value)
return value

View file

@ -7,7 +7,7 @@ from typing import Optional
import click import click
from colorama import Back, Fore, Style from colorama import Back, Fore, Style
from . import container, errors from . import args, container, errors
from .container import convert from .container import convert
from .document import Document from .document import Document
from .global_common import GlobalCommon from .global_common import GlobalCommon
@ -20,9 +20,13 @@ def print_header(s: str) -> None:
@click.command() @click.command()
@click.option("--output-filename", help="Default is filename ending with -safe.pdf") @click.option(
"--output-filename",
callback=args.validate_output_filename,
help="Default is filename ending with -safe.pdf",
)
@click.option("--ocr-lang", help="Language to OCR, defaults to none") @click.option("--ocr-lang", help="Language to OCR, defaults to none")
@click.argument("filename", required=True) @click.argument("filename", required=True, callback=args.validate_input_filename)
@errors.handle_document_errors @errors.handle_document_errors
def cli_main( def cli_main(
output_filename: Optional[str], ocr_lang: Optional[str], filename: str output_filename: Optional[str], ocr_lang: Optional[str], filename: str

View file

@ -1,9 +1,12 @@
import functools import functools
import logging import logging
import sys import sys
from typing import Any, Callable, TypeVar, cast
import click import click
F = TypeVar("F", bound=Callable[..., Any])
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -11,11 +14,11 @@ class DocumentFilenameException(Exception):
"""Exception for document-related filename errors.""" """Exception for document-related filename errors."""
def handle_document_errors(func): def handle_document_errors(func: F) -> F:
"""Log document-related errors and exit gracefully.""" """Log document-related errors and exit gracefully."""
@functools.wraps(func) @functools.wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs): # type: ignore
try: try:
return func(*args, **kwargs) return func(*args, **kwargs)
except DocumentFilenameException as e: except DocumentFilenameException as e:
@ -26,4 +29,4 @@ def handle_document_errors(func):
click.echo(str(e)) click.echo(str(e))
exit(1) exit(1)
return wrapper return cast(F, wrapper)

View file

@ -10,7 +10,7 @@ import click
import colorama import colorama
from PySide2 import QtCore, QtGui, QtWidgets from PySide2 import QtCore, QtGui, QtWidgets
from .. import errors from .. import args, errors
from ..document import Document from ..document import Document
from ..global_common import GlobalCommon from ..global_common import GlobalCommon
from .common import GuiCommon from .common import GuiCommon
@ -50,7 +50,7 @@ class ApplicationWrapper(QtCore.QObject):
@click.command() @click.command()
@click.argument("filename", required=False) @click.argument("filename", required=False, callback=args.validate_input_filename)
@errors.handle_document_errors @errors.handle_document_errors
def gui_main(filename: Optional[str]) -> bool: def gui_main(filename: Optional[str]) -> bool:
setup_logging() setup_logging()