60 lines
1.5 KiB
Ruby
60 lines
1.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class APIImageUploadService
|
|
class UploadError < StandardError; end
|
|
attr_reader :params, :image, :upload
|
|
|
|
def initialize(params)
|
|
@params = params
|
|
end
|
|
|
|
def start!
|
|
file = params.delete(:file)
|
|
APIImage.transaction do
|
|
@image = APIImage.new(**params, creator: CurrentUser.user)
|
|
begin
|
|
@image.file = get_file(@image, file: file)
|
|
process_file(@image, @image.file)
|
|
@image.save
|
|
return @image if @image.invalid?
|
|
store_file(@image, @image.file)
|
|
@image
|
|
rescue UploadError, ActiveRecord::RecordInvalid => e
|
|
@image.exception = e
|
|
@image
|
|
end
|
|
end
|
|
end
|
|
|
|
def get_file(image, file: nil)
|
|
return file if file.present?
|
|
raise(UploadError, "No file or source URL provided") if image.original_url.blank?
|
|
|
|
download = FileDownload.new(image.original_url)
|
|
download.download!
|
|
end
|
|
|
|
def process_file(image, file)
|
|
mime, ext = @image.file_header_info(file.path)
|
|
image.mime_type = mime
|
|
image.file_ext = ext
|
|
image.file_size = file.size
|
|
image.id = Digest::MD5.file(file.path).hexdigest
|
|
|
|
width, height = calculate_dimensions(file.path)
|
|
image.width = width
|
|
image.height = height
|
|
image.validate!(:file)
|
|
end
|
|
|
|
def store_file(image, file)
|
|
Websites.config.yiffy2_storage.put(image.path, file)
|
|
Websites.config.yiffy2_backup_storage.put(image.path, file)
|
|
end
|
|
|
|
def calculate_dimensions(file_path)
|
|
image = Vips::Image.new_from_file(file_path)
|
|
[image.width, image.height]
|
|
end
|
|
end
|