relationship_filter.rb 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. # frozen_string_literal: true
  2. class RelationshipFilter
  3. KEYS = %i(
  4. relationship
  5. status
  6. by_domain
  7. activity
  8. order
  9. location
  10. ).freeze
  11. IGNORED_PARAMS = %w(relationship page).freeze
  12. attr_reader :params, :account
  13. def initialize(account, params)
  14. @account = account
  15. @params = params
  16. set_defaults!
  17. end
  18. def results
  19. scope = scope_for('relationship', params['relationship'].to_s.strip)
  20. params.each do |key, value|
  21. next if IGNORED_PARAMS.include?(key)
  22. scope.merge!(scope_for(key.to_s, value.to_s.strip)) if value.present?
  23. end
  24. scope
  25. end
  26. private
  27. def set_defaults!
  28. params['relationship'] = 'following' if params['relationship'].blank?
  29. params['order'] = 'recent' if params['order'].blank?
  30. end
  31. def scope_for(key, value)
  32. case key
  33. when 'relationship'
  34. relationship_scope(value)
  35. when 'by_domain'
  36. by_domain_scope(value)
  37. when 'location'
  38. location_scope(value)
  39. when 'status'
  40. status_scope(value)
  41. when 'order'
  42. order_scope(value)
  43. when 'activity'
  44. activity_scope(value)
  45. else
  46. raise Mastodon::InvalidParameterError, "Unknown filter: #{key}"
  47. end
  48. end
  49. def relationship_scope(value)
  50. case value
  51. when 'following'
  52. account.following.includes(:account_stat).reorder(nil)
  53. when 'followed_by'
  54. account.followers.includes(:account_stat).reorder(nil)
  55. when 'mutual'
  56. account.followers.includes(:account_stat).reorder(nil).merge(Account.where(id: account.following))
  57. when 'invited'
  58. Account.joins(user: :invite).merge(Invite.where(user: account.user)).includes(:account_stat).reorder(nil)
  59. else
  60. raise Mastodon::InvalidParameterError, "Unknown relationship: #{value}"
  61. end
  62. end
  63. def by_domain_scope(value)
  64. Account.where(domain: value)
  65. end
  66. def location_scope(value)
  67. case value
  68. when 'local'
  69. Account.local
  70. when 'remote'
  71. Account.remote
  72. else
  73. raise Mastodon::InvalidParameterError, "Unknown location: #{value}"
  74. end
  75. end
  76. def status_scope(value)
  77. case value
  78. when 'moved'
  79. Account.where.not(moved_to_account_id: nil)
  80. when 'primary'
  81. Account.where(moved_to_account_id: nil)
  82. else
  83. raise Mastodon::InvalidParameterError, "Unknown status: #{value}"
  84. end
  85. end
  86. def order_scope(value)
  87. case value
  88. when 'active'
  89. Account.by_recent_status
  90. when 'recent'
  91. params[:relationship] == 'invited' ? Account.recent : Follow.recent
  92. else
  93. raise Mastodon::InvalidParameterError, "Unknown order: #{value}"
  94. end
  95. end
  96. def activity_scope(value)
  97. case value
  98. when 'dormant'
  99. Account.joins(:account_stat).where(account_stat: { last_status_at: [nil, ...1.month.ago] })
  100. else
  101. raise Mastodon::InvalidParameterError, "Unknown activity: #{value}"
  102. end
  103. end
  104. end