Example #1
0
 def Clear( self ):
     
     with self._lock:
         
         self._data_cache.Clear()
         
         self._special_thumbs = {}
         
         names = [ 'hydrus', 'pdf', 'psd', 'clip', 'audio', 'video', 'zip' ]
         
         bounding_dimensions = self._controller.options[ 'thumbnail_dimensions' ]
         thumbnail_scale_type = self._controller.new_options.GetInteger( 'thumbnail_scale_type' )
         
         # it would be ideal to replace this with mimes_to_default_thumbnail_paths at a convenient point
         
         for name in names:
             
             path = os.path.join( HC.STATIC_DIR, '{}.png'.format( name ) )
             
             numpy_image = ClientImageHandling.GenerateNumPyImage( path, HC.IMAGE_PNG )
             
             numpy_image_resolution = HydrusImageHandling.GetResolutionNumPy( numpy_image )
             
             ( clip_rect, target_resolution ) = HydrusImageHandling.GetThumbnailResolutionAndClipRegion( numpy_image_resolution, bounding_dimensions, thumbnail_scale_type )
             
             if clip_rect is not None:
                 
                 numpy_image = HydrusImageHandling.ClipNumPyImage( numpy_image, clip_rect )
                 
             
             numpy_image = HydrusImageHandling.ResizeNumPyImage( numpy_image, target_resolution )
             
             hydrus_bitmap = ClientRendering.GenerateHydrusBitmapFromNumPyImage( numpy_image )
             
             self._special_thumbs[ name ] = hydrus_bitmap
             
         
         self._controller.pub( 'notify_complete_thumbnail_reset' )
         
         self._waterfall_queue_quick = set()
         self._delayed_regeneration_queue_quick = set()
         
         self._RecalcQueues()
Example #2
0
    def GenerateInfo(self, status_hook=None):

        if self._pre_import_file_status.mime is None:

            if status_hook is not None:

                status_hook('generating filetype')

            mime = HydrusFileHandling.GetMime(self._temp_path)

            self._pre_import_file_status.mime = mime

        else:

            mime = self._pre_import_file_status.mime

        if HG.file_import_report_mode:

            HydrusData.ShowText('File import job mime: {}'.format(
                HC.mime_string_lookup[mime]))

        new_options = HG.client_controller.new_options

        if mime in HC.DECOMPRESSION_BOMB_IMAGES and not self._file_import_options.AllowsDecompressionBombs(
        ):

            if HG.file_import_report_mode:

                HydrusData.ShowText(
                    'File import job testing for decompression bomb')

            if HydrusImageHandling.IsDecompressionBomb(self._temp_path):

                if HG.file_import_report_mode:

                    HydrusData.ShowText(
                        'File import job: it was a decompression bomb')

                raise HydrusExceptions.DecompressionBombException(
                    'Image seems to be a Decompression Bomb!')

        if status_hook is not None:

            status_hook('generating file metadata')

        self._file_info = HydrusFileHandling.GetFileInfo(self._temp_path,
                                                         mime=mime)

        (size, mime, width, height, duration, num_frames, has_audio,
         num_words) = self._file_info

        if HG.file_import_report_mode:

            HydrusData.ShowText('File import job file info: {}'.format(
                self._file_info))

        if mime in HC.MIMES_WITH_THUMBNAILS:

            if status_hook is not None:

                status_hook('generating thumbnail')

            if HG.file_import_report_mode:

                HydrusData.ShowText('File import job generating thumbnail')

            bounding_dimensions = HG.client_controller.options[
                'thumbnail_dimensions']
            thumbnail_scale_type = HG.client_controller.new_options.GetInteger(
                'thumbnail_scale_type')

            (clip_rect, target_resolution
             ) = HydrusImageHandling.GetThumbnailResolutionAndClipRegion(
                 (width, height), bounding_dimensions, thumbnail_scale_type)

            percentage_in = HG.client_controller.new_options.GetInteger(
                'video_thumbnail_percentage_in')

            try:

                self._thumbnail_bytes = HydrusFileHandling.GenerateThumbnailBytes(
                    self._temp_path,
                    target_resolution,
                    mime,
                    duration,
                    num_frames,
                    clip_rect=clip_rect,
                    percentage_in=percentage_in)

            except Exception as e:

                raise HydrusExceptions.DamagedOrUnusualFileException(
                    'Could not render a thumbnail: {}'.format(str(e)))

        if mime in HC.FILES_THAT_HAVE_PERCEPTUAL_HASH:

            if status_hook is not None:

                status_hook('generating similar files metadata')

            if HG.file_import_report_mode:

                HydrusData.ShowText(
                    'File import job generating perceptual_hashes')

            self._perceptual_hashes = ClientImageHandling.GenerateShapePerceptualHashes(
                self._temp_path, mime)

            if HG.file_import_report_mode:

                HydrusData.ShowText(
                    'File import job generated {} perceptual_hashes: {}'.
                    format(len(self._perceptual_hashes), [
                        perceptual_hash.hex()
                        for perceptual_hash in self._perceptual_hashes
                    ]))

        if HG.file_import_report_mode:

            HydrusData.ShowText('File import job generating other hashes')

        if status_hook is not None:

            status_hook('generating additional hashes')

        self._extra_hashes = HydrusFileHandling.GetExtraHashesFromPath(
            self._temp_path)

        has_icc_profile = False

        if mime in HC.FILES_THAT_CAN_HAVE_ICC_PROFILE:

            try:

                pil_image = HydrusImageHandling.RawOpenPILImage(
                    self._temp_path)

                has_icc_profile = HydrusImageHandling.HasICCProfile(pil_image)

            except:

                pass

        self._has_icc_profile = has_icc_profile

        if mime in HC.FILES_THAT_CAN_HAVE_PIXEL_HASH and duration is None:

            try:

                self._pixel_hash = HydrusImageHandling.GetImagePixelHash(
                    self._temp_path, mime)

            except:

                pass

        self._file_modified_timestamp = HydrusFileHandling.GetFileModifiedTimestamp(
            self._temp_path)
