Files
danbooru/app/logical/upload_service.rb
evazion b068c113a8 Add MediaAsset model.
A MediaAsset represents an image or video file uploaded to Danbooru. It
stores the metadata associated with the image or video. This is to work
on decoupling files from posts so that images can be uploaded separately
from posts.
2021-09-02 06:07:52 -05:00

121 lines
3.2 KiB
Ruby

# A service object for uploading an image.
class UploadService
attr_reader :params, :post, :upload
def initialize(params)
@params = params
end
def delayed_start(uploader)
CurrentUser.scoped(uploader) do
start!
end
rescue ActiveRecord::RecordNotUnique
end
def start!
preprocessor = Preprocessor.new(params)
if preprocessor.in_progress?
UploadServiceDelayedStartJob.set(wait: 5.seconds).perform_later(params, CurrentUser.user)
return preprocessor.predecessor
end
if preprocessor.completed?
@upload = preprocessor.finish!
begin
create_post_from_upload(@upload)
rescue Exception => e
@upload.update(status: "error: #{e.class} - #{e.message}", backtrace: e.backtrace.join("\n"))
end
return @upload
end
params[:rating] ||= "q"
params[:tag_string] ||= "tagme"
@upload = Upload.create!(params)
begin
if @upload.invalid?
return @upload
end
@upload.update(status: "processing")
@upload.file = Utils.get_file_for_upload(@upload, file: @upload.file&.tempfile)
Utils.process_file(upload, @upload.file)
@upload.save!
@post = create_post_from_upload(@upload)
@upload
rescue Exception => e
@upload.update(status: "error: #{e.class} - #{e.message}", backtrace: e.backtrace.join("\n"))
@upload
end
end
def warnings
return [] if @post.nil?
@post.warnings.full_messages
end
def create_post_from_upload(upload)
@post = convert_to_post(upload)
@post.save!
if upload.context && upload.context["ugoira"]
PixivUgoiraFrameData.create(
post_id: @post.id,
data: upload.context["ugoira"]["frame_data"],
content_type: upload.context["ugoira"]["content_type"]
)
end
if upload.has_commentary?
@post.create_artist_commentary(
:original_title => upload.artist_commentary_title,
:original_description => upload.artist_commentary_desc,
:translated_title => upload.translated_commentary_title,
:translated_description => upload.translated_commentary_desc
)
end
@post.update_iqdb
upload.update(status: "completed", post_id: @post.id)
@post
end
def convert_to_post(upload)
Post.new.tap do |p|
p.has_cropped = true
p.tag_string = upload.tag_string
p.md5 = upload.md5
p.file_ext = upload.file_ext
p.image_width = upload.image_width
p.image_height = upload.image_height
p.rating = upload.rating
if upload.source.present?
p.source = Sources::Strategies.find(upload.source, upload.referer_url).canonical_url || upload.source
end
p.file_size = upload.file_size
p.uploader_id = upload.uploader_id
p.uploader_ip_addr = upload.uploader_ip_addr
p.parent_id = upload.parent_id
p.media_asset = MediaAsset.new(
md5: upload.md5,
file_ext: upload.file_ext,
file_size: upload.file_size,
image_width: upload.image_width,
image_height: upload.image_height,
)
if !upload.uploader.can_upload_free? || upload.upload_as_pending?
p.is_pending = true
end
end
end
end