From f181c618b3e5f93fa68aefe3d99f0ba92e1e7966 Mon Sep 17 00:00:00 2001 From: Cedric Leporcq Date: Sat, 17 Apr 2021 15:37:37 +0200 Subject: [PATCH] Metadata changes are made in dest files instead of source files --- elodie.py | 5 +---- elodie/external/pyexiftool.py | 5 +++-- elodie/filesystem.py | 35 +++++++++++++---------------------- elodie/media/base.py | 13 +++++++++---- elodie/media/media.py | 30 +++++++++++------------------- 5 files changed, 37 insertions(+), 51 deletions(-) diff --git a/elodie.py b/elodie.py index fc9ff49..d5f03e0 100755 --- a/elodie.py +++ b/elodie.py @@ -60,11 +60,8 @@ def import_file(_file, destination, album_from_folder, trash, allow_duplicates): log.all('{"source":"%s", "error_msg":"Not a supported file"}' % _file) return - if album_from_folder: - media.set_album_from_folder() - dest_path = FILESYSTEM.process_file(_file, destination, - media, allowDuplicate=allow_duplicates, move=False) + media, album_from_folder, allowDuplicate=allow_duplicates, move=False) if dest_path: log.all('%s -> %s' % (_file, dest_path)) if trash: diff --git a/elodie/external/pyexiftool.py b/elodie/external/pyexiftool.py index d09aa2a..51ff7f5 100644 --- a/elodie/external/pyexiftool.py +++ b/elodie/external/pyexiftool.py @@ -396,7 +396,7 @@ class ExifTool(object, with_metaclass(Singleton)): """ return self.get_tag_batch(tag, [filename])[0] - def set_tags_batch(self, tags, filenames): + def set_tags_batch(self, tags, filenames, overwrite=True): """Writes the values of the specified tags for the given files. The first argument is a dictionary of tags and values. The tag names may @@ -422,7 +422,8 @@ class ExifTool(object, with_metaclass(Singleton)): params_utf8 = [] for tag, value in tags.items(): params.append(u'-%s=%s' % (tag, value)) - + if overwrite: + params.append('-overwrite_original') params.extend(filenames) params_utf8 = [x.encode('utf-8') for x in params] return self.execute(*params_utf8) diff --git a/elodie/filesystem.py b/elodie/filesystem.py index df41e9f..d1dfcd2 100644 --- a/elodie/filesystem.py +++ b/elodie/filesystem.py @@ -614,17 +614,20 @@ class FileSystem(object): )) return checksum - def process_file(self, _file, destination, media, **kwargs): + def process_file(self, _file, destination, media, album_from_folder, **kwargs): move = False if('move' in kwargs): - move = kwargs['move'] + if kwargs['move']: + action = 'move' + else: + action = 'copy' allow_duplicate = False if('allowDuplicate' in kwargs): allow_duplicate = kwargs['allowDuplicate'] stat_info_original = os.stat(_file) - metadata = media.get_metadata() + metadata = media.get_metadata(album_from_folder) if(not media.is_valid()): print('%s is not a valid media file. Skipping...' % _file) @@ -648,8 +651,6 @@ class FileSystem(object): file_name = self.get_file_name(metadata) dest_path = os.path.join(dest_directory, file_name) - media.set_original_name() - # If source and destination are identical then # we should not write the file. gh-210 if(_file == dest_path): @@ -661,37 +662,27 @@ class FileSystem(object): # exiftool renames the original file by appending '_original' to the # file name. A new file is written with new tags with the initial file # name. See exiftool man page for more details. - exif_original_file = _file + '_original' # Check if the source file was processed by exiftool and an _original # file was created. - exif_original_file_exists = False - if(os.path.exists(exif_original_file)): - exif_original_file_exists = True - if(move is True): + if(action == 'move'): stat = os.stat(_file) # Move the processed file into the destination directory shutil.move(_file, dest_path) - if(exif_original_file_exists is True): - # We can remove it as we don't need the initial file. - os.remove(exif_original_file) - else: - if(exif_original_file_exists is True): - # Move the newly processed file with any updated tags to the - # destination directory - shutil.move(_file, dest_path) - # Move the exif _original back to the initial source file - shutil.move(exif_original_file, _file) - else: - compatability._copyfile(_file, dest_path) + elif action == 'copy': + shutil.copy2(_file, dest_path) + if action != 'dry-run': # Set the utime based on what the original file contained # before we made any changes. # Then set the utime on the destination file based on metadata. date_taken = self.get_date_taken(metadata) self.set_utime_from_metadata(date_taken, dest_path) + media.set_original_name(dest_path) + if album_from_folder: + media.set_album_from_folder(dest_path) db = Db() db.add_hash(checksum, dest_path) diff --git a/elodie/media/base.py b/elodie/media/base.py index 65c5362..7132345 100644 --- a/elodie/media/base.py +++ b/elodie/media/base.py @@ -91,6 +91,11 @@ class Base(object): return self.metadata source = self.source + folder = os.path.basename(os.path.dirname(source)) + album = self.get_album() + album_from_folder = True + if album_from_folder and (album is None or album == ''): + album = folder self.metadata = { 'date_original': self.get_date_attribute(self.date_original), @@ -100,11 +105,11 @@ class Base(object): 'camera_model': self.get_camera_model(), 'latitude': self.get_coordinate('latitude'), 'longitude': self.get_coordinate('longitude'), - 'album': self.get_album(), + 'album': album, 'title': self.get_title(), 'mime_type': self.get_mimetype(), 'original_name': self.get_original_name(), - 'base_name': os.path.splitext(os.path.basename(source))[0], + 'base_name': folder, 'extension': self.get_extension(), 'directory_path': os.path.dirname(source) } @@ -164,7 +169,7 @@ class Base(object): """ return None - def set_album_from_folder(self): + def set_album_from_folder(self, path): """Set the album attribute based on the leaf folder name :returns: bool @@ -180,7 +185,7 @@ class Base(object): if(len(folder) == 0): return False - status = self.set_album(folder) + self.set_album(folder) if status == False: return False return True diff --git a/elodie/media/media.py b/elodie/media/media.py index d1fbf0a..3ca389f 100644 --- a/elodie/media/media.py +++ b/elodie/media/media.py @@ -248,20 +248,18 @@ class Media(Base): self.exif_metadata = None super(Media, self).reset_cache() - def set_album(self, album): - """Set album for a photo + def set_album(self, name, path): + """Set album EXIF tag if not already set. - :param str name: Name of album - :returns: bool + :returns: True, False, None """ - if(not self.is_valid()): + if self.get_album() is not None: return None - tags = {self.album_keys[0]: album} - status = self.__set_tags(tags) + tags = {self.album_keys[0]: name} + status = ExifTool().set_tags(tags, path) self.reset_cache() - - return status + return status != '' def set_date_original(self, time): """Set the date/time a photo was taken. @@ -314,27 +312,21 @@ class Media(Base): return status - def set_original_name(self, name=None): + def set_original_name(self, path): """Sets the original name EXIF tag if not already set. :returns: True, False, None """ - if(not self.is_valid()): - return None - # If EXIF original name tag is set then we return. if self.get_original_name() is not None: return None - source = self.source - - if not name: - name = os.path.basename(source) + name = os.path.basename(path) tags = {self.original_name_key: name} - status = self.__set_tags(tags) + status = ExifTool().set_tags(tags, path) self.reset_cache() - return status + return status != '' def set_title(self, title): """Set title for a photo.