about summary refs log tree commit diff
path: root/app/services
diff options
context:
space:
mode:
authorStarfall <us@starfall.systems>2021-05-11 11:19:04 -0500
committerStarfall <us@starfall.systems>2021-05-11 11:19:04 -0500
commitd56731a0b9d73c48bbfbced8732e25587ba892a4 (patch)
treed3830ce2e0292ce07336496e40882c222f455a33 /app/services
parent459a36ab7303db4ee59945b4b2121b25cc86eb38 (diff)
parentffc3f8eebe134ca9b18af73aa29eaa1627082e40 (diff)
Merge branch 'glitch'
Diffstat (limited to 'app/services')
-rw-r--r--app/services/activitypub/fetch_remote_key_service.rb2
-rw-r--r--app/services/activitypub/process_account_service.rb3
-rw-r--r--app/services/after_block_service.rb5
-rw-r--r--app/services/bootstrap_timeline_service.rb37
-rw-r--r--app/services/follow_service.rb9
-rw-r--r--app/services/process_hashtags_service.rb3
-rw-r--r--app/services/process_mentions_service.rb5
-rw-r--r--app/services/reblog_service.rb11
-rw-r--r--app/services/remove_status_service.rb41
-rw-r--r--app/services/report_service.rb2
-rw-r--r--app/services/resolve_account_service.rb2
-rw-r--r--app/services/suspend_account_service.rb12
-rw-r--r--app/services/unsuspend_account_service.rb15
13 files changed, 67 insertions, 80 deletions
diff --git a/app/services/activitypub/fetch_remote_key_service.rb b/app/services/activitypub/fetch_remote_key_service.rb
index df17d9079..c48288b3b 100644
--- a/app/services/activitypub/fetch_remote_key_service.rb
+++ b/app/services/activitypub/fetch_remote_key_service.rb
@@ -5,6 +5,8 @@ class ActivityPub::FetchRemoteKeyService < BaseService
 
   # Returns account that owns the key
   def call(uri, id: true, prefetched_body: nil)
+    return if uri.blank?
+
     if prefetched_body.nil?
       if id
         @json = fetch_resource_without_id_validation(uri)
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
index 27b088240..2c80175e7 100644
--- a/app/services/activitypub/process_account_service.rb
+++ b/app/services/activitypub/process_account_service.rb
@@ -88,6 +88,7 @@ class ActivityPub::ProcessAccountService < BaseService
     @account.url                     = url || @uri
     @account.uri                     = @uri
     @account.actor_type              = actor_type
+    @account.created_at              = @json['published'] if @json['published'].present?
   end
 
   def set_immediate_attributes!
@@ -102,7 +103,7 @@ class ActivityPub::ProcessAccountService < BaseService
   end
 
   def set_fetchable_key!
-    @account.public_key        = public_key || ''
+    @account.public_key = public_key || ''
   end
 
   def set_fetchable_attributes!
diff --git a/app/services/after_block_service.rb b/app/services/after_block_service.rb
index 314919df8..899e84be4 100644
--- a/app/services/after_block_service.rb
+++ b/app/services/after_block_service.rb
@@ -6,6 +6,7 @@ class AfterBlockService < BaseService
     @target_account = target_account
 
     clear_home_feed!
+    clear_list_feeds!
     clear_notifications!
     clear_conversations!
   end
@@ -16,6 +17,10 @@ class AfterBlockService < BaseService
     FeedManager.instance.clear_from_home(@account, @target_account)
   end
 
+  def clear_list_feeds!
+    FeedManager.instance.clear_from_lists(@account, @target_account)
+  end
+
   def clear_conversations!
     AccountConversation.where(account: @account).where('? = ANY(participant_account_ids)', @target_account.id).in_batches.destroy_all
   end
