Import “converted” objects as media attachments if possible

This allows Image and Audio objects at least to be imported if any of
the URLs holds a supported media type. Only the first such link is
imported, even if multiple URLs are associated with the object, since
they are generally alternative representations (e.g. different formats)
of the same object.
This commit is contained in:
Giuseppe Bilotta 2023-03-12 19:55:05 +01:00
parent fa95e0db07
commit a6e87cd9a6

View file

@ -110,7 +110,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
def process_status_params
@status_parser = ActivityPub::Parser::StatusParser.new(@json, followers_collection: @account.followers_url)
attachment_ids = process_attachments.take(4).map(&:id)
attachment_ids = (converted_object_type? ? converted_attachments : process_attachments).take(4).map(&:id)
@params = {
uri: @status_parser.uri,
@ -252,11 +252,71 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
end
end
def process_attachments
return [] if @object['attachment'].nil?
# Get the first supported object URL and turn it into an attachment,
# before processing the actual attachments
def converted_attachments
return process_attachments if @object['url'].nil?
media_attachments = []
icon_url = @object['icon'].presence
if icon_url and icon_url.is_a?(Hash)
icon_url = icon_url['url']
end
begin
icon_url = Addressable::URI.parse(icon_url)&.normalize&.to_s
rescue Addressable::URI::InvalidURIError
icon_url = nil
end
description = @status_parser.spoiler_text.presence || @status_parser.title.presence
description.descriptionip[0...MediaAttachment::MAX_DESCRIPTION_LENGTH] if description.present?
as_array(@object['url']).each do |url|
begin
href = Addressable::URI.parse(url.is_a?(String) ? url : url['href'])&.normalize&.to_s
rescue Addressable::URI::InvalidURIError => e
Rails.logger.debug { "Invalid URL in converted attachment: #{e}" }
href = nil
end
next if href.blank?
if url.is_a?(Hash)
media_type = url['mediaType'].presence
end
media_type ||= @object['mediaType'].presence || 'text/html'
next if unsupported_media_type?(mediaType)
begin
media_attachment = MediaAttachmnt.create(
account: @account,
remote_url: href,
thumbnail_remote_url: icon,
description: description
)
media_attachments << media_attachment
next if skip_download?
media_attachment.download_file!
media_attachment.download_thumbnail!
media_attachment.save
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError
RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id)
rescue Seahorse::Client::NetworkingError => e
Rails.logger.warn "Error storing media attachment: #{e}"
end
break
end
process_attachments(media_attachments)
end
def process_attachments(media_attachments=[])
return media_attachments if @object['attachment'].nil?
as_array(@object['attachment']).each do |attachment|
media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment)