You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.3 KiB

  1. # frozen_string_literal: true
  2. class AccountSearchService < BaseService
  3. attr_reader :query, :limit, :offset, :options, :account
  4. def call(query, account = nil, options = {})
  5. @query = query.strip
  6. @limit = options[:limit].to_i
  7. @offset = options[:offset].to_i
  8. @options = options
  9. @account = account
  10. search_service_results
  11. end
  12. private
  13. def search_service_results
  14. return [] if query_blank_or_hashtag? || limit < 1
  15. if resolving_non_matching_remote_account?
  16. [ResolveAccountService.new.call("#{query_username}@#{query_domain}")].compact
  17. else
  18. search_results_and_exact_match.compact.uniq.slice(0, limit)
  19. end
  20. end
  21. def resolving_non_matching_remote_account?
  22. options[:resolve] && !exact_match && !domain_is_local?
  23. end
  24. def search_results_and_exact_match
  25. exact = [exact_match]
  26. return exact if !exact[0].nil? && limit == 1
  27. exact + search_results.to_a
  28. end
  29. def query_blank_or_hashtag?
  30. query.blank? || query.start_with?('#')
  31. end
  32. def split_query_string
  33. @_split_query_string ||= query.gsub(/\A@/, '').split('@')
  34. end
  35. def query_username
  36. @_query_username ||= split_query_string.first || ''
  37. end
  38. def query_domain
  39. @_query_domain ||= query_without_split? ? nil : split_query_string.last
  40. end
  41. def query_without_split?
  42. split_query_string.size == 1
  43. end
  44. def domain_is_local?
  45. @_domain_is_local ||= TagManager.instance.local_domain?(query_domain)
  46. end
  47. def search_from
  48. options[:following] && account ? account.following : Account
  49. end
  50. def exact_match
  51. @_exact_match ||= begin
  52. if domain_is_local?
  53. search_from.without_suspended.find_local(query_username)
  54. else
  55. search_from.without_suspended.find_remote(query_username, query_domain)
  56. end
  57. end
  58. end
  59. def search_results
  60. @_search_results ||= begin
  61. if account
  62. advanced_search_results
  63. else
  64. simple_search_results
  65. end
  66. end
  67. end
  68. def advanced_search_results
  69. Account.advanced_search_for(terms_for_query, account, limit, options[:following], offset)
  70. end
  71. def simple_search_results
  72. Account.search_for(terms_for_query, limit, offset)
  73. end
  74. def terms_for_query
  75. if domain_is_local?
  76. query_username
  77. else
  78. "#{query_username} #{query_domain}"
  79. end
  80. end
  81. end