diff --git a/app/services/bootstrap_timeline_service.rb b/app/services/bootstrap_timeline_service.rb
index 8412aa7e7..e1a1b98c3 100644
--- a/app/services/bootstrap_timeline_service.rb
+++ b/app/services/bootstrap_timeline_service.rb
@@ -5,48 +5,13 @@ class BootstrapTimelineService < BaseService
     @source_account = source_account
 
     autofollow_inviter!
-    autofollow_bootstrap_timeline_accounts! if Setting.enable_bootstrap_timeline_accounts
   end
 
   private
 
   def autofollow_inviter!
     return unless @source_account&.user&.invite&.autofollow?
-    FollowService.new.call(@source_account, @source_account.user.invite.user.account)
-  end
-
-  def autofollow_bootstrap_timeline_accounts!
-    bootstrap_timeline_accounts.each do |target_account|
-      begin
-        FollowService.new.call(@source_account, target_account)
-      rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
-        nil
-      end
-    end
-  end
-
-  def bootstrap_timeline_accounts
-    return @bootstrap_timeline_accounts if defined?(@bootstrap_timeline_accounts)
-
-    @bootstrap_timeline_accounts = bootstrap_timeline_accounts_usernames.empty? ? admin_accounts : local_unlocked_accounts(bootstrap_timeline_accounts_usernames)
-  end
-
-  def bootstrap_timeline_accounts_usernames
-    @bootstrap_timeline_accounts_usernames ||= (Setting.bootstrap_timeline_accounts || '').split(',').map { |str| str.strip.gsub(/\A@/, '') }.reject(&:blank?)
-  end
 
-  def admin_accounts
-    User.admins
-        .includes(:account)
-        .where(accounts: { locked: false })
-        .map(&:account)
-  end
-
-  def local_unlocked_accounts(usernames)
-    Account.local
-           .without_suspended
-           .where(username: usernames)
-           .where(locked: false)
-           .where(moved_to_account_id: nil)
+    FollowService.new.call(@source_account, @source_account.user.invite.user.account)
   end
 end
diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb
index d3db07a74..329262cca 100644
--- a/app/services/follow_service.rb
+++ b/app/services/follow_service.rb
@@ -30,6 +30,11 @@ class FollowService < BaseService
 
     ActivityTracker.increment('activity:interactions')
 
+    # When an account follows someone for the first time, avoid showing
+    # an empty home feed while the follow request is being processed
+    # and the feeds are being merged
+    mark_home_feed_as_partial! if @source_account.not_following_anyone?
+
     if (@target_account.locked? && !@options[:bypass_locked]) || @source_account.silenced? || @target_account.activitypub?
       request_follow!
     elsif @target_account.local?
@@ -39,6 +44,10 @@ class FollowService < BaseService
 
   private
 
+  def mark_home_feed_as_partial!
+    redis.set("account:#{@source_account.id}:regeneration", true, nx: true, ex: 1.day.seconds)
+  end
+
   def following_not_possible?
     @target_account.nil? || @target_account.id == @source_account.id || @target_account.suspended?
   end
diff --git a/app/services/process_hashtags_service.rb b/app/services/process_hashtags_service.rb
index e8e139b05..c42b79db8 100644
--- a/app/services/process_hashtags_service.rb
+++ b/app/services/process_hashtags_service.rb
@@ -8,8 +8,7 @@ class ProcessHashtagsService < BaseService
     Tag.find_or_create_by_names(tags) do |tag|
       status.tags << tag
       records << tag
-
-      TrendingTags.record_use!(tag, status.account, status.created_at) if status.public_visibility?
+      tag.use!(status.account, status: status, at_time: status.created_at) if status.public_visibility?
     end
 
     return unless status.distributable?
diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb
index 570cd8272..ec4cb11f9 100644
--- a/app/services/process_mentions_service.rb
+++ b/app/services/process_mentions_service.rb
@@ -43,7 +43,6 @@ class ProcessMentionsService < BaseService
     end
 
     status.save!
