diff options
author | beatrix <beatrix.bitrot@gmail.com> | 2017-09-28 21:48:28 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-28 21:48:28 -0400 |
commit | c027a7bd4d7b5af21f4b201d656f7251fa3606a1 (patch) | |
tree | ce2c2327b26358c26cb899ea918988af373ca6d6 /app/lib/activitypub | |
parent | 210e6776fce016666ecfd248b2208c487f3440f9 (diff) | |
parent | 53f829dfa8bc376041a442dc84c22aa1cbfcb9d0 (diff) |
Merge pull request #157 from glitch-soc/merging-upstream
ABRACA-HRRRRRRRRRRRNGGGGGGGHHH!!!!!!!!!!!!!!!!!!!
Diffstat (limited to 'app/lib/activitypub')
-rw-r--r-- | app/lib/activitypub/activity/announce.rb | 9 | ||||
-rw-r--r-- | app/lib/activitypub/activity/create.rb | 60 | ||||
-rw-r--r-- | app/lib/activitypub/adapter.rb | 6 | ||||
-rw-r--r-- | app/lib/activitypub/tag_manager.rb | 6 |
4 files changed, 60 insertions, 21 deletions
diff --git a/app/lib/activitypub/activity/announce.rb b/app/lib/activitypub/activity/announce.rb index c4da405c7..4516454e1 100644 --- a/app/lib/activitypub/activity/announce.rb +++ b/app/lib/activitypub/activity/announce.rb @@ -11,7 +11,12 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity return status unless status.nil? - status = Status.create!(account: @account, reblog: original_status, uri: @json['id']) + status = Status.create!( + account: @account, + reblog: original_status, + uri: @json['id'], + created_at: @json['published'] || Time.now.utc + ) distribute(status) status end @@ -20,6 +25,8 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity def fetch_remote_original_status if object_uri.start_with?('http') + return if ActivityPub::TagManager.instance.local_uri?(object_uri) + ActivityPub::FetchRemoteStatusService.new.call(object_uri) elsif @object['url'].present? ::FetchRemoteStatusService.new.call(@object['url']) diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 9a34484f5..4e19b3096 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -4,26 +4,31 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def perform return if delete_arrived_first?(object_uri) || unsupported_object_type? - status = find_existing_status + RedisLock.acquire(lock_options) do |lock| + if lock.acquired? + @status = find_existing_status + process_status if @status.nil? + end + end - return status unless status.nil? + @status + end + + private + def process_status ApplicationRecord.transaction do - status = Status.create!(status_params) + @status = Status.create!(status_params) - process_tags(status) - process_attachments(status) + process_tags(@status) + process_attachments(@status) end - resolve_thread(status) - distribute(status) - forward_for_reply if status.public_visibility? || status.unlisted_visibility? - - status + resolve_thread(@status) + distribute(@status) + forward_for_reply if @status.public_visibility? || @status.unlisted_visibility? end - private - def find_existing_status status = status_from_uri(object_uri) status ||= Status.find_by(uri: @object['atomUri']) if @object['atomUri'].present? @@ -56,11 +61,15 @@ class ActivityPub::Activity::Create < ActivityPub::Activity process_hashtag tag, status when 'Mention' process_mention tag, status + when 'Emoji' + process_emoji tag, status end end end def process_hashtag(tag, status) + return if tag['name'].blank? + hashtag = tag['name'].gsub(/\A#/, '').mb_chars.downcase hashtag = Tag.where(name: hashtag).first_or_initialize(name: hashtag) @@ -68,17 +77,32 @@ class ActivityPub::Activity::Create < ActivityPub::Activity end def process_mention(tag, status) + return if tag['href'].blank? + account = account_from_uri(tag['href']) account = FetchRemoteAccountService.new.call(tag['href']) if account.nil? return if account.nil? account.mentions.create(status: status) end + def process_emoji(tag, _status) + return if tag['name'].blank? || tag['href'].blank? + + shortcode = tag['name'].delete(':') + emoji = CustomEmoji.find_by(shortcode: shortcode, domain: @account.domain) + + return if !emoji.nil? || skip_download? + + emoji = CustomEmoji.new(domain: @account.domain, shortcode: shortcode) + emoji.image_remote_url = tag['href'] + emoji.save + end + def process_attachments(status) return unless @object['attachment'].is_a?(Array) @object['attachment'].each do |attachment| - next if unsupported_media_type?(attachment['mediaType']) + next if unsupported_media_type?(attachment['mediaType']) || attachment['url'].blank? href = Addressable::URI.parse(attachment['url']).normalize.to_s media_attachment = MediaAttachment.create(status: status, account: status.account, remote_url: href) @@ -88,6 +112,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity media_attachment.file_remote_url = href media_attachment.save end + rescue Addressable::URI::InvalidURIError => e + Rails.logger.debug e end def resolve_thread(status) @@ -97,8 +123,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def conversation_from_uri(uri) return nil if uri.nil? - return Conversation.find_by(id: TagManager.instance.unique_tag_to_local_id(uri, 'Conversation')) if TagManager.instance.local_id?(uri) - Conversation.find_by(uri: uri) || Conversation.create!(uri: uri) + return Conversation.find_by(id: OStatus::TagManager.instance.unique_tag_to_local_id(uri, 'Conversation')) if OStatus::TagManager.instance.local_id?(uri) + Conversation.find_by(uri: uri) || Conversation.create(uri: uri) end def visibility_from_audience @@ -182,4 +208,8 @@ class ActivityPub::Activity::Create < ActivityPub::Activity return unless @json['signature'].present? && reply_to_local? ActivityPub::RawDistributionWorker.perform_async(Oj.dump(@json), replied_to_status.account_id) end + + def lock_options + { redis: Redis.current, key: "create:#{@object['id']}" } + end end diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb index 6ed66a239..790d2025c 100644 --- a/app/lib/activitypub/adapter.rb +++ b/app/lib/activitypub/adapter.rb @@ -14,6 +14,8 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base 'atomUri' => 'ostatus:atomUri', 'inReplyToAtomUri' => 'ostatus:inReplyToAtomUri', 'conversation' => 'ostatus:conversation', + 'toot' => 'http://joinmastodon.org/ns#', + 'Emoji' => 'toot:Emoji', }, ], }.freeze @@ -28,7 +30,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base def serializable_hash(options = nil) options = serialization_options(options) - serialized_hash = CONTEXT.merge(ActiveModelSerializers::Adapter::Attributes.new(serializer, instance_options).serializable_hash(options)) - self.class.transform_key_casing!(serialized_hash, instance_options) + serialized_hash = ActiveModelSerializers::Adapter::Attributes.new(serializer, instance_options).serializable_hash(options) + CONTEXT.merge(self.class.transform_key_casing!(serialized_hash, instance_options)) end end diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index 929e87852..4ec3b8c56 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -37,7 +37,7 @@ class ActivityPub::TagManager end def activity_uri_for(target) - return nil unless %i(note comment activity).include?(target.object_type) && target.local? + raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local? activity_account_status_url(target.account, target) end @@ -98,8 +98,8 @@ class ActivityPub::TagManager else StatusFinder.new(uri).status end - elsif ::TagManager.instance.local_id?(uri) - klass.find_by(id: ::TagManager.instance.unique_tag_to_local_id(uri, klass.to_s)) + elsif OStatus::TagManager.instance.local_id?(uri) + klass.find_by(id: OStatus::TagManager.instance.unique_tag_to_local_id(uri, klass.to_s)) else klass.find_by(uri: uri.split('#').first) end |