Add optional fetching with processing status references

This commit is contained in:
KMY 2023-09-19 17:53:13 +09:00
parent dc6ad38474
commit ac915654b6
6 changed files with 45 additions and 22 deletions

View file

@ -3,30 +3,39 @@
class ProcessReferencesService < BaseService
include Payloadable
include FormattingHelper
include Redisable
include Lockable
DOMAIN = ENV['WEB_DOMAIN'] || ENV.fetch('LOCAL_DOMAIN', nil)
REFURL_EXP = /(RT|QT|BT|RN|RE)((:|;)?\s+|:|;)(#{URI::DEFAULT_PARSER.make_regexp(%w(http https))})/
MAX_REFERENCES = 5
def call(status, reference_parameters, urls: nil)
def call(status, reference_parameters, urls: nil, fetch_remote: true, no_fetch_urls: nil)
@status = status
@reference_parameters = reference_parameters || []
@urls = urls || []
@no_fetch_urls = no_fetch_urls || []
@fetch_remote = fetch_remote
@again = false
@references_count = old_references.size
with_redis_lock("process_status_refs:#{@status.id}") do
@references_count = old_references.size
return unless added_references.size.positive? || removed_references.size.positive?
if added_references.size.positive? || removed_references.size.positive?
StatusReference.transaction do
remove_old_references
add_references
StatusReference.transaction do
remove_old_references
add_references
@status.save!
end
@status.save!
create_notifications!
end
Rails.cache.delete("status_reference:#{@status.id}")
end
Rails.cache.delete("status_reference:#{@status.id}")
create_notifications!
launch_worker if @again
end
def self.need_process?(status, reference_parameters, urls)
@ -37,13 +46,13 @@ class ProcessReferencesService < BaseService
return unless need_process?(status, reference_parameters, urls)
Rails.cache.write("status_reference:#{status.id}", true, expires_in: 10.minutes)
ProcessReferencesWorker.perform_async(status.id, reference_parameters, urls)
ProcessReferencesWorker.perform_async(status.id, reference_parameters, urls, [])
end
def self.call_service(status, reference_parameters, urls)
return unless need_process?(status, reference_parameters, urls)
ProcessReferencesService.new.call(status, reference_parameters || [], urls: urls || [])
ProcessReferencesService.new.call(status, reference_parameters || [], urls: urls || [], fetch_remote: false)
end
private
@ -65,14 +74,22 @@ class ProcessReferencesService < BaseService
end
def scan_text!
text = @status.account.local? ? @status.text : @status.text.gsub(%r{</?[^>]*>}, '')
@scan_text = fetch_statuses!(text.scan(REFURL_EXP).pluck(3).uniq).map(&:id).uniq.filter { |status_id| !status_id.zero? }
text = extract_status_plain_text(@status)
statuses = fetch_statuses!(text.scan(REFURL_EXP).pluck(3).uniq)
@again = true if !@fetch_remote && statuses.any?(&:nil?)
@scan_text = statuses.compact.map(&:id).uniq.filter { |status_id| !status_id.zero? }
end
def fetch_statuses!(urls)
(urls + @urls)
.map { |url| ResolveURLService.new.call(url, on_behalf_of: @status.account) }
.filter { |status| status }
target_urls = urls + @urls
target_urls.map do |url|
status = ResolveURLService.new.call(url, on_behalf_of: @status.account, fetch_remote: @fetch_remote && @no_fetch_urls.exclude?(url))
@no_fetch_urls << url if !@fetch_remote && status.present?
status
end
end
def add_references
@ -112,4 +129,8 @@ class ProcessReferencesService < BaseService
@references_count -= 1
end
end
def launch_worker
ProcessReferencesWorker.perform_async(@status.id, @reference_parameters, @urls, @no_fetch_urls)
end
end