-    check_for_spam(status)
 
     mentions.each { |mention| create_notification(mention) }
   end
@@ -72,8 +71,4 @@ class ProcessMentionsService < BaseService
   def resolve_account_service
     ResolveAccountService.new
   end
-
-  def check_for_spam(status)
-    SpamCheck.perform(status)
-  end
 end
diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb
index 6f018e24b..f41276de0 100644
--- a/app/services/reblog_service.rb
+++ b/app/services/reblog_service.rb
@@ -35,6 +35,7 @@ class ReblogService < BaseService
 
     create_notification(reblog)
     bump_potential_friendship(account, reblog)
+    record_use(account, reblog)
 
     reblog
   end
@@ -59,6 +60,16 @@ class ReblogService < BaseService
     PotentialFriendshipTracker.record(account.id, reblog.reblog.account_id, :reblog)
   end
 
+  def record_use(account, reblog)
+    return unless reblog.public_visibility?
+
+    original_status = reblog.reblog
+
+    original_status.tags.each do |tag|
+      tag.use!(account)
+    end
+  end
+
   def build_json(reblog)
     Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_status(reblog), ActivityPub::ActivitySerializer, signer: reblog.account))
   end
diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb
index 764ed288d..5cc1dba06 100644
--- a/app/services/remove_status_service.rb
+++ b/app/services/remove_status_service.rb
@@ -16,6 +16,8 @@ class RemoveStatusService < BaseService
     @account  = status.account
     @options  = options
 
+    @status.discard
+
     RedisLock.acquire(lock_options) do |lock|
       if lock.acquired?
         remove_from_self if @account.local?
@@ -27,10 +29,7 @@ class RemoveStatusService < BaseService
         # original object being removed implicitly removes reblogs
         # of it. The Delete activity of the original is forwarded
         # separately.
-        if @account.local? && !@options[:original_removed]
-          remove_from_remote_followers
-          remove_from_remote_reach
-        end
+        remove_from_remote_reach if @account.local? && !@options[:original_removed]
 
         # Since reblogs don't mention anyone, don't get reblogged,
         # favourited and don't contain their own media attachments
@@ -42,7 +41,6 @@ class RemoveStatusService < BaseService
           remove_from_public
           remove_from_media if @status.media_attachments.any?
           remove_from_direct if status.direct_visibility?
-          remove_from_spam_check
           remove_media
         end
 
@@ -85,13 +83,10 @@ class RemoveStatusService < BaseService
   end
 
   def remove_from_remote_reach
-    return if @status.reblog?
-
-    # People who got mentioned in the status, or who
-    # reblogged it from someone else might not follow
-    # the author and wouldn't normally receive the
-    # delete notification - so here, we explicitly
-    # send it to them
+    # Followers, relays, people who got mentioned in the status,
+    # or who reblogged it from someone else might not follow
+    # the author and wouldn't normally receive the delete
+    # notification - so here, we explicitly send it to them
 
     status_reach_finder = StatusReachFinder.new(@status)
 
@@ -100,24 +95,6 @@ class RemoveStatusService < BaseService
     end
   end
 
-  def remove_from_remote_followers
-    ActivityPub::DeliveryWorker.push_bulk(@account.followers.inboxes) do |inbox_url|
-      [signed_activity_json, @account.id, inbox_url]
-    end
-
-    relay! if relayable?
-  end
-
-  def relayable?
-    @status.public_visibility?
-  end
-
-  def relay!
-    ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
-      [signed_activity_json, @account.id, inbox_url]
-    end
-  end
-
   def signed_activity_json
     @signed_activity_json ||= Oj.dump(serialize_payload(@status, @status.reblog? ? ActivityPub::UndoAnnounceSerializer : ActivityPub::DeleteSerializer, signer: @account))
   end
@@ -171,10 +148,6 @@ class RemoveStatusService < BaseService
     @status.media_attachments.destroy_all
   end
 
