# 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