about summary refs log tree commit diff
path: root/app/services
diff options
context:
space:
mode:
Diffstat (limited to 'app/services')
-rw-r--r--app/services/account_search_service.rb10
-rw-r--r--app/services/activitypub/process_poll_service.rb5
-rw-r--r--app/services/fetch_link_card_service.rb2
-rw-r--r--app/services/follow_service.rb2
-rw-r--r--app/services/move_service.rb32
-rw-r--r--app/services/post_status_service.rb2
-rw-r--r--app/services/search_service.rb3
-rw-r--r--app/services/tag_search_service.rb29
-rw-r--r--app/services/update_account_service.rb4
-rw-r--r--app/services/vote_service.rb32
10 files changed, 95 insertions, 26 deletions
diff --git a/app/services/account_search_service.rb b/app/services/account_search_service.rb
index 01caaefa9..40c5f8590 100644
--- a/app/services/account_search_service.rb
+++ b/app/services/account_search_service.rb
@@ -42,11 +42,9 @@ class AccountSearchService < BaseService
     return [] if limit_for_non_exact_results.zero?
 
     @search_results ||= begin
-      if Chewy.enabled?
-        from_elasticsearch
-      else
-        from_database
-      end
+      results = from_elasticsearch if Chewy.enabled?
+      results ||= from_database
+      results
     end
   end
 
@@ -92,6 +90,8 @@ class AccountSearchService < BaseService
     ActiveRecord::Associations::Preloader.new.preload(records, :account_stat)
 
     records
+  rescue Faraday::ConnectionFailed, Parslet::ParseFailed
+    nil
   end
 
   def reputation_score_function
diff --git a/app/services/activitypub/process_poll_service.rb b/app/services/activitypub/process_poll_service.rb
index 2fbce65b9..cb4a0d460 100644
--- a/app/services/activitypub/process_poll_service.rb
+++ b/app/services/activitypub/process_poll_service.rb
@@ -28,6 +28,8 @@ class ActivityPub::ProcessPollService < BaseService
       end
     end
 
+    voters_count = @json['votersCount']
+
     latest_options = items.map { |item| item['name'].presence || item['content'] }
 
     # If for some reasons the options were changed, it invalidates all previous
@@ -39,7 +41,8 @@ class ActivityPub::ProcessPollService < BaseService
         last_fetched_at: Time.now.utc,
         expires_at: expires_at,
         options: latest_options,
-        cached_tallies: items.map { |item| item.dig('replies', 'totalItems') || 0 }
+        cached_tallies: items.map { |item| item.dig('replies', 'totalItems') || 0 },
+        voters_count: voters_count
       )
     rescue ActiveRecord::StaleObjectError
       poll.reload
diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb
index 4e75c370f..ac5503d46 100644
--- a/app/services/fetch_link_card_service.rb
+++ b/app/services/fetch_link_card_service.rb
@@ -22,7 +22,7 @@ class FetchLinkCardService < BaseService
     RedisLock.acquire(lock_options) do |lock|
       if lock.acquired?
         @card = PreviewCard.find_by(url: @url)
-        process_url if @card.nil? || @card.updated_at <= 2.weeks.ago
+        process_url if @card.nil? || @card.updated_at <= 2.weeks.ago || @card.missing_image?
       else
         raise Mastodon::RaceConditionError
       end
diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb
index 101acdaf9..1941c2e2d 100644
--- a/app/services/follow_service.rb
+++ b/app/services/follow_service.rb
@@ -30,7 +30,7 @@ class FollowService < BaseService
 
     ActivityTracker.increment('activity:interactions')
 
-    if target_account.locked? || target_account.activitypub?
+    if target_account.locked? || source_account.silenced? || target_account.activitypub?
       request_follow(source_account, target_account, reblogs: reblogs)
     elsif target_account.local?
       direct_follow(source_account, target_account, reblogs: reblogs)
diff --git a/app/services/move_service.rb b/app/services/move_service.rb
new file mode 100644
index 000000000..da0c62c4e
--- /dev/null
+++ b/app/services/move_service.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+class MoveService < BaseService
+  def call(migration)
+    @migration      = migration
+    @source_account = migration.account
+    @target_account = migration.target_account
+
+    update_redirect!
+    process_local_relationships!
+    distribute_update!
+    distribute_move!
+  end
+
+  private
+
+  def update_redirect!
+    @source_account.update!(moved_to_account: @target_account)
+  end
+
+  def process_local_relationships!
+    MoveWorker.perform_async(@source_account.id, @target_account.id)
+  end
+
+  def distribute_update!
+    ActivityPub::UpdateDistributionWorker.perform_async(@source_account.id)
+  end
+
+  def distribute_move!
+    ActivityPub::MoveDistributionWorker.perform_async(@migration.id)
+  end
+end
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index 5d17f111b..936e6ac55 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -184,7 +184,7 @@ class PostStatusService < BaseService
   def poll_attributes
     return if @options[:poll].blank?
 