-  def remove_from_spam_check
-    redis.zremrangebyscore("spam_check:#{@status.account_id}", @status.id, @status.id)
-  end
-
   def lock_options
     { redis: Redis.current, key: "distribute:#{@status.id}" }
   end
diff --git a/app/services/report_service.rb b/app/services/report_service.rb
index 9d9c7d6c9..bc0a8b464 100644
--- a/app/services/report_service.rb
+++ b/app/services/report_service.rb
@@ -10,6 +10,8 @@ class ReportService < BaseService
     @comment        = options.delete(:comment) || ''
     @options        = options
 
+    raise ActiveRecord::RecordNotFound if @target_account.suspended?
+
     create_report!
     notify_staff!
     forward_to_origin! if !@target_account.local? && ActiveModel::Type::Boolean.new.cast(@options[:forward])
diff --git a/app/services/resolve_account_service.rb b/app/services/resolve_account_service.rb
index b8ddeb2ad..493995447 100644
--- a/app/services/resolve_account_service.rb
+++ b/app/services/resolve_account_service.rb
@@ -122,7 +122,7 @@ class ResolveAccountService < BaseService
     return false if @options[:check_delivery_availability] && !DeliveryFailureTracker.available?(@domain)
     return false if @options[:skip_webfinger]
 
-    @account.nil? || (@account.ostatus? && @account.possibly_stale?)
+    @account.nil? || @account.possibly_stale?
   end
 
   def activitypub_ready?
diff --git a/app/services/suspend_account_service.rb b/app/services/suspend_account_service.rb
index 9f4da91d4..b8dc8d5e0 100644
--- a/app/services/suspend_account_service.rb
+++ b/app/services/suspend_account_service.rb
@@ -42,7 +42,13 @@ class SuspendAccountService < BaseService
   end
 
   def distribute_update_actor!
-    ActivityPub::UpdateDistributionWorker.perform_async(@account.id) if @account.local?
+    return unless @account.local?
+
+    account_reach_finder = AccountReachFinder.new(@account)
+
+    ActivityPub::DeliveryWorker.push_bulk(account_reach_finder.inboxes) do |inbox_url|
+      [signed_activity_json, @account.id, inbox_url]
+    end
   end
 
   def unmerge_from_home_timelines!
@@ -90,4 +96,8 @@ class SuspendAccountService < BaseService
       end
     end
   end
+
+  def signed_activity_json
+    @signed_activity_json ||= Oj.dump(serialize_payload(@account, ActivityPub::UpdateSerializer, signer: @account))
+  end
 end
diff --git a/app/services/unsuspend_account_service.rb b/app/services/unsuspend_account_service.rb
index ce9ee48ed..949c670aa 100644
--- a/app/services/unsuspend_account_service.rb
+++ b/app/services/unsuspend_account_service.rb
@@ -12,6 +12,7 @@ class UnsuspendAccountService < BaseService
     merge_into_home_timelines!
     merge_into_list_timelines!
     publish_media_attachments!
+    distribute_update_actor!
   end
 
   private
@@ -36,6 +37,16 @@ class UnsuspendAccountService < BaseService
     # @account would now be nil.
   end
 
+  def distribute_update_actor!
+    return unless @account.local?
+
+    account_reach_finder = AccountReachFinder.new(@account)
+
+    ActivityPub::DeliveryWorker.push_bulk(account_reach_finder.inboxes) do |inbox_url|
+      [signed_activity_json, @account.id, inbox_url]
+    end
+  end
+
   def merge_into_home_timelines!
     @account.followers_for_local_distribution.find_each do |follower|
       FeedManager.instance.merge_into_home(@account, follower)
@@ -81,4 +92,8 @@ class UnsuspendAccountService < BaseService
       end
     end
   end
+
+  def signed_activity_json
+    @signed_activity_json ||= Oj.dump(serialize_payload(@account, ActivityPub::UpdateSerializer, signer: @account))
+  end
 end