mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-05-04 20:51:49 +02:00
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:
parent
16555424cc
commit
4f4e716de6
4 changed files with 41 additions and 8 deletions
26
dangerzone/args.py
Normal file
26
dangerzone/args.py
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue