From 78d494ff2c4d8a299f8d9c90a7a27fd33a102e25 Mon Sep 17 00:00:00 2001 From: Pablo 'merKur' Kohan Date: Mon, 17 Aug 2020 21:43:57 +0300 Subject: [PATCH] Touch file upon image date - Issue #194 --- osxphotos/__main__.py | 12 ++++++++++++ osxphotos/fileutil.py | 14 ++++++++++++++ osxphotos/photoinfo/_photoinfo_export.py | 10 ++++++++++ 3 files changed, 36 insertions(+) diff --git a/osxphotos/__main__.py b/osxphotos/__main__.py index 3d9e2052..8a609305 100644 --- a/osxphotos/__main__.py +++ b/osxphotos/__main__.py @@ -1121,6 +1121,11 @@ def query( help="Hardlink files instead of copying them. " "Cannot be used with --exiftool which creates copies of the files with embedded EXIF data.", ) +@click.option( + "--touch-file", + is_flag=True, + help="Sets the file's modification time upon photo date.", +) @click.option( "--overwrite", is_flag=True, @@ -1299,6 +1304,7 @@ def export( update, dry_run, export_as_hardlink, + touch_file, overwrite, export_by_date, skip_edited, @@ -1564,6 +1570,7 @@ def export( export_db=export_db, fileutil=fileutil, dry_run=dry_run, + touch_file=touch_file, edited_suffix=edited_suffix, ) results_exported.extend(results.exported) @@ -1601,6 +1608,7 @@ def export( export_db=export_db, fileutil=fileutil, dry_run=dry_run, + touch_file=touch_file, edited_suffix=edited_suffix, ) results_exported.extend(results.exported) @@ -2073,6 +2081,7 @@ def export_photo( export_db=None, fileutil=FileUtil, dry_run=None, + touch_file=None, edited_suffix="_edited", ): """ Helper function for export that does the actual export @@ -2101,6 +2110,7 @@ def export_photo( export_db: export database instance compatible with ExportDB_ABC fileutil: file util class compatible with FileUtilABC dry_run: boolean; if True, doesn't actually export or update any files + touch_file: boolean; sets file's modification time upon photo date Returns: list of path(s) of exported photo or None if photo was missing @@ -2178,6 +2188,7 @@ def export_photo( export_db=export_db, fileutil=fileutil, dry_run=dry_run, + touch_file=touch_file, ) results_exported.extend(export_results.exported) @@ -2234,6 +2245,7 @@ def export_photo( export_db=export_db, fileutil=fileutil, dry_run=dry_run, + touch_file=touch_file, ) results_exported.extend(export_results_edited.exported) diff --git a/osxphotos/fileutil.py b/osxphotos/fileutil.py index 440a031e..187d7ac8 100644 --- a/osxphotos/fileutil.py +++ b/osxphotos/fileutil.py @@ -27,6 +27,11 @@ class FileUtilABC(ABC): def unlink(cls, dest): pass + @classmethod + @abstractmethod + def utime(cls, path, times): + pass + @classmethod @abstractmethod def cmp_sig(cls, file1, file2): @@ -103,6 +108,11 @@ class FileUtilMacOS(FileUtilABC): else: os.unlink(filepath) + @classmethod + def utime(cls, path, times): + """ Set the access and modified time of path. """ + os.utime(path, times) + @classmethod def cmp_sig(cls, f1, s2): """Compare file f1 to signature s2. @@ -172,6 +182,10 @@ class FileUtilNoOp(FileUtil): def unlink(cls, dest): cls.verbose(f"unlink: {dest}") + @classmethod + def utime(cls, path, times): + cls.verbose(f"utime: {path}, {times}") + @classmethod def file_sig(cls, file1): cls.verbose(f"file_sig: {file1}") diff --git a/osxphotos/photoinfo/_photoinfo_export.py b/osxphotos/photoinfo/_photoinfo_export.py index 72284f66..2bb7660b 100644 --- a/osxphotos/photoinfo/_photoinfo_export.py +++ b/osxphotos/photoinfo/_photoinfo_export.py @@ -305,6 +305,7 @@ def export2( export_db=None, fileutil=FileUtil, dry_run=False, + touch_file=False, ): """ export photo, like export but with update and dry_run options dest: must be valid destination path or exception raised @@ -347,6 +348,7 @@ def export2( for getting/setting data related to exported files to compare update state fileutil: (FileUtilABC); class that conforms to FileUtilABC with various file utilities dry_run: (boolean, default=False); set to True to run in "dry run" mode + touch_file: (boolean, default=False); if True, sets file's modification time upon photo date Returns: ExportResults namedtuple with fields: exported, new, updated, skipped where each field is a list of file paths @@ -558,6 +560,7 @@ def export2( no_xattr, export_as_hardlink, exiftool, + touch_file, fileutil, ) exported_files = results.exported @@ -583,6 +586,7 @@ def export2( no_xattr, export_as_hardlink, exiftool, + touch_file, fileutil, ) exported_files.extend(results.exported) @@ -608,6 +612,7 @@ def export2( no_xattr, export_as_hardlink, exiftool, + touch_file, fileutil, ) exported_files.extend(results.exported) @@ -793,6 +798,7 @@ def _export_photo( no_xattr, export_as_hardlink, exiftool, + touch_file, fileutil=FileUtil, ): """ Helper function for export() @@ -810,6 +816,7 @@ def _export_photo( no_xattr: don't copy extended attributes export_as_hardlink: bool exiftool: bool + touch_file: bool fileutil: FileUtil class that conforms to fileutil.FileUtilABC Returns: @@ -865,6 +872,9 @@ def _export_photo( fileutil.hardlink(src, dest) else: fileutil.copy(src, dest_str, norsrc=no_xattr) + if touch_file: + ts=self.date.timestamp() + fileutil.utime(dest, (ts, ts)) export_db.set_data( dest_str,