about summary refs log tree commit diff
path: root/app/models/public_feed.rb
diff options
context:
space:
mode:
authorThibaut Girka <thib@sitedethib.com>2020-09-08 16:01:55 +0200
committerThibaut Girka <thib@sitedethib.com>2020-09-08 16:26:47 +0200
commit9748f074a385fce5ad6913b1a22fb7ea9e7566db (patch)
treeccd775be4b73170fcbf45407b84ad35fc37fb853 /app/models/public_feed.rb
parent437d71bddf967573df3912ee5976f7c5a5a7b4c7 (diff)
parent65760f59df46e388919a9f7ccba1958d967b2695 (diff)
Merge branch 'master' into glitch-soc/merge-upstream
Conflicts:
- app/controllers/api/v1/timelines/public_controller.rb
- app/lib/feed_manager.rb
- app/models/status.rb
- app/services/precompute_feed_service.rb
- app/workers/feed_insert_worker.rb
- spec/models/status_spec.rb

All conflicts are due to upstream refactoring feed management and us having
local-only toots on top of that. Rewrote local-only toots management for
upstream's changes.
Diffstat (limited to 'app/models/public_feed.rb')
-rw-r--r--app/models/public_feed.rb104
1 files changed, 104 insertions, 0 deletions
diff --git a/app/models/public_feed.rb b/app/models/public_feed.rb
new file mode 100644
index 000000000..2839da5cb
--- /dev/null
+++ b/app/models/public_feed.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+class PublicFeed < Feed
+  # @param [Account] account
+  # @param [Hash] options
+  # @option [Boolean] :with_replies
+  # @option [Boolean] :with_reblogs
+  # @option [Boolean] :local
+  # @option [Boolean] :remote
+  # @option [Boolean] :only_media
+  # @option [Boolean] :allow_local_only
+  def initialize(account, options = {})
+    @account = account
+    @options = options
+  end
+
+  # @param [Integer] limit
+  # @param [Integer] max_id
+  # @param [Integer] since_id
+  # @param [Integer] min_id
+  # @return [Array<Status>]
+  def get(limit, max_id = nil, since_id = nil, min_id = nil)
+    scope = public_scope
+
+    scope.merge!(without_local_only_scope) unless allow_local_only?
+    scope.merge!(without_replies_scope) unless with_replies?
+    scope.merge!(without_reblogs_scope) unless with_reblogs?
+    scope.merge!(local_only_scope) if local_only?
+    scope.merge!(remote_only_scope) if remote_only?
+    scope.merge!(account_filters_scope) if account?
+    scope.merge!(media_only_scope) if media_only?
+
+    scope.cache_ids.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id)
+  end
+
+  private
+
+  def allow_local_only?
+    local_account? && (local_only? || @options[:allow_local_only])
+  end
+
+  def with_reblogs?
+    @options[:with_reblogs]
+  end
+
+  def with_replies?
+    @options[:with_replies]
+  end
+
+  def local_only?
+    @options[:local]
+  end
+
+  def remote_only?
+    @options[:remote]
+  end
+
+  def account?
+    @account.present?
+  end
+
+  def local_account?
+    @account&.local?
+  end
+
+  def media_only?
+    @options[:only_media]
+  end
+
+  def public_scope
+    Status.with_public_visibility.joins(:account).merge(Account.without_suspended.without_silenced)
+  end
+
+  def local_only_scope
+    Status.local
+  end
+
+  def remote_only_scope
+    Status.remote
+  end
+
+  def without_replies_scope
+    Status.without_replies
+  end
+
+  def without_reblogs_scope
+    Status.without_reblogs
+  end
+
+  def media_only_scope
+    Status.joins(:media_attachments).group(:id)
+  end
+
+  def without_local_only_scope
+    Status.not_local_only
+  end
+
+  def account_filters_scope
+    Status.not_excluded_by_account(@account).tap do |scope|
+      scope.merge!(Status.not_domain_blocked_by_account(@account)) unless local_only?
+      scope.merge!(Status.in_chosen_languages(@account)) if @account.chosen_languages.present?
+    end
+  end
+end