Removed debug code from exiftool, fixed #641
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
""" version info """
|
||||
|
||||
__version__ = "0.46.3"
|
||||
__version__ = "0.46.4"
|
||||
|
||||
@@ -105,10 +105,9 @@ class _ExifToolProc:
|
||||
|
||||
return cls.instance
|
||||
|
||||
def __init__(self, exiftool=None, debug=False):
|
||||
def __init__(self, exiftool=None):
|
||||
"""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)
|
||||
debug: optional bool to enable debugging output
|
||||
"""
|
||||
|
||||
if hasattr(self, "_process_running") and self._process_running:
|
||||
@@ -119,11 +118,8 @@ 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
|
||||
@@ -177,17 +173,10 @@ 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
|
||||
|
||||
@@ -207,16 +196,11 @@ 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, debug=False
|
||||
):
|
||||
def __init__(self, filepath, exiftool=None, overwrite=True, flags=None):
|
||||
"""Create ExifTool object
|
||||
|
||||
Args:
|
||||
@@ -224,7 +208,6 @@ 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
|
||||
@@ -232,13 +215,12 @@ class ExifTool:
|
||||
self.file = filepath
|
||||
self.overwrite = overwrite
|
||||
self.flags = flags or []
|
||||
self.debug = debug
|
||||
self.data = {}
|
||||
self.warning = None
|
||||
self.error = None
|
||||
# if running as a context manager, self._context_mgr will be True
|
||||
self._context_mgr = False
|
||||
self._exiftoolproc = _ExifToolProc(exiftool=exiftool, debug=debug)
|
||||
self._exiftoolproc = _ExifToolProc(exiftool=exiftool)
|
||||
self._read_exif()
|
||||
|
||||
@property
|
||||
@@ -366,9 +348,6 @@ 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()
|
||||
@@ -389,10 +368,6 @@ 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
|
||||
|
||||
@@ -417,8 +392,6 @@ class ExifTool:
|
||||
"""
|
||||
json_str, _, _ = self.run_commands("-json")
|
||||
if not json_str:
|
||||
if self.debug:
|
||||
logging.debug(f"empty json_str")
|
||||
return dict()
|
||||
json_str = unescape_str(json_str.decode("utf-8"))
|
||||
|
||||
@@ -427,8 +400,7 @@ class ExifTool:
|
||||
except Exception as e:
|
||||
# will fail with some commands, e.g --ext AVI which produces
|
||||
# 'No file with specified extension' instead of json
|
||||
if self.debug:
|
||||
logging.debug(f"json.loads error {e}")
|
||||
logging.warning(f"error loading json returned by exiftool: {e} {json_str}")
|
||||
return dict()
|
||||
exifdict = exifdict[0]
|
||||
if not tag_groups:
|
||||
@@ -442,25 +414,18 @@ 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}"
|
||||
@@ -486,17 +451,15 @@ class ExifToolCaching(ExifTool):
|
||||
|
||||
_singletons = {}
|
||||
|
||||
def __new__(cls, filepath, exiftool=None, debug=False):
|
||||
def __new__(cls, filepath, exiftool=None):
|
||||
"""create new object or return instance of already created singleton"""
|
||||
if filepath not in cls._singletons:
|
||||
cls._singletons[filepath] = _ExifToolCaching(
|
||||
filepath, exiftool=exiftool, debug=debug
|
||||
)
|
||||
cls._singletons[filepath] = _ExifToolCaching(filepath, exiftool=exiftool)
|
||||
return cls._singletons[filepath]
|
||||
|
||||
|
||||
class _ExifToolCaching(ExifTool):
|
||||
def __init__(self, filepath, exiftool=None, debug=False):
|
||||
def __init__(self, filepath, exiftool=None):
|
||||
"""Create read-only ExifTool object that caches values
|
||||
|
||||
Args:
|
||||
@@ -506,12 +469,9 @@ 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, debug=debug
|
||||
)
|
||||
super().__init__(filepath, exiftool=exiftool, overwrite=False, flags=None)
|
||||
|
||||
def run_commands(self, *commands, no_file=False):
|
||||
if commands[0] not in ["-json", "-ver"]:
|
||||
|
||||
@@ -560,11 +560,15 @@ class PhotoExporter:
|
||||
touch_results = []
|
||||
for touch_file in set(touch_files):
|
||||
ts = int(self.photo.date.timestamp())
|
||||
stat = os.stat(touch_file)
|
||||
if stat.st_mtime != ts:
|
||||
if not options.dry_run:
|
||||
try:
|
||||
stat = os.stat(touch_file)
|
||||
if stat.st_mtime != ts:
|
||||
fileutil.utime(touch_file, (ts, ts))
|
||||
touch_results.append(touch_file)
|
||||
touch_results.append(touch_file)
|
||||
except FileNotFoundError as e:
|
||||
# ignore errors if in dry_run as file may not be present
|
||||
if not options.dry_run:
|
||||
raise e from e
|
||||
return ExportResults(touched=touch_results)
|
||||
|
||||
def _get_edited_filename(self, original_filename):
|
||||
@@ -669,8 +673,8 @@ class PhotoExporter:
|
||||
|
||||
if file_record.export_options != options.bit_flags:
|
||||
# exporting with different set of options (e.g. exiftool), should update
|
||||
# need to check this before exiftool in case exiftool options are different
|
||||
# and export database is missing; this will always be True if database is missing
|
||||
# need to check this before exiftool in case exiftool options are different
|
||||
# and export database is missing; this will always be True if database is missing
|
||||
# as it'll be None and bit_flags will be an int
|
||||
return True
|
||||
|
||||
|
||||
@@ -588,7 +588,7 @@ class PhotoInfo:
|
||||
@property
|
||||
def ismissing(self):
|
||||
"""returns true if photo is missing from disk (which means it's not been downloaded from iCloud)
|
||||
|
||||
|
||||
NOTE: the photos.db database uses an asynchrounous write-ahead log so changes in Photos
|
||||
do not immediately get written to disk. In particular, I've noticed that downloading
|
||||
an image from the cloud does not force the database to be updated until something else
|
||||
@@ -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, debug=_debug())
|
||||
exiftool = ExifToolCaching(self.path, exiftool=exiftool_path)
|
||||
else:
|
||||
exiftool = None
|
||||
except FileNotFoundError:
|
||||
|
||||
Reference in New Issue
Block a user