Пример #1
0
    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)
Пример #2
0
    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
Пример #3
0
 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()
Пример #4
0
 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()
Пример #5
0
    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()
Пример #6
0
 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
Пример #7
0
 def _update_directory_mtime(new_directory):
     new_directory.modification_time = get_mtime_datetime(collection_phys_path(new_directory.path))
     new_directory.save()
Пример #8
0
 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()