-    @options[:poll].merge(account: @account)
+    @options[:poll].merge(account: @account, voters_count: 0)
   end
 
   def scheduled_options
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index a5ba5dd11..3a498dcf4 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -60,7 +60,8 @@ class SearchService < BaseService
     TagSearchService.new.call(
       @query,
       limit: @limit,
-      offset: @offset
+      offset: @offset,
+      exclude_unreviewed: @options[:exclude_unreviewed]
     )
   end
 
diff --git a/app/services/tag_search_service.rb b/app/services/tag_search_service.rb
index 64dd76bb7..b78d65625 100644
--- a/app/services/tag_search_service.rb
+++ b/app/services/tag_search_service.rb
@@ -2,15 +2,15 @@
 
 class TagSearchService < BaseService
   def call(query, options = {})
-    @query  = query.strip.gsub(/\A#/, '')
-    @offset = options[:offset].to_i
-    @limit  = options[:limit].to_i
+    @query   = query.strip.gsub(/\A#/, '')
+    @offset  = options.delete(:offset).to_i
+    @limit   = options.delete(:limit).to_i
+    @options = options
 
-    if Chewy.enabled?
-      from_elasticsearch
-    else
-      from_database
-    end
+    results   = from_elasticsearch if Chewy.enabled?
+    results ||= from_database
+
+    results
   end
 
   private
@@ -63,9 +63,9 @@ class TagSearchService < BaseService
           },
 
           {
-            term: {
+            match: {
               name: {
-                value: @query,
+                query: @query,
               },
             },
           },
@@ -73,10 +73,15 @@ class TagSearchService < BaseService
       },
     }
 
-    TagsIndex.query(query).filter(filter).limit(@limit).offset(@offset).objects.compact
+    definition = TagsIndex.query(query)
+    definition = definition.filter(filter) if @options[:exclude_unreviewed]
+
+    definition.limit(@limit).offset(@offset).objects.compact
+  rescue Faraday::ConnectionFailed, Parslet::ParseFailed
+    nil
   end
 
   def from_database
-    Tag.search_for(@query, @limit, @offset)
+    Tag.search_for(@query, @limit, @offset, @options)
   end
 end
diff --git a/app/services/update_account_service.rb b/app/services/update_account_service.rb
index 01756a73d..ebf24be37 100644
--- a/app/services/update_account_service.rb
+++ b/app/services/update_account_service.rb
@@ -20,7 +20,9 @@ class UpdateAccountService < BaseService
   private
 
   def authorize_all_follow_requests(account)
-    AuthorizeFollowWorker.push_bulk(FollowRequest.where(target_account: account).select(:account_id, :target_account_id)) do |req|
+    follow_requests = FollowRequest.where(target_account: account)
+    follow_requests = follow_requests.select { |req| !req.account.silenced? }
+    AuthorizeFollowWorker.push_bulk(follow_requests) do |req|
       [req.account_id, req.target_account_id]
     end
   end
diff --git a/app/services/vote_service.rb b/app/services/vote_service.rb
index 0eeb8fd56..cb7dce6e8 100644
--- a/app/services/vote_service.rb
+++ b/app/services/vote_service.rb
@@ -12,12 +12,24 @@ class VoteService < BaseService
     @choices = choices
     @votes   = []
 
-    ApplicationRecord.transaction do
-      @choices.each do |choice|
-        @votes << @poll.votes.create!(account: @account, choice: choice)
+    already_voted = true
+
+    RedisLock.acquire(lock_options) do |lock|
+      if lock.acquired?
+        already_voted = @poll.votes.where(account: @account).exists?
+
+        ApplicationRecord.transaction do
+          @choices.each do |choice|
+            @votes << @poll.votes.create!(account: @account, choice: choice)
+          end
+        end
+      else
+        raise Mastodon::RaceConditionError
       end
     end
 
+    increment_voters_count! unless already_voted
+
     ActivityTracker.increment('activity:interactions')
 
     if @poll.account.local?
@@ -53,4 +65,18 @@ class VoteService < BaseService
   def build_json(vote)
     Oj.dump(serialize_payload(vote, ActivityPub::VoteSerializer))
   end
+
+  def increment_voters_count!
+    unless @poll.voters_count.nil?
+      @poll.voters_count = @poll.voters_count + 1
+      @poll.save
+    end
+  rescue ActiveRecord::StaleObjectError
+    @poll.reload
+    retry
+  end
+
+  def lock_options
+    { redis: Redis.current, key: "vote:#{@poll.id}:#{@account.id}" }
+  end
 end