has_attached_file :avatar, styles: ->(f) { avatar_styles(f) }, convert_options: { all: '-strip' }, processors: [:lazy_thumbnail]
validates_attachment_content_type :avatar, content_type: IMAGE_MIME_TYPES
validates_attachment_size :avatar, less_than: LIMIT
- remotable_attachment :avatar, LIMIT
+ remotable_attachment :avatar, LIMIT, suppress_errors: false
end
def avatar_original_url
has_attached_file :header, styles: ->(f) { header_styles(f) }, convert_options: { all: '-strip' }, processors: [:lazy_thumbnail]
validates_attachment_content_type :header, content_type: IMAGE_MIME_TYPES
validates_attachment_size :header, less_than: LIMIT
- remotable_attachment :header, LIMIT
+ remotable_attachment :header, LIMIT, suppress_errors: false
end
def header_original_url
end
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError => e
Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}"
+ public_send("#{attachment_name}=", nil) if public_send("#{attachment_name}_file_name").present?
raise e unless suppress_errors
rescue Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Paperclip::Error, Mastodon::DimensionsValidationError, Mastodon::StreamValidationError => e
Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}"
+ public_send("#{attachment_name}=", nil) if public_send("#{attachment_name}_file_name").present?
end
nil
end
def set_fetchable_attributes!
- @account.avatar_remote_url = image_url('icon') || '' unless skip_download?
- @account.header_remote_url = image_url('image') || '' unless skip_download?
+ begin
+ @account.avatar_remote_url = image_url('icon') || '' unless skip_download?
+ rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError
+ RedownloadAvatarWorker.perform_in(rand(30..600).seconds, @account.id)
+ end
+ begin
+ @account.header_remote_url = image_url('image') || '' unless skip_download?
+ rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError
+ RedownloadHeaderWorker.perform_in(rand(30..600).seconds, @account.id)
+ end
@account.statuses_count = outbox_total_items if outbox_total_items.present?
@account.following_count = following_total_items if following_total_items.present?
@account.followers_count = followers_total_items if followers_total_items.present?
--- /dev/null
+# frozen_string_literal: true
+
+class RedownloadAvatarWorker
+ include Sidekiq::Worker
+ include ExponentialBackoff
+ include JsonLdHelper
+
+ sidekiq_options queue: 'pull', retry: 7
+
+ def perform(id)
+ account = Account.find(id)
+
+ return if account.suspended? || DomainBlock.rule_for(account.domain)&.reject_media?
+ return if account.avatar_remote_url.blank? || account.avatar_file_name.present?
+
+ account.reset_avatar!
+ account.save!
+ rescue ActiveRecord::RecordNotFound
+ # Do nothing
+ rescue Mastodon::UnexpectedResponseError => e
+ response = e.response
+
+ if response_error_unsalvageable?(response)
+ # Give up
+ else
+ raise e
+ end
+ end
+end
--- /dev/null
+# frozen_string_literal: true
+
+class RedownloadHeaderWorker
+ include Sidekiq::Worker
+ include ExponentialBackoff
+ include JsonLdHelper
+
+ sidekiq_options queue: 'pull', retry: 7
+
+ def perform(id)
+ account = Account.find(id)
+
+ return if account.suspended? || DomainBlock.rule_for(account.domain)&.reject_media?
+ return if account.header_remote_url.blank? || account.header_file_name.present?
+
+ account.reset_header!
+ account.save!
+ rescue ActiveRecord::RecordNotFound
+ # Do nothing
+ rescue Mastodon::UnexpectedResponseError => e
+ response = e.response
+
+ if response_error_unsalvageable?(response)
+ # Give up
+ else
+ raise e
+ end
+ end
+end