about summary refs log tree commit diff
path: root/app/lib/activitypub/activity/create.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/lib/activitypub/activity/create.rb')
-rw-r--r--app/lib/activitypub/activity/create.rb46
1 files changed, 34 insertions, 12 deletions
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 9a34484f5..41f2b0bad 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
+
+    @status
+  end
 
-    return status unless status.nil?
+  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,6 +61,8 @@ 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
@@ -74,6 +81,17 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     account.mentions.create(status: status)
   end
 
+  def process_emoji(tag, _status)
+    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)
 
@@ -182,4 +200,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