Example #3
0
def ParseFileArguments(path, decompression_bombs_ok=False):

    HydrusImageHandling.ConvertToPNGIfBMP(path)

    hash = HydrusFileHandling.GetHashFromPath(path)

    try:

        mime = HydrusFileHandling.GetMime(path)

        if mime in HC.DECOMPRESSION_BOMB_IMAGES and not decompression_bombs_ok:

            if HydrusImageHandling.IsDecompressionBomb(path):

                raise HydrusExceptions.InsufficientCredentialsException(
                    'File seemed to be a Decompression Bomb, which you cannot upload!'
                )

        (size, mime, width, height, duration, num_frames, has_audio,
         num_words) = HydrusFileHandling.GetFileInfo(path, mime=mime)

    except Exception as e:

        raise HydrusExceptions.BadRequestException('File ' + hash.hex() +
                                                   ' could not parse: ' +
                                                   str(e))

    args = ParsedRequestArguments()

    args['path'] = path
    args['hash'] = hash
    args['size'] = size
    args['mime'] = mime

    if width is not None: args['width'] = width
    if height is not None: args['height'] = height
    if duration is not None: args['duration'] = duration
    if num_frames is not None: args['num_frames'] = num_frames
    args['has_audio'] = has_audio
    if num_words is not None: args['num_words'] = num_words

    if mime in HC.MIMES_WITH_THUMBNAILS:

        try:

            bounding_dimensions = HC.SERVER_THUMBNAIL_DIMENSIONS

            (clip_rect, target_resolution
             ) = HydrusImageHandling.GetThumbnailResolutionAndClipRegion(
                 (width, height), bounding_dimensions,
                 HydrusImageHandling.THUMBNAIL_SCALE_DOWN_ONLY)

            thumbnail_bytes = HydrusFileHandling.GenerateThumbnailBytes(
                path,
                target_resolution,
                mime,
                duration,
                num_frames,
                clip_rect=clip_rect)

        except Exception as e:

            tb = traceback.format_exc()

            raise HydrusExceptions.BadRequestException(
                'Could not generate thumbnail from that file:' + os.linesep +
                tb)

        args['thumbnail'] = thumbnail_bytes

    return args
