about summary refs log tree commit diff
path: root/app/services
diff options
context:
space:
mode:
authorClaire <claire.github-309c@sitedethib.com>2022-12-15 20:25:25 +0100
committerClaire <claire.github-309c@sitedethib.com>2022-12-15 20:25:25 +0100
commitf3a4d57be14b40d1e3a6ad9e1a1f9337dafc872e (patch)
tree623c4b710fed94a7280587da7d66863ab489957c /app/services
parent3868ba683d56dbbeecc839fdeaeb7b3d0b18bb9a (diff)
parentf847f67410c75036edb2c4b45d0db048af0481c9 (diff)
Merge branch 'main' into glitch-soc/merge-upstream
Conflicts:
- `README.md`:
  Discarded upstream changes: we have our own README
- `app/controllers/follower_accounts_controller.rb`:
  Port upstream's minor refactoring
Diffstat (limited to 'app/services')
-rw-r--r--app/services/activitypub/process_status_update_service.rb42
-rw-r--r--app/services/post_status_service.rb12
-rw-r--r--app/services/tag_search_service.rb18
3 files changed, 48 insertions, 24 deletions
diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb
index fad19f87f..11b38ab92 100644
--- a/app/services/activitypub/process_status_update_service.rb
+++ b/app/services/activitypub/process_status_update_service.rb
@@ -45,6 +45,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
         create_edits!
       end
 
+      download_media_files!
       queue_poll_notifications!
 
       next unless significant_changes?
@@ -66,12 +67,12 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
   def update_media_attachments!
     previous_media_attachments     = @status.media_attachments.to_a
     previous_media_attachments_ids = @status.ordered_media_attachment_ids || previous_media_attachments.map(&:id)
-    next_media_attachments         = []
+    @next_media_attachments        = []
 
     as_array(@json['attachment']).each do |attachment|
       media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment)
 
-      next if media_attachment_parser.remote_url.blank? || next_media_attachments.size > 4
+      next if media_attachment_parser.remote_url.blank? || @next_media_attachments.size > 4
 
       begin
         media_attachment   = previous_media_attachments.find { |previous_media_attachment| previous_media_attachment.remote_url == media_attachment_parser.remote_url }
@@ -87,34 +88,39 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
         media_attachment.focus                = media_attachment_parser.focus
         media_attachment.thumbnail_remote_url = media_attachment_parser.thumbnail_remote_url
         media_attachment.blurhash             = media_attachment_parser.blurhash
+        media_attachment.status_id            = @status.id
+        media_attachment.skip_download        = unsupported_media_type?(media_attachment_parser.file_content_type) || skip_download?
         media_attachment.save!
 
-        next_media_attachments << media_attachment
-
-        next if unsupported_media_type?(media_attachment_parser.file_content_type) || skip_download?
-
-        begin
-          media_attachment.download_file! if media_attachment.remote_url_previously_changed?
-          media_attachment.download_thumbnail! if media_attachment.thumbnail_remote_url_previously_changed?
-          media_attachment.save
-        rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError
-          RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id)
-        end
+        @next_media_attachments << media_attachment
       rescue Addressable::URI::InvalidURIError => e
         Rails.logger.debug "Invalid URL in attachment: #{e}"
       end
     end
 
-    added_media_attachments = next_media_attachments - previous_media_attachments
+    added_media_attachments = @next_media_attachments - previous_media_attachments
 
-    MediaAttachment.where(id: added_media_attachments.map(&:id)).update_all(status_id: @status.id)
-
-    @status.ordered_media_attachment_ids = next_media_attachments.map(&:id)
-    @status.media_attachments.reload
+    @status.ordered_media_attachment_ids = @next_media_attachments.map(&:id)
 
     @media_attachments_changed = true if @status.ordered_media_attachment_ids != previous_media_attachments_ids
   end
 
+  def download_media_files!
+    @next_media_attachments.each do |media_attachment|
+      next if media_attachment.skip_download
+
+      media_attachment.download_file! if media_attachment.remote_url_previously_changed?
+      media_attachment.download_thumbnail! if media_attachment.thumbnail_remote_url_previously_changed?
+      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
+
+    @status.media_attachments.reload
+  end
+
   def update_poll!(allow_significant_changes: true)
     previous_poll        = @status.preloadable_poll
     @previous_expires_at = previous_poll&.expires_at
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index 36592a531..bcda001f5 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -37,12 +37,15 @@ class PostStatusService < BaseService
       schedule_status!
     else
       process_status!
-      postprocess_status!
-      bump_potential_friendship!
     end
 
     redis.setex(idempotency_key, 3_600, @status.id) if idempotency_given?
 
+    unless scheduled?
+      postprocess_status!
+      bump_potential_friendship!
+    end
+
     @status
   end
 
@@ -75,9 +78,6 @@ class PostStatusService < BaseService
     ApplicationRecord.transaction do
       @status = @account.statuses.create!(status_attributes)
     end
-
-    process_hashtags_service.call(@status)
-    process_mentions_service.call(@status)
   end
 
   def schedule_status!
@@ -101,6 +101,8 @@ class PostStatusService < BaseService
   end
 
   def postprocess_status!
+    process_hashtags_service.call(@status)
+    process_mentions_service.call(@status)
     Trends.tags.register(@status)
     LinkCrawlWorker.perform_async(@status.id)
     DistributionWorker.perform_async(@status.id)
diff --git a/app/services/tag_search_service.rb b/app/services/tag_search_service.rb
index b78d65625..b66ccced9 100644
--- a/app/services/tag_search_service.rb
+++ b/app/services/tag_search_service.rb
@@ -76,11 +76,27 @@ class TagSearchService < BaseService
     definition = TagsIndex.query(query)
     definition = definition.filter(filter) if @options[:exclude_unreviewed]
 
-    definition.limit(@limit).offset(@offset).objects.compact
+    ensure_exact_match(definition.limit(@limit).offset(@offset).objects.compact)
   rescue Faraday::ConnectionFailed, Parslet::ParseFailed
     nil
   end
 
+  # Since the ElasticSearch Query doesn't guarantee the exact match will be the
+  # first result or that it will even be returned, patch the results accordingly
+  def ensure_exact_match(results)
+    return results unless @offset.nil? || @offset.zero?
+
+    normalized_query = Tag.normalize(@query)
+    exact_match = results.find { |tag| tag.name.downcase == normalized_query }
+    exact_match ||= Tag.find_normalized(normalized_query)
+    unless exact_match.nil?
+      results.delete(exact_match)
+      results = [exact_match] + results
+    end
+
+    results
+  end
+
   def from_database
     Tag.search_for(@query, @limit, @offset, @options)
   end