From 476c94407f008f77a092392a0f2e6c4e5184444b Mon Sep 17 00:00:00 2001 From: Rhet Turnbull Date: Fri, 14 Jan 2022 18:31:50 -0800 Subject: [PATCH] More refactoring of export code, #462 --- osxphotos/photoexporter.py | 288 +++++++++++++++++++++---------------- 1 file changed, 167 insertions(+), 121 deletions(-) diff --git a/osxphotos/photoexporter.py b/osxphotos/photoexporter.py index 9e0e79fe..5c377681 100644 --- a/osxphotos/photoexporter.py +++ b/osxphotos/photoexporter.py @@ -13,7 +13,7 @@ import pathlib import re import tempfile from collections import namedtuple # pylint: disable=syntax-error -from typing import TYPE_CHECKING, Optional, Callable +from typing import TYPE_CHECKING, Callable, List, Optional import photoscript from mako.template import Template @@ -34,7 +34,7 @@ from ._constants import ( from ._version import __version__ from .datetime_utils import datetime_tz_to_utc from .exiftool import ExifTool -from .export_db import ExportDBNoOp, ExportDB_ABC +from .export_db import ExportDB_ABC, ExportDBNoOp from .fileutil import FileUtil from .photokit import ( PHOTOS_VERSION_CURRENT, @@ -715,125 +715,29 @@ class PhotoExporter: exif_files = all_results.exported # TODO: remove duplicative code from below - if exiftool and update and exif_files: - for exported_file in exif_files: - files_are_different = False - old_data = export_db.get_exifdata_for_file(exported_file) - if old_data is not None: - old_data = json.loads(old_data)[0] - current_data = json.loads( - self._exiftool_json_sidecar( - use_albums_as_keywords=use_albums_as_keywords, - use_persons_as_keywords=use_persons_as_keywords, - keyword_template=keyword_template, - description_template=description_template, - ignore_date_modified=ignore_date_modified, - merge_exif_keywords=merge_exif_keywords, - merge_exif_persons=merge_exif_persons, - persons=persons, - location=location, - replace_keywords=replace_keywords, - strip=strip, - ) - )[0] - if old_data != current_data: - files_are_different = True - - if old_data is None or files_are_different: - # didn't have old data, assume we need to write it - # or files were different - verbose(f"Writing metadata with exiftool for {exported_file}") - if not dry_run: - warning_, error_ = self._write_exif_data( - exported_file, - use_albums_as_keywords=use_albums_as_keywords, - use_persons_as_keywords=use_persons_as_keywords, - keyword_template=keyword_template, - description_template=description_template, - ignore_date_modified=ignore_date_modified, - flags=exiftool_flags, - merge_exif_keywords=merge_exif_keywords, - merge_exif_persons=merge_exif_persons, - persons=persons, - location=location, - replace_keywords=replace_keywords, - strip=strip, - ) - if warning_: - all_results.exiftool_warning.append( - (exported_file, warning_) - ) - if error_: - all_results.exiftool_error.append((exported_file, error_)) - all_results.error.append((exported_file, error_)) - - export_db.set_exifdata_for_file( - exported_file, - self._exiftool_json_sidecar( - use_albums_as_keywords=use_albums_as_keywords, - use_persons_as_keywords=use_persons_as_keywords, - keyword_template=keyword_template, - description_template=description_template, - ignore_date_modified=ignore_date_modified, - merge_exif_keywords=merge_exif_keywords, - merge_exif_persons=merge_exif_persons, - persons=persons, - location=location, - replace_keywords=replace_keywords, - strip=strip, - ), - ) - export_db.set_stat_exif_for_file( - exported_file, fileutil.file_sig(exported_file) - ) - all_results.exif_updated.append(exported_file) - else: - verbose(f"Skipped up to date exiftool metadata for {exported_file}") - elif exiftool and exif_files: - for exported_file in exif_files: - verbose(f"Writing metadata with exiftool for {exported_file}") - if not dry_run: - warning_, error_ = self._write_exif_data( - exported_file, - use_albums_as_keywords=use_albums_as_keywords, - use_persons_as_keywords=use_persons_as_keywords, - keyword_template=keyword_template, - description_template=description_template, - ignore_date_modified=ignore_date_modified, - flags=exiftool_flags, - merge_exif_keywords=merge_exif_keywords, - merge_exif_persons=merge_exif_persons, - persons=persons, - location=location, - replace_keywords=replace_keywords, - strip=strip, - ) - if warning_: - all_results.exiftool_warning.append((exported_file, warning_)) - if error_: - all_results.exiftool_error.append((exported_file, error_)) - all_results.error.append((exported_file, error_)) - - export_db.set_exifdata_for_file( - exported_file, - self._exiftool_json_sidecar( - use_albums_as_keywords=use_albums_as_keywords, - use_persons_as_keywords=use_persons_as_keywords, - keyword_template=keyword_template, - description_template=description_template, - ignore_date_modified=ignore_date_modified, - merge_exif_keywords=merge_exif_keywords, - merge_exif_persons=merge_exif_persons, - persons=persons, - location=location, - replace_keywords=replace_keywords, - strip=strip, - ), - ) - export_db.set_stat_exif_for_file( - exported_file, fileutil.file_sig(exported_file) - ) - all_results.exif_updated.append(exported_file) + for exported_file in exif_files: + results = self._write_exif_metadata_to_files( + exported_file=exported_file, + exiftool=exiftool, + update=update, + exiftool_flags=exiftool_flags, + use_albums_as_keywords=use_albums_as_keywords, + use_persons_as_keywords=use_persons_as_keywords, + keyword_template=keyword_template, + description_template=description_template, + ignore_date_modified=ignore_date_modified, + merge_exif_keywords=merge_exif_keywords, + merge_exif_persons=merge_exif_persons, + persons=persons, + location=location, + replace_keywords=replace_keywords, + strip=strip, + fileutil=fileutil, + export_db=export_db, + dry_run=dry_run, + verbose=verbose, + ) + all_results += results if touch_file: for exif_file in all_results.exif_updated: @@ -1448,6 +1352,148 @@ class PhotoExporter: sidecar_xmp_skipped=sidecar_xmp_files_skipped, ) + def _write_exif_metadata_to_files( + self, + exported_file: str, + exiftool: bool, + update: bool, + exiftool_flags: Optional[List[str]], + use_albums_as_keywords: bool, + use_persons_as_keywords: bool, + keyword_template: Optional[str], + description_template: Optional[str], + ignore_date_modified: bool, + merge_exif_keywords: bool, + merge_exif_persons: bool, + persons: bool, + location: bool, + replace_keywords: bool, + strip: bool, + fileutil: FileUtil, + export_db: ExportDB_ABC, + dry_run: bool, + verbose: Optional[Callable], + ) -> ExportResults: + results = ExportResults() + if exiftool and update and exported_file: + for exported_file in [exported_file]: + files_are_different = False + old_data = export_db.get_exifdata_for_file(exported_file) + if old_data is not None: + old_data = json.loads(old_data)[0] + current_data = json.loads( + self._exiftool_json_sidecar( + use_albums_as_keywords=use_albums_as_keywords, + use_persons_as_keywords=use_persons_as_keywords, + keyword_template=keyword_template, + description_template=description_template, + ignore_date_modified=ignore_date_modified, + merge_exif_keywords=merge_exif_keywords, + merge_exif_persons=merge_exif_persons, + persons=persons, + location=location, + replace_keywords=replace_keywords, + strip=strip, + ) + )[0] + if old_data != current_data: + files_are_different = True + + if old_data is None or files_are_different: + # didn't have old data, assume we need to write it + # or files were different + verbose(f"Writing metadata with exiftool for {exported_file}") + if not dry_run: + warning_, error_ = self._write_exif_data( + exported_file, + use_albums_as_keywords=use_albums_as_keywords, + use_persons_as_keywords=use_persons_as_keywords, + keyword_template=keyword_template, + description_template=description_template, + ignore_date_modified=ignore_date_modified, + flags=exiftool_flags, + merge_exif_keywords=merge_exif_keywords, + merge_exif_persons=merge_exif_persons, + persons=persons, + location=location, + replace_keywords=replace_keywords, + strip=strip, + ) + if warning_: + results.exiftool_warning.append((exported_file, warning_)) + if error_: + results.exiftool_error.append((exported_file, error_)) + results.error.append((exported_file, error_)) + + export_db.set_exifdata_for_file( + exported_file, + self._exiftool_json_sidecar( + use_albums_as_keywords=use_albums_as_keywords, + use_persons_as_keywords=use_persons_as_keywords, + keyword_template=keyword_template, + description_template=description_template, + ignore_date_modified=ignore_date_modified, + merge_exif_keywords=merge_exif_keywords, + merge_exif_persons=merge_exif_persons, + persons=persons, + location=location, + replace_keywords=replace_keywords, + strip=strip, + ), + ) + export_db.set_stat_exif_for_file( + exported_file, fileutil.file_sig(exported_file) + ) + results.exif_updated.append(exported_file) + else: + verbose(f"Skipped up to date exiftool metadata for {exported_file}") + elif exiftool and exported_file: + for exported_file in [exported_file]: + verbose(f"Writing metadata with exiftool for {exported_file}") + if not dry_run: + warning_, error_ = self._write_exif_data( + exported_file, + use_albums_as_keywords=use_albums_as_keywords, + use_persons_as_keywords=use_persons_as_keywords, + keyword_template=keyword_template, + description_template=description_template, + ignore_date_modified=ignore_date_modified, + flags=exiftool_flags, + merge_exif_keywords=merge_exif_keywords, + merge_exif_persons=merge_exif_persons, + persons=persons, + location=location, + replace_keywords=replace_keywords, + strip=strip, + ) + if warning_: + results.exiftool_warning.append((exported_file, warning_)) + if error_: + results.exiftool_error.append((exported_file, error_)) + results.error.append((exported_file, error_)) + + export_db.set_exifdata_for_file( + exported_file, + self._exiftool_json_sidecar( + use_albums_as_keywords=use_albums_as_keywords, + use_persons_as_keywords=use_persons_as_keywords, + keyword_template=keyword_template, + description_template=description_template, + ignore_date_modified=ignore_date_modified, + merge_exif_keywords=merge_exif_keywords, + merge_exif_persons=merge_exif_persons, + persons=persons, + location=location, + replace_keywords=replace_keywords, + strip=strip, + ), + ) + export_db.set_stat_exif_for_file( + exported_file, fileutil.file_sig(exported_file) + ) + results.exif_updated.append(exported_file) + return results + def _write_exif_data( self, filepath,