Example #4
0
 def _GetThumbnailHydrusBitmap( self, display_media ):
     
     hash = display_media.GetHash()
     mime = display_media.GetMime()
     
     thumbnail_mime = HC.IMAGE_JPEG
     
     # we don't actually know this, it comes down to detailed stuff, but since this is png vs jpeg it isn't a huge deal down in the guts of image loading
     # only really matters with transparency, so anything that can be transparent we'll prime with a png thing
     # ain't like I am encoding EXIF rotation in my jpeg thumbs
     if mime in ( HC.IMAGE_APNG, HC.IMAGE_PNG, HC.IMAGE_GIF, HC.IMAGE_ICON, HC.IMAGE_WEBP ):
         
         thumbnail_mime = HC.IMAGE_PNG
         
     
     locations_manager = display_media.GetLocationsManager()
     
     try:
         
         path = self._controller.client_files_manager.GetThumbnailPath( display_media )
         
     except HydrusExceptions.FileMissingException as e:
         
         if locations_manager.IsLocal():
             
             summary = 'Unable to get thumbnail for file {}.'.format( hash.hex() )
             
             self._HandleThumbnailException( e, summary )
             
         
         return self._special_thumbs[ 'hydrus' ]
         
     
     try:
         
         numpy_image = ClientImageHandling.GenerateNumPyImage( path, thumbnail_mime )
         
     except Exception as e:
         
         try:
             
             # file is malformed, let's force a regen
             self._controller.files_maintenance_manager.RunJobImmediately( [ display_media ], ClientFiles.REGENERATE_FILE_DATA_JOB_FORCE_THUMBNAIL, pub_job_key = False )
             
         except Exception as e:
             
             summary = 'The thumbnail for file {} was not loadable. An attempt to regenerate it failed.'.format( hash.hex() )
             
             self._HandleThumbnailException( e, summary )
             
             return self._special_thumbs[ 'hydrus' ]
             
         
         try:
             
             numpy_image = ClientImageHandling.GenerateNumPyImage( path, thumbnail_mime )
             
         except Exception as e:
             
             summary = 'The thumbnail for file {} was not loadable. It was regenerated, but that file would not render either. Your image libraries or hard drive connection are unreliable. Please inform the hydrus developer what has happened.'.format( hash.hex() )
             
             self._HandleThumbnailException( e, summary )
             
             return self._special_thumbs[ 'hydrus' ]
             
         
     
     ( current_width, current_height ) = HydrusImageHandling.GetResolutionNumPy( numpy_image )
     
     ( media_width, media_height ) = display_media.GetResolution()
     
     bounding_dimensions = self._controller.options[ 'thumbnail_dimensions' ]
     
     thumbnail_scale_type = self._controller.new_options.GetInteger( 'thumbnail_scale_type' )
     
     ( clip_rect, ( expected_width, expected_height ) ) = HydrusImageHandling.GetThumbnailResolutionAndClipRegion( ( media_width, media_height ), bounding_dimensions, thumbnail_scale_type )
     
     exactly_as_expected = current_width == expected_width and current_height == expected_height
     
     rotation_exception = current_width == expected_height and current_height == expected_width
     
     correct_size = exactly_as_expected or rotation_exception
     
     if not correct_size:
         
         numpy_image = HydrusImageHandling.ResizeNumPyImage( numpy_image, ( expected_width, expected_height ) )
         
         if locations_manager.IsLocal():
             
             # we have the master file, so we should regen the thumb from source
             
             if HG.file_report_mode:
                 
                 HydrusData.ShowText( 'Thumbnail {} too small, scheduling regeneration from source.'.format( hash.hex() ) )
                 
             
             delayed_item = display_media.GetMediaResult()
             
             with self._lock:
                 
                 if delayed_item not in self._delayed_regeneration_queue_quick:
                     
                     self._delayed_regeneration_queue_quick.add( delayed_item )
                     
                     self._delayed_regeneration_queue.append( delayed_item )
                     
                 
             
         else:
             
             # we do not have the master file, so we have to scale up from what we have
             
             if HG.file_report_mode:
                 
                 HydrusData.ShowText( 'Stored thumbnail {} was the wrong size, only scaling due to no local source.'.format( hash.hex() ) )
                 
             
         
     
     hydrus_bitmap = ClientRendering.GenerateHydrusBitmapFromNumPyImage( numpy_image )
     
     return hydrus_bitmap