From a5384b45e3d8e50ee4b4726bb54b7e0f4b9ccd9f Mon Sep 17 00:00:00 2001
From: noellabo <noel.yoshiba@gmail.com>
Date: Fri, 29 Nov 2019 12:10:59 +0900
Subject: [PATCH] Apply quote by parsing post body

---
 app/lib/activitypub/activity/create.rb | 16 +++++++++++++++-
 app/services/post_status_service.rb    | 16 ++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 622f4361a3..a68ef003e5 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -38,6 +38,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     @mentions = []
     @params   = {}
 
+    process_quote
     process_status_params
     process_tags
     process_audience
@@ -78,7 +79,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
         conversation: conversation_from_uri(@object['conversation']),
         media_attachment_ids: process_attachments.take(4).map(&:id),
         poll: process_poll,
-        quote: quote_from_url(@object['quoteUrl'] || @object['_misskey_quote']),
+        quote: quote,
       }
     end
   end
@@ -461,9 +462,22 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
     { redis: Redis.current, key: "vote:#{replied_to_status.poll_id}:#{@account.id}" }
   end
 
+  def quote
+    @quote ||= quote_from_url(@object['quoteUrl'] || @object['_misskey_quote'])
+  end
+
+  def process_quote
+    if quote.nil? && md = @object['content'].match(/QT:\s*\[<a href=\"([^\"]+).*?\]/)
+      @quote = quote_from_url(md[1])
+      @object['content'] = @object['content'].sub(/QT:\s*\[.*?\]/, '<span class="quote-inline"><br/>\1</span>')
+    end
+  end
+
   def quote_from_url(url)
     return nil if url.nil?
     quote = ResolveURLService.new.call(url)
     status_from_uri(quote.uri) if quote
+  rescue
+    nil
   end
 end
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index 6e78c91f82..3ebe94f62c 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -46,12 +46,28 @@ class PostStatusService < BaseService
 
   private
 
+  def status_from_uri(uri)
+    ActivityPub::TagManager.instance.uri_to_resource(uri, Status)
+  end
+
+  def quote_from_url(url)
+    return nil if url.nil?
+    quote = ResolveURLService.new.call(url)
+    status_from_uri(quote.uri) if quote
+  rescue
+    nil
+  end
+
   def preprocess_attributes!
     @text         = @options.delete(:spoiler_text) if @text.blank? && @options[:spoiler_text].present?
     @visibility   = @options[:visibility] || @account.user&.setting_default_privacy
     @visibility   = :unlisted if @visibility == :public && @account.silenced?
     @scheduled_at = @options[:scheduled_at]&.to_datetime
     @scheduled_at = nil if scheduled_in_the_past?
+    if @options[:quote_id].nil? && md = @text.match(/QT:\s*\[\s*(https:\/\/.+?)\s*\]/)
+      @options[:quote_id] = quote_from_url(md[1])&.id
+      @text.sub!(/QT:\s*\[.*?\]/, '')
+    end
   rescue ArgumentError
     raise ActiveRecord::RecordInvalid
   end
-- 
GitLab