Added debug output to exiftool

This commit is contained in:
Rhet Turnbull
2022-02-22 06:40:25 -08:00
parent 5b66962ac1
commit 39ba17dd1c
15 changed files with 92 additions and 45 deletions

View File

@@ -1,3 +1,3 @@
""" version info """
__version__ = "0.46.2"
__version__ = "0.46.3"

View File

@@ -2298,6 +2298,9 @@ def help(ctx, topic, **kw):
"This only works if the Photos library being queried is the last-opened (default) library in Photos. "
"This feature is currently experimental. I don't know how well it will work on large query sets.",
)
@click.option(
"--debug", required=False, is_flag=True, default=False, hidden=OSXPHOTOS_HIDDEN
)
@DB_ARGUMENT
@click.pass_obj
@click.pass_context
@@ -2382,12 +2385,18 @@ def query(
query_eval,
query_function,
add_to_album,
debug,
):
"""Query the Photos database using 1 or more search options;
if more than one option is provided, they are treated as "AND"
(e.g. search for photos matching all options).
"""
global DEBUG
if debug:
DEBUG = True
osxphotos._set_debug(True)
# if no query terms, show help and return
# sanity check input args
nonexclusive = [

View File

@@ -103,9 +103,11 @@ class _ExifToolProc:
return cls.instance
def __init__(self, exiftool=None):
def __init__(self, exiftool=None, debug=False):
"""construct _ExifToolProc singleton object or return instance of already created object
exiftool: optional path to exiftool binary (if not provided, will search path to find it)"""
exiftool: optional path to exiftool binary (if not provided, will search path to find it)
debug: optional bool to enable debugging output
"""
if hasattr(self, "_process_running") and self._process_running:
# already running
@@ -115,9 +117,11 @@ class _ExifToolProc:
f"ignoring exiftool={exiftool}"
)
return
self.debug = debug
self._process_running = False
self._exiftool = exiftool or get_exiftool_path()
if self.debug:
logging.debug(f"exiftool={self._exiftool}")
self._start_proc()
@property
@@ -167,10 +171,17 @@ class _ExifToolProc:
self._process_running = True
EXIFTOOL_PROCESSES.append(self)
if self.debug:
logging.debug(
"exiftool process started: {self._process} {self._process_running}"
)
def _stop_proc(self):
"""stop the exiftool process if it's running, otherwise, do nothing"""
if self.debug:
logging.debug(f"exiftool process stopping: {self._process}")
if not self._process_running:
return
@@ -190,11 +201,16 @@ class _ExifToolProc:
del self._process
self._process_running = False
if self.debug:
logging.debug(f"exiftool process stopped: {self._process}")
class ExifTool:
"""Basic exiftool interface for reading and writing EXIF tags"""
def __init__(self, filepath, exiftool=None, overwrite=True, flags=None):
def __init__(
self, filepath, exiftool=None, overwrite=True, flags=None, debug=False
):
"""Create ExifTool object
Args:
@@ -202,6 +218,7 @@ class ExifTool:
exiftool: path to exiftool, if not specified will look in path
overwrite: if True, will overwrite image file without creating backup, default=False
flags: optional list of exiftool flags to prepend to exiftool command when writing metadata (e.g. -m or -F)
debug: if True, enables debug output
Returns:
ExifTool instance
@@ -209,6 +226,7 @@ class ExifTool:
self.file = filepath
self.overwrite = overwrite
self.flags = flags or []
self.debug = debug
self.data = {}
self.warning = None
self.error = None
@@ -342,6 +360,9 @@ class ExifTool:
+ b"-execute\n"
)
if self.debug:
logging.debug(f"running exiftool command: {command_str}")
# send the command
self._process.stdin.write(command_str)
self._process.stdin.flush()
@@ -362,6 +383,11 @@ class ExifTool:
error = "" if error == b"" else error.decode("utf-8")
self.warning = warning
self.error = error
if self.debug:
logging.debug(
f"run_commands: output={output[:-EXIFTOOL_STAYOPEN_EOF_LEN]}, warning={warning}, error={error}"
)
return output[:-EXIFTOOL_STAYOPEN_EOF_LEN], warning, error
@property
@@ -406,18 +432,25 @@ class ExifTool:
if normalized:
exifdict = {k.lower(): v for (k, v) in exifdict.items()}
if self.debug:
logging.debug(f"asdict: {exifdict}")
return exifdict
def json(self):
"""returns JSON string containing all EXIF tags and values from exiftool"""
json, _, _ = self.run_commands("-json")
json = unescape_str(json.decode("utf-8"))
if self.debug:
logging.debug(f"json: {json}")
return json
def _read_exif(self):
"""read exif data from file"""
data = self.asdict()
self.data = {k: v for k, v in data.items()}
if self.debug:
logging.debug(f"_read_exif: {self.data}")
def __str__(self):
return f"file: {self.file}\nexiftool: {self._exiftoolproc._exiftool}"
@@ -443,15 +476,17 @@ class ExifToolCaching(ExifTool):
_singletons = {}
def __new__(cls, filepath, exiftool=None):
def __new__(cls, filepath, exiftool=None, debug=False):
"""create new object or return instance of already created singleton"""
if filepath not in cls._singletons:
cls._singletons[filepath] = _ExifToolCaching(filepath, exiftool=exiftool)
cls._singletons[filepath] = _ExifToolCaching(
filepath, exiftool=exiftool, debug=debug
)
return cls._singletons[filepath]
class _ExifToolCaching(ExifTool):
def __init__(self, filepath, exiftool=None):
def __init__(self, filepath, exiftool=None, debug=False):
"""Create read-only ExifTool object that caches values
Args:
@@ -461,9 +496,12 @@ class _ExifToolCaching(ExifTool):
Returns:
ExifTool instance
"""
self.debug = debug
self._json_cache = None
self._asdict_cache = {}
super().__init__(filepath, exiftool=exiftool, overwrite=False, flags=None)
super().__init__(
filepath, exiftool=exiftool, overwrite=False, flags=None, debug=debug
)
def run_commands(self, *commands, no_file=False):
if commands[0] not in ["-json", "-ver"]:

View File

@@ -54,7 +54,7 @@ from .scoreinfo import ScoreInfo
from .searchinfo import SearchInfo
from .text_detection import detect_text
from .uti import get_preferred_uti_extension, get_uti_for_extension
from .utils import _debug, _get_resource_loc, list_directory
from .utils import _debug, _get_resource_loc, list_directory, _debug
__all__ = ["PhotoInfo", "PhotoInfoNone"]
@@ -1343,7 +1343,7 @@ class PhotoInfo:
try:
exiftool_path = self._db._exiftool_path or get_exiftool_path()
if self.path is not None and os.path.isfile(self.path):
exiftool = ExifToolCaching(self.path, exiftool=exiftool_path)
exiftool = ExifToolCaching(self.path, exiftool=exiftool_path, debug=_debug())
else:
exiftool = None
except FileNotFoundError: