Added debug output to exiftool
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
""" version info """
|
||||
|
||||
__version__ = "0.46.2"
|
||||
__version__ = "0.46.3"
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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"]:
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user