uploads: refactor to simplify ugoira-handling and replacements:
* Make it so replacing a post doesn't generate a dummy upload as a side effect. * Make it so you can't replace a post with itself (the post should be regenerated instead). * Refactor uploads and replacements to save the ugoira frame data when the MediaAsset is created, not when the post is created. This way it's possible to view the ugoira before the post is created. * Make `download_file!` in the Pixiv source strategy return a MediaFile with the ugoira frame data already attached to it, instead of returning it in the `data` field then passing it around separately in the `context` field of the upload.
This commit is contained in:
@@ -71,7 +71,7 @@ class UploadService
|
||||
begin
|
||||
upload.update(status: "preprocessing")
|
||||
|
||||
file = Utils.get_file_for_upload(upload, file: params[:file]&.tempfile)
|
||||
file = Utils.get_file_for_upload(upload.source_url, upload.referer_url, params[:file]&.tempfile)
|
||||
Utils.process_file(upload, file, original_post_id: original_post_id)
|
||||
|
||||
upload.rating = params[:rating]
|
||||
|
||||
@@ -61,69 +61,44 @@ class UploadService
|
||||
undoer.process!
|
||||
end
|
||||
|
||||
def source_strategy(upload)
|
||||
Sources::Strategies.find(upload.source, upload.referer_url)
|
||||
end
|
||||
|
||||
def find_replacement_url(repl, upload)
|
||||
if repl.replacement_file.present?
|
||||
return "file://#{repl.replacement_file.original_filename}"
|
||||
def replacement_url
|
||||
if replacement.replacement_file.present?
|
||||
"file://#{replacement.replacement_file.original_filename}"
|
||||
else
|
||||
Sources::Strategies.find(replacement.replacement_url).canonical_url
|
||||
end
|
||||
|
||||
if upload.source.blank?
|
||||
raise "No source found in upload for replacement"
|
||||
end
|
||||
|
||||
if source_strategy(upload).canonical_url.present?
|
||||
return source_strategy(upload).canonical_url
|
||||
end
|
||||
|
||||
upload.source
|
||||
end
|
||||
|
||||
def process!
|
||||
preprocessor = Preprocessor.new(
|
||||
rating: post.rating,
|
||||
tag_string: replacement.tags,
|
||||
source: replacement.replacement_url,
|
||||
file: replacement.replacement_file,
|
||||
replaced_post: post,
|
||||
original_post_id: post.id
|
||||
)
|
||||
upload = preprocessor.start!
|
||||
raise Error, upload.status if upload.is_errored?
|
||||
upload = preprocessor.finish!(upload)
|
||||
raise Error, upload.status if upload.is_errored?
|
||||
md5_changed = upload.md5 != post.md5
|
||||
media_file = Utils::get_file_for_upload(replacement.replacement_url, nil, replacement.replacement_file&.tempfile)
|
||||
|
||||
replacement.replacement_url = find_replacement_url(replacement, upload)
|
||||
|
||||
if md5_changed
|
||||
post.queue_delete_files(PostReplacement::DELETION_GRACE_PERIOD)
|
||||
if media_file.md5 == post.md5
|
||||
raise Error, "Can't replace a post with itself; regenerate the post instead"
|
||||
elsif Post.exists?(md5: media_file.md5)
|
||||
raise Error, "Duplicate: post with md5 #{media_file.md5} already exists"
|
||||
end
|
||||
|
||||
replacement.file_ext = upload.file_ext
|
||||
replacement.file_size = upload.file_size
|
||||
replacement.image_height = upload.image_height
|
||||
replacement.image_width = upload.image_width
|
||||
replacement.md5 = upload.md5
|
||||
media_asset = MediaAsset.upload!(media_file)
|
||||
post.queue_delete_files(PostReplacement::DELETION_GRACE_PERIOD)
|
||||
|
||||
post.md5 = upload.md5
|
||||
post.file_ext = upload.file_ext
|
||||
post.image_width = upload.image_width
|
||||
post.image_height = upload.image_height
|
||||
post.file_size = upload.file_size
|
||||
replacement.replacement_url = replacement_url
|
||||
replacement.file_ext = media_asset.file_ext
|
||||
replacement.file_size = media_asset.file_size
|
||||
replacement.image_height = media_asset.image_height
|
||||
replacement.image_width = media_asset.image_width
|
||||
replacement.md5 = media_asset.md5
|
||||
|
||||
post.md5 = media_asset.md5
|
||||
post.file_ext = media_asset.file_ext
|
||||
post.image_width = media_asset.image_width
|
||||
post.image_height = media_asset.image_height
|
||||
post.file_size = media_asset.file_size
|
||||
post.source = replacement.final_source.presence || replacement.replacement_url
|
||||
post.tag_string = upload.tag_string
|
||||
post.tag_string = replacement.tags
|
||||
|
||||
rescale_notes(post)
|
||||
update_ugoira_frame_data(post, upload)
|
||||
|
||||
if md5_changed
|
||||
CurrentUser.scoped(User.system) { Comment.create!(post: post, creator: User.system, updater: User.system, body: comment_replacement_message(post, replacement), do_not_bump_post: true, creator_ip_addr: "127.0.0.1") }
|
||||
else
|
||||
purge_cached_urls(post)
|
||||
end
|
||||
CurrentUser.scoped(User.system) { Comment.create!(post: post, creator: User.system, updater: User.system, body: comment_replacement_message(post, replacement), do_not_bump_post: true, creator_ip_addr: "127.0.0.1") }
|
||||
|
||||
replacement.save!
|
||||
post.save!
|
||||
@@ -131,18 +106,6 @@ class UploadService
|
||||
post.update_iqdb
|
||||
end
|
||||
|
||||
def purge_cached_urls(post)
|
||||
urls = [
|
||||
post.preview_file_url,
|
||||
post.large_file_url,
|
||||
post.file_url,
|
||||
post.tagged_large_file_url,
|
||||
post.tagged_file_url
|
||||
]
|
||||
|
||||
CloudflareService.new.purge_cache(urls)
|
||||
end
|
||||
|
||||
def rescale_notes(post)
|
||||
x_scale = post.image_width.to_f / post.image_width_was.to_f
|
||||
y_scale = post.image_height.to_f / post.image_height_was.to_f
|
||||
@@ -151,19 +114,5 @@ class UploadService
|
||||
note.rescale!(x_scale, y_scale)
|
||||
end
|
||||
end
|
||||
|
||||
def update_ugoira_frame_data(post, upload)
|
||||
post.pixiv_ugoira_frame_data.destroy if post.pixiv_ugoira_frame_data.present?
|
||||
|
||||
unless post.is_ugoira?
|
||||
return
|
||||
end
|
||||
|
||||
PixivUgoiraFrameData.create(
|
||||
post_id: post.id,
|
||||
data: upload.context["ugoira"]["frame_data"],
|
||||
content_type: upload.context["ugoira"]["content_type"]
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,9 +7,9 @@ class UploadService
|
||||
end
|
||||
|
||||
def process_file(upload, file, original_post_id: nil)
|
||||
upload.file = file
|
||||
media_file = upload.media_file
|
||||
media_file = MediaFile.open(file)
|
||||
|
||||
upload.file = media_file
|
||||
upload.file_ext = media_file.file_ext.to_s
|
||||
upload.file_size = media_file.file_size
|
||||
upload.md5 = media_file.md5
|
||||
@@ -28,25 +28,14 @@ class UploadService
|
||||
tags.join(" ")
|
||||
end
|
||||
|
||||
def get_file_for_upload(upload, file: nil)
|
||||
return file if file.present?
|
||||
raise "No file or source URL provided" if upload.source_url.blank?
|
||||
def get_file_for_upload(source_url, referer_url, file)
|
||||
return MediaFile.open(file) if file.present?
|
||||
raise "No file or source URL provided" if source_url.blank?
|
||||
|
||||
strategy = Sources::Strategies.find(upload.source_url, upload.referer_url)
|
||||
strategy = Sources::Strategies.find(source_url, referer_url)
|
||||
raise NotImplementedError, "No login credentials configured for #{strategy.site_name}." unless strategy.class.enabled?
|
||||
|
||||
file = strategy.download_file!
|
||||
|
||||
if strategy.data[:ugoira_frame_data].present?
|
||||
upload.context = {
|
||||
"ugoira" => {
|
||||
"frame_data" => strategy.data[:ugoira_frame_data],
|
||||
"content_type" => "image/jpeg"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
file
|
||||
strategy.download_file!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user