Files
danbooru/app/models/upload_media_asset.rb
evazion 16b8d4b607 uploads: consider uploads as failed when all assets fail.
Make the "completed" status for an upload mean "at least one file in the
upload successfully completed". The "error" status means "all files in
the upload failed".

This means that when an upload has multiple assets and some succeed and
some fail, the whole upload is considered completed. This can happen
when uploading multiple files and some files are over the size limit,
for example. The upload is considered failed only if all files in the
upload fail.

This fixes an issue where, if uploading a single file and that file
failed because it was over the size limit, then the upload wouldn't be
marked as failed.
2022-02-15 17:12:02 -06:00

81 lines
1.8 KiB
Ruby

# frozen_string_literal: true
class UploadMediaAsset < ApplicationRecord
extend Memoist
belongs_to :upload
belongs_to :media_asset, optional: true
after_create :async_process_upload!
after_save :update_upload_status, if: :saved_change_to_status?
enum status: {
pending: 0,
processing: 100,
active: 200,
failed: 300,
}
def self.visible(user)
if user.is_admin?
all
else
where(upload: { uploader: user })
end
end
def self.search(params)
q = search_attributes(params, :id, :created_at, :updated_at, :status, :source_url, :page_url, :error, :upload, :media_asset)
q.apply_default_order(params)
end
def loading?
pending? || processing?
end
def finished?
active? || failed?
end
def file_upload?
source_url.starts_with?("file://")
end
def source_strategy
return nil if source_url.blank?
Sources::Strategies.find(source_url, page_url)
end
def async_process_upload!
return if file_upload?
ProcessUploadMediaAssetJob.perform_later(self)
end
def process_upload!
return if file_upload?
update!(status: :processing)
strategy = Sources::Strategies.find(source_url)
media_file = strategy.download_file!(source_url)
MediaAsset.upload!(media_file) do |media_asset|
update!(media_asset: media_asset)
end
update!(status: :active)
rescue Exception => e
update!(status: :failed, error: e.message)
end
def update_upload_status
upload.with_lock do
if upload.upload_media_assets.all?(&:failed?)
upload.update!(status: "error", error: upload.upload_media_assets.map(&:error).join("; "))
elsif upload.upload_media_assets.all?(&:finished?)
upload.update!(status: "completed")
end
end
end
memoize :source_strategy
end