dangerzone/dangerzone/document.py
deeplow 7222e7700c Always resolve relative paths in Document class
Make the Document class always resolve relative input/output file paths,
which are usually passed as arguments by users.

Previously, resolving relative filepaths was a job left to the
instantiators of the Document class. This was error-prone since this
conversion must happen in all the places where we instantiated the
Document class.
2022-10-27 15:20:35 +03:00

77 lines
2.4 KiB
Python

import os
import platform
import stat
import tempfile
from typing import Optional
import appdirs
from .errors import DocumentFilenameException
class Document:
"""Track the state of a single document.
The Document class is responsible for holding the state of a single
document, and validating its info.
"""
def __init__(self, input_filename: str = None) -> None:
self._input_filename: Optional[str] = None
self._output_filename: Optional[str] = None
if input_filename:
self.input_filename = input_filename
@staticmethod
def normalize_filename(filename: str) -> str:
return os.path.abspath(filename)
@staticmethod
def validate_input_filename(filename: str) -> None:
try:
open(filename, "rb")
except FileNotFoundError as e:
raise DocumentFilenameException(
"Input file not found: make sure you typed it correctly."
) from e
except PermissionError as e:
raise DocumentFilenameException(
"You don't have permission to open the input file."
) from e
@staticmethod
def validate_output_filename(filename: str) -> None:
if not filename.endswith(".pdf"):
raise DocumentFilenameException("Safe PDF filename must end in '.pdf'")
try:
with open(filename, "wb"):
pass
except PermissionError as e:
raise DocumentFilenameException("Safe PDF filename is not writable") from e
@property
def input_filename(self) -> str:
if self._input_filename is None:
raise DocumentFilenameException("Input filename has not been set yet.")
else:
return self._input_filename
@input_filename.setter
def input_filename(self, filename: str) -> None:
filename = self.normalize_filename(filename)
self.validate_input_filename(filename)
self._input_filename = filename
@property
def output_filename(self) -> str:
if self._output_filename is None:
raise DocumentFilenameException("Output filename has not been set yet.")
else:
return self._output_filename
@output_filename.setter
def output_filename(self, filename: str) -> None:
filename = self.normalize_filename(filename)
self.validate_output_filename(filename)
self._output_filename = filename