diff --git a/app/controllers/pixiv_ugoira_frame_data_controller.rb b/app/controllers/pixiv_ugoira_frame_data_controller.rb deleted file mode 100644 index 4d940138e..000000000 --- a/app/controllers/pixiv_ugoira_frame_data_controller.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -class PixivUgoiraFrameDataController < ApplicationController - respond_to :json, :xml - - def index - @pixiv_ugoira_frame_data = PixivUgoiraFrameData.paginated_search(params) - respond_with(@pixiv_ugoira_frame_data) - end -end diff --git a/app/logical/media_file/ugoira.rb b/app/logical/media_file/ugoira.rb index 070f06446..2f9015083 100644 --- a/app/logical/media_file/ugoira.rb +++ b/app/logical/media_file/ugoira.rb @@ -9,11 +9,11 @@ # zip file, so it must be passed around separately. class MediaFile::Ugoira < MediaFile class Error < StandardError; end - attr_accessor :frame_data + attr_accessor :frame_delays - def initialize(file, frame_data: {}, **options) + def initialize(file, frame_delays: [], **options) super(file, **options) - @frame_data = frame_data + @frame_delays = frame_delays end def close @@ -39,22 +39,18 @@ class MediaFile::Ugoira < MediaFile end def frame_count - frame_data.count + frame_delays.count end def frame_rate frame_count / duration end - def frame_delays - frame_data.map { |frame| frame["delay"] } - end - # Convert a ugoira to a webm. # XXX should take width and height and resize image def convert raise NotImplementedError, "can't convert ugoira to webm: ffmpeg or mkvmerge not installed" unless self.class.videos_enabled? - raise RuntimeError, "can't convert ugoira to webm: no ugoira frame data was provided" unless frame_data.present? + raise RuntimeError, "can't convert ugoira to webm: no ugoira frame data was provided" unless frame_delays.present? Dir.mktmpdir("ugoira-#{md5}") do |tmpdir| output_file = Tempfile.new(["ugoira-conversion", ".webm"], binmode: true) @@ -80,9 +76,9 @@ class MediaFile::Ugoira < MediaFile timecodes_path = File.join(tmpdir, "timecodes.tc") File.open(timecodes_path, "w+") do |f| f.write("# timecode format v2\n") - frame_data.each do |img| + frame_delays.each do |delay| f.write("#{delay_sum}\n") - delay_sum += (img["delay"] || img["delay_msec"]) + delay_sum += delay end f.write("#{delay_sum}\n") f.write("#{delay_sum}\n") diff --git a/app/logical/source/extractor/pixiv.rb b/app/logical/source/extractor/pixiv.rb index 16e8bd23e..46791f604 100644 --- a/app/logical/source/extractor/pixiv.rb +++ b/app/logical/source/extractor/pixiv.rb @@ -115,9 +115,9 @@ module Source end def download_file!(url) - file = super(url) - file.frame_data = ugoira_frame_data if is_ugoira? - file + media_file = super(url) + media_file.frame_delays = ugoira_frame_delays if is_ugoira? + media_file end def translate_tag(tag) @@ -162,8 +162,8 @@ module Source parsed_url.username || api_illust[:userAccount] end - def ugoira_frame_data - api_ugoira[:frames] + def ugoira_frame_delays + api_ugoira[:frames].pluck("delay") end memoize :illust_id, :api_client, :api_illust, :api_pages, :api_ugoira diff --git a/app/models/media_asset.rb b/app/models/media_asset.rb index 2f0504493..864825d50 100644 --- a/app/models/media_asset.rb +++ b/app/models/media_asset.rb @@ -17,13 +17,12 @@ class MediaAsset < ApplicationRecord has_one :post, foreign_key: :md5, primary_key: :md5 has_one :media_metadata, dependent: :destroy - has_one :pixiv_ugoira_frame_data, class_name: "PixivUgoiraFrameData", foreign_key: :md5, primary_key: :md5 has_many :upload_media_assets, dependent: :destroy has_many :uploads, through: :upload_media_assets has_many :uploaders, through: :uploads, class_name: "User", foreign_key: :uploader_id has_many :ai_tags - delegate :metadata, to: :media_metadata + delegate :frame_delays, :metadata, to: :media_metadata delegate :is_non_repeating_animation?, :is_greyscale?, :is_rotated?, :is_ai_generated?, to: :metadata scope :public_only, -> { where(is_public: true) } @@ -81,8 +80,8 @@ class MediaAsset < ApplicationRecord def open_file file = storage_service.open(file_path) - frame_data = media_asset.pixiv_ugoira_frame_data&.data if media_asset.is_ugoira? - MediaFile.open(file, frame_data: frame_data, strict: false) + frame_delays = media_asset.frame_delays if media_asset.is_ugoira? + MediaFile.open(file, frame_delays: frame_delays, strict: false) end def convert_file(media_file) @@ -252,7 +251,6 @@ class MediaAsset < ApplicationRecord # XXX should do this in parallel with thumbnail generation. # XXX shouldn't generate thumbnail twice (very slow for ugoira) media_asset.update!(ai_tags: media_file.preview(360, 360).ai_tags) - media_asset.update!(pixiv_ugoira_frame_data: PixivUgoiraFrameData.new(data: media_file.frame_data, content_type: "image/jpeg")) if media_asset.is_ugoira? media_asset.update!(media_metadata: MediaMetadata.new(file: media_file)) media_asset.distribute_files!(media_file) @@ -423,6 +421,6 @@ class MediaAsset < ApplicationRecord end def self.available_includes - %i[post media_metadata pixiv_ugoira_frame_data ai_tags] + %i[post media_metadata ai_tags] end end diff --git a/app/models/media_metadata.rb b/app/models/media_metadata.rb index fe9c3fbdc..6e37b3bd4 100644 --- a/app/models/media_metadata.rb +++ b/app/models/media_metadata.rb @@ -28,4 +28,8 @@ class MediaMetadata < ApplicationRecord def metadata ExifTool::Metadata.new(self[:metadata]) end + + def frame_delays + metadata["Ugoira:FrameDelays"].to_a + end end diff --git a/app/models/pixiv_ugoira_frame_data.rb b/app/models/pixiv_ugoira_frame_data.rb deleted file mode 100644 index de9b58a1b..000000000 --- a/app/models/pixiv_ugoira_frame_data.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -class PixivUgoiraFrameData < ApplicationRecord - belongs_to :post, optional: true, foreign_key: :md5, primary_key: :md5 - belongs_to :media_asset, foreign_key: :md5, primary_key: :md5 - - serialize :data - before_validation :normalize_data, on: :create - - def self.available_includes - [:post] - end - - def self.search(params, current_user) - q = search_attributes(params, [:id, :data, :content_type, :post, :md5], current_user: current_user) - q.apply_default_order(params) - end - - def frame_delays - data.pluck("delay") - end - - def normalize_data - return if data.nil? - - if data[0]["delay_msec"] - self.data = data.map.with_index do |datum, i| - filename = format("%06d.jpg", i) - {"delay" => datum["delay_msec"], "file" => filename} - end - end - end -end diff --git a/app/models/post.rb b/app/models/post.rb index e99eefc12..23a86e386 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -58,7 +58,6 @@ class Post < ApplicationRecord has_one :media_asset, -> { active }, foreign_key: :md5, primary_key: :md5 has_one :media_metadata, through: :media_asset has_one :artist_commentary, :dependent => :destroy - has_one :pixiv_ugoira_frame_data, class_name: "PixivUgoiraFrameData", foreign_key: :md5, primary_key: :md5 has_one :vote_by_current_user, -> { active.where(user_id: CurrentUser.id) }, class_name: "PostVote" # XXX using current user here is wrong has_many :flags, :class_name => "PostFlag", :dependent => :destroy has_many :appeals, :class_name => "PostAppeal", :dependent => :destroy @@ -1406,7 +1405,7 @@ class Post < ApplicationRecord :last_comment_bumped_at, :last_commented_at, :last_noted_at, :uploader, :approver, :parent, :artist_commentary, :flags, :appeals, :notes, :comments, :children, - :approvals, :replacements, :pixiv_ugoira_frame_data], + :approvals, :replacements], current_user: current_user ) @@ -1630,7 +1629,7 @@ class Post < ApplicationRecord # attributes accessible through the ?only= parameter %i[ uploader approver flags appeals events parent children notes - comments approvals disapprovals replacements pixiv_ugoira_frame_data + comments approvals disapprovals replacements artist_commentary media_asset ai_tags ] end diff --git a/config/routes.rb b/config/routes.rb index 682c82153..bfad4d101 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -164,7 +164,6 @@ Rails.application.routes.draw do resources :note_versions, :only => [:index, :show] resource :note_previews, only: [:create, :show] resource :password_reset, only: [:create, :show] - resources :pixiv_ugoira_frame_data, only: [:index] resources :pools do member do put :revert diff --git a/test/factories/pixiv_ugoira_frame_data.rb b/test/factories/pixiv_ugoira_frame_data.rb deleted file mode 100644 index 2370db591..000000000 --- a/test/factories/pixiv_ugoira_frame_data.rb +++ /dev/null @@ -1,12 +0,0 @@ -FactoryBot.define do - factory(:pixiv_ugoira_frame_data) do - post - content_type { "image/jpeg" } - data do - [ - { "file" => "000000.jpg", "delay" => 200 }, - { "file" => "000001.jpg", "delay" => 200 }, - ] - end - end -end diff --git a/test/functional/pixiv_ugoira_frame_data_controller_test.rb b/test/functional/pixiv_ugoira_frame_data_controller_test.rb deleted file mode 100644 index 7d398fbec..000000000 --- a/test/functional/pixiv_ugoira_frame_data_controller_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -require "test_helper" - -class PixivUgoiraFrameDataControllerTest < ActionDispatch::IntegrationTest - context "index action" do - should "work" do - create(:pixiv_ugoira_frame_data) - get pixiv_ugoira_frame_data_path, as: :json - assert_response :success - end - end -end diff --git a/test/functional/post_replacements_controller_test.rb b/test/functional/post_replacements_controller_test.rb index 8d2ee6a3d..80506ad57 100644 --- a/test/functional/post_replacements_controller_test.rb +++ b/test/functional/post_replacements_controller_test.rb @@ -128,8 +128,7 @@ class PostReplacementsControllerTest < ActionDispatch::IntegrationTest assert_equal("cad1da177ef309bf40a117c17b8eecf5", @post.media_asset.variant(:original).open_file.md5) assert_equal("https://i.pximg.net/img-zip-ugoira/img/2017/04/04/08/57/38/62247364_ugoira1920x1080.zip", @post.source) - assert_equal([{"delay" => 125, "file" => "000000.jpg"}, {"delay" => 125, "file" => "000001.jpg"}], @post.pixiv_ugoira_frame_data.data) - assert_equal([125, 125], @post.media_asset.metadata["Ugoira:FrameDelays"]) + assert_equal([125, 125], @post.media_asset.frame_delays) end end diff --git a/test/unit/downloads/pixiv_test.rb b/test/unit/downloads/pixiv_test.rb index d04d4b76f..864cd8909 100644 --- a/test/unit/downloads/pixiv_test.rb +++ b/test/unit/downloads/pixiv_test.rb @@ -122,8 +122,7 @@ module Downloads @strategy = Source::Extractor.find("http://www.pixiv.net/member_illust.php?mode=medium&illust_id=62247364") media_file = @strategy.download_file!(@strategy.image_urls.sole) - assert_equal(2, media_file.frame_data.size) - assert_equal([{"file" => "000000.jpg", "delay" => 125}, {"file" => "000001.jpg", "delay" => 125}], media_file.frame_data) + assert_equal([125, 125], media_file.frame_delays) end end end diff --git a/test/unit/media_file_test.rb b/test/unit/media_file_test.rb index 1f4b78194..a16762f97 100644 --- a/test/unit/media_file_test.rb +++ b/test/unit/media_file_test.rb @@ -33,8 +33,8 @@ class MediaFileTest < ActiveSupport::TestCase should "determine the correct dimensions for a ugoira file" do skip unless MediaFile.videos_enabled? - frame_data = JSON.parse(File.read("test/files/ugoira.json")) - assert_equal([60, 60], MediaFile.open("test/files/ugoira.zip", frame_data: frame_data).dimensions) + frame_delays = JSON.parse(File.read("test/files/ugoira.json")).pluck("delay") + assert_equal([60, 60], MediaFile.open("test/files/ugoira.zip", frame_delays: frame_delays).dimensions) end should "determine the correct dimensions for a flash file" do @@ -58,8 +58,8 @@ class MediaFileTest < ActiveSupport::TestCase assert_equal([512, 512], mf.dimensions) assert_equal([512, 512], mf.dimensions) - frame_data = JSON.parse(File.read("test/files/ugoira.json")) - mf = MediaFile.open("test/files/ugoira.zip", frame_data: frame_data) + frame_delays = JSON.parse(File.read("test/files/ugoira.json")).pluck("delay") + mf = MediaFile.open("test/files/ugoira.zip", frame_delays: frame_delays) assert_equal([60, 60], mf.dimensions) assert_equal([60, 60], mf.dimensions) end @@ -151,8 +151,8 @@ class MediaFileTest < ActiveSupport::TestCase context "for a ugoira" do setup do skip unless MediaFile::Ugoira.videos_enabled? - frame_data = JSON.parse(File.read("test/files/ugoira.json")) - @ugoira = MediaFile.open("test/files/ugoira.zip", frame_data: frame_data) + frame_delays = JSON.parse(File.read("test/files/ugoira.json")).pluck("delay") + @ugoira = MediaFile.open("test/files/ugoira.zip", frame_delays: frame_delays) end should "generate a preview" do diff --git a/test/unit/sources/pixiv_test.rb b/test/unit/sources/pixiv_test.rb index 0f635d24f..1bea8d2a4 100644 --- a/test/unit/sources/pixiv_test.rb +++ b/test/unit/sources/pixiv_test.rb @@ -46,8 +46,7 @@ module Sources should "capture the frame data" do media_file = @site.download_file!(@site.image_urls.sole) - assert_equal(2, media_file.frame_data.size) - assert_equal([{"file" => "000000.jpg", "delay" => 125}, {"file" => "000001.jpg", "delay" => 125}], media_file.frame_data) + assert_equal([125, 125], media_file.frame_delays) end end