def _process_files(self, fs_filenames, root_object, root_phys_path): db_files = root_object.files.all() for file_object in db_files: if file_object.name not in fs_filenames: # if any of images under root doesn't exist -> remove it from db logger.info("scheduling file removal: " + file_object.path) self._removals.append(file_object) else: # update mtime if neeeded self._update_mtime_if_needed(file_object) # add file objects if not found on db db_filenames = {x.name for x in db_files} for missing_file in set(fs_filenames) - db_filenames: file_phys_path = os.path.join(root_phys_path, missing_file) file_mtime = get_mtime_datetime(file_phys_path) if is_jpeg(missing_file): aspect_ratio = self.get_image_aspect_ratio(file_phys_path) raw_filename = self._detect_rawfile(file_phys_path) file_object = Image(name=missing_file, directory=root_object, modification_time=file_mtime, aspect_ratio=aspect_ratio, raw_filename=raw_filename) elif is_video(missing_file): file_object = Video(name=missing_file, directory=root_object, modification_time=file_mtime) else: raise Exception("File should be either Image or Video" + missing_file) file_object.save() logger.info("adding file " + file_object.path)
def _try_copying_existing_miniature(cls, original_phys_path, miniature_phys_path, generator): """ When original in collection is moved to new directory, copy existing miniature instead of creating a new one. """ original_mtime = get_mtime_datetime(original_phys_path) original_basename = os.path.basename(original_phys_path) # originals with same basename and modification time are considered as identical # therefore if there exists thumbnail it can be used instead of creating new one same_original_query = File.objects.filter(name=original_basename, modification_time=original_mtime) for same_original in same_original_query.all(): same_original_phys_path = locations.collection_phys_path(same_original.path) same_original_miniature_phys_path = generator.miniature_phys_path(same_original_phys_path) copy_args = (same_original_miniature_phys_path, miniature_phys_path) # underlying thumbnail exists - thumbnails can be copied if os.path.exists(same_original_miniature_phys_path): logger.info( "there exists already original with same name and mtime: copying {} -> {}".format(*copy_args)) shutil.copy(*copy_args) return True # there was no thumbnail yet # this could happen when two exact copies are added and no thumbnail was created for any of them return False
def _update_mtime_if_needed(cls, file_object): file_phys_path = collection_phys_path(file_object.path) mtime = get_mtime_datetime(file_phys_path) if file_object.modification_time != mtime: logger.info("updating file mtime (and possibly: aspect_ratio): " + file_object.path) file_object.modification_time = mtime if is_jpeg(file_phys_path): file_object.aspect_ratio = cls.get_image_aspect_ratio(file_phys_path) file_object.save()
def _name_original_to_miniature(self, f): if os.path.exists(f): timestamp = get_mtime_datetime(f) else: try: directory, filename = os.path.split(locations.collection_web_path(f)) timestamp = File.objects.all().get(name=filename, directory__path=directory).modification_time timestamp = timestamp.astimezone(tzlocal.get_localzone()) except File.DoesNotExist: raise Exception("File should either exist or be present on database " + f) return f + "_" + timestamp.strftime(TIMESTAMP_FORMAT) + self.extension()
def _rotate_by_jpegtran(cls, image_phys_path, rotated_image): image_phys_path_rotated = image_phys_path + "_rotated" rotation_angle = str(cls.ROTATIONS_MAP[rotated_image.orientation]) logger.info("rotating image ({} degrees): {}".format(rotation_angle, image_phys_path)) # call lossless rotation subprocess.call( ['jpegtran', '-rotate', rotation_angle, '-outfile', image_phys_path_rotated, image_phys_path]) os.rename(image_phys_path_rotated, image_phys_path) # invoke thumbnail recreation Thumbnailer.create_miniatures(image_phys_path, force_recreate=True) # reset image orientation rotated_image.orientation = 'up' # recalculate aspect radio, modification_time rotated_image.aspect_ratio = Indexer.get_image_aspect_ratio(image_phys_path) rotated_image.modification_time = get_mtime_datetime(image_phys_path) rotated_image.save()
def _timestamps_differ(cls, collection_phys_path, miniature_phys_path): originals_mtime = get_mtime_datetime(collection_phys_path).replace(microsecond=0) miniature_mtime = cls._get_miniature_timestamp(miniature_phys_path) timestamps_differ = miniature_mtime != originals_mtime return timestamps_differ
def _update_directory_mtime(new_directory): new_directory.modification_time = get_mtime_datetime(collection_phys_path(new_directory.path)) new_directory.save()
def _update_file_information(file, new_original_phys_path): file.name = os.path.basename(new_original_phys_path) file.modification_time = get_mtime_datetime(new_original_phys_path) file.substitute_original = False file.save()