From d2c520035b06c94068ae22e05978853da6688aa4 Mon Sep 17 00:00:00 2001 From: evazion Date: Tue, 1 Nov 2022 16:30:50 -0500 Subject: [PATCH] media assets: fix regenerating AI tags for flash files. Fix it so that trying to regenerate AI tags for a Flash file doesn't fail because Flash files have no image preview. Also let `MediaFile.open` take a block argument. --- app/logical/media_file.rb | 35 ++++++++++++++++++++++++++++------- app/models/media_asset.rb | 18 +++++++++++++----- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/app/logical/media_file.rb b/app/logical/media_file.rb index a926aed07..1d41e97be 100644 --- a/app/logical/media_file.rb +++ b/app/logical/media_file.rb @@ -15,17 +15,38 @@ class MediaFile # delegate all File methods to `file`. delegate *(File.instance_methods - MediaFile.instance_methods), to: :file - # Open a file or filename and return a MediaFile object. + # Open a file or filename and return a MediaFile object. If a block is given, + # pass the file to the block and return the result after closing the file. # - # @param file [File, String] a filename or an open File object + # @param file [File, MediaFile, String] A filename or an open File object. # @param options [Hash] extra options for the MediaFile subclass. - # @return [MediaFile] the media file - def self.open(file, **options) - return file.dup if file.is_a?(MediaFile) + # @yieldparam media_file [MediaFile] The opened media file. + # @return [MediaFile] The media file. + def self.open(file, **options, &block) + if file.is_a?(MediaFile) + media_file = file + else + file = Kernel.open(file, "r", binmode: true) unless file.respond_to?(:read) + media_file = new_from_file(file, **options) + end - file = Kernel.open(file, "r", binmode: true) unless file.respond_to?(:read) + if block_given? + result = yield media_file + media_file.close + result + else + media_file + end + end - case file_ext(file) + # Return a new MediaFile from an open File object. + # + # @param file [File] The File object. + # @param file_ext [Symbol] The file extension. + # @param options [Hash] Extra options for the MediaFile subclass. + # @return [MediaFile] The media file. + def self.new_from_file(file, file_ext = MediaFile.file_ext(file), **options) + case file_ext when :jpg, :gif, :png, :webp, :avif MediaFile::Image.new(file, **options) when :swf diff --git a/app/models/media_asset.rb b/app/models/media_asset.rb index 2bf9ba858..138d0d3df 100644 --- a/app/models/media_asset.rb +++ b/app/models/media_asset.rb @@ -80,16 +80,16 @@ class MediaAsset < ApplicationRecord backup_storage_service.delete(file_path) end - def open_file - open_file! + def open_file(&block) + open_file!(&block) rescue nil end - def open_file! + def open_file!(&block) file = storage_service.open(file_path) frame_delays = media_asset.frame_delays if media_asset.is_ugoira? - MediaFile.open(file, frame_delays: frame_delays, strict: false) + MediaFile.open(file, frame_delays: frame_delays, strict: false, &block) end def convert_file(media_file) @@ -323,7 +323,15 @@ class MediaAsset < ApplicationRecord def regenerate_ai_tags! with_lock do ai_tags.each(&:destroy!) - update!(ai_tags: variant(:"360x360").open_file.ai_tags) + update!(ai_tags: generate_ai_tags) + end + end + + def generate_ai_tags + return [] if !has_variant?("360x360") + + variant("360x360").open_file! do |media_file| + media_file.ai_tags end end