summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2023-09-08 14:25:00 +0200
committerGitHub <noreply@github.com>2023-09-08 14:25:00 +0200
commit3a679844e499df026be7d5b3a9e80e5bf3ad585a (patch)
tree1256c658e1bff5e3ddce1cce50cddd338e8d27ab
parente9b528eaee834221e1740b029260b35fe80d673b (diff)
Fix `account_id`, `max_id` and `min_id` params not working in search (#26847)
-rw-r--r--app/lib/search_query_parser.rb2
-rw-r--r--app/lib/search_query_transformer.rb11
-rw-r--r--app/services/statuses_search_service.rb22
-rw-r--r--lib/mastodon/snowflake.rb4
-rw-r--r--spec/lib/search_query_transformer_spec.rb20
5 files changed, 52 insertions, 7 deletions
diff --git a/app/lib/search_query_parser.rb b/app/lib/search_query_parser.rb
index 1c57b9b0248..dfe8b9e9d86 100644
--- a/app/lib/search_query_parser.rb
+++ b/app/lib/search_query_parser.rb
@@ -8,7 +8,7 @@ class SearchQueryParser < Parslet::Parser
rule(:operator) { (str('+') | str('-')).as(:operator) }
rule(:prefix) { term >> colon }
rule(:shortcode) { (colon >> term >> colon.maybe).as(:shortcode) }
- rule(:phrase) { (quote >> (term >> space.maybe).repeat >> quote).as(:phrase) }
+ rule(:phrase) { (quote >> (match('[^\s"]').repeat(1).as(:term) >> space.maybe).repeat >> quote).as(:phrase) }
rule(:clause) { (operator.maybe >> prefix.maybe.as(:prefix) >> (phrase | term | shortcode)).as(:clause) | prefix.as(:clause) | quote.as(:junk) }
rule(:query) { (clause >> space.maybe).repeat.as(:query) }
root(:query)
diff --git a/app/lib/search_query_transformer.rb b/app/lib/search_query_transformer.rb
index 870f34cae8e..a45ae3d09bc 100644
--- a/app/lib/search_query_transformer.rb
+++ b/app/lib/search_query_transformer.rb
@@ -225,17 +225,16 @@ class SearchQueryTransformer < Parslet::Transform
rule(clause: subtree(:clause)) do
prefix = clause[:prefix][:term].to_s if clause[:prefix]
operator = clause[:operator]&.to_s
+ term = clause[:phrase] ? clause[:phrase].map { |term| term[:term].to_s }.join(' ') : clause[:term].to_s
if clause[:prefix] && SUPPORTED_PREFIXES.include?(prefix)
- PrefixClause.new(prefix, operator, clause[:term].to_s, current_account: current_account)
+ PrefixClause.new(prefix, operator, term, current_account: current_account)
elsif clause[:prefix]
- TermClause.new(operator, "#{prefix} #{clause[:term]}")
+ TermClause.new(operator, "#{prefix} #{term}")
elsif clause[:term]
- TermClause.new(operator, clause[:term].to_s)
- elsif clause[:shortcode]
- TermClause.new(operator, ":#{clause[:term]}:")
+ TermClause.new(operator, term)
elsif clause[:phrase]
- PhraseClause.new(operator, clause[:phrase].is_a?(Array) ? clause[:phrase].map { |p| p[:term].to_s }.join(' ') : clause[:phrase].to_s)
+ PhraseClause.new(operator, term)
else
raise "Unexpected clause type: #{clause}"
end
diff --git a/app/services/statuses_search_service.rb b/app/services/statuses_search_service.rb
index e4b38a9dabe..e2a5f41b10a 100644
--- a/app/services/statuses_search_service.rb
+++ b/app/services/statuses_search_service.rb
@@ -8,6 +8,7 @@ class StatusesSearchService < BaseService
@limit = options[:limit].to_i
@offset = options[:offset].to_i
+ convert_deprecated_options!
status_search_results
end
@@ -28,4 +29,25 @@ class StatusesSearchService < BaseService
def parsed_query
SearchQueryTransformer.new.apply(SearchQueryParser.new.parse(@query), current_account: @account)
end
+
+ def convert_deprecated_options!
+ syntax_options = []
+
+ if @options[:account_id]
+ username = Account.select(:username, :domain).find(@options[:account_id]).acct
+ syntax_options << "from:@#{username}"
+ end
+
+ if @options[:min_id]
+ timestamp = Mastodon::Snowflake.to_time(@options[:min_id])
+ syntax_options << "after:\"#{timestamp.iso8601}\""
+ end
+
+ if @options[:max_id]
+ timestamp = Mastodon::Snowflake.to_time(@options[:max_id])
+ syntax_options << "before:\"#{timestamp.iso8601}\""
+ end
+
+ @query = "#{@query} #{syntax_options.join(' ')}".strip if syntax_options.any?
+ end
end
diff --git a/lib/mastodon/snowflake.rb b/lib/mastodon/snowflake.rb
index 8b79541da27..0a596b29401 100644
--- a/lib/mastodon/snowflake.rb
+++ b/lib/mastodon/snowflake.rb
@@ -104,6 +104,10 @@ module Mastodon::Snowflake
id
end
+ def to_time(id)
+ Time.at((id >> 16) / 1000).utc
+ end
+
private
def already_defined?
diff --git a/spec/lib/search_query_transformer_spec.rb b/spec/lib/search_query_transformer_spec.rb
index 4b949b1b825..5817e3d1d20 100644
--- a/spec/lib/search_query_transformer_spec.rb
+++ b/spec/lib/search_query_transformer_spec.rb
@@ -57,4 +57,24 @@ describe SearchQueryTransformer do
expect(subject.send(:filter_clauses)).to be_empty
end
end
+
+ context 'with \'"hello world"\'' do
+ let(:query) { '"hello world"' }
+
+ it 'transforms clauses' do
+ expect(subject.send(:must_clauses).map(&:phrase)).to contain_exactly('hello world')
+ expect(subject.send(:must_not_clauses)).to be_empty
+ expect(subject.send(:filter_clauses)).to be_empty
+ end
+ end
+
+ context 'with \'before:"2022-01-01 23:00"\'' do
+ let(:query) { 'before:"2022-01-01 23:00"' }
+
+ it 'transforms clauses' do
+ expect(subject.send(:must_clauses)).to be_empty
+ expect(subject.send(:must_not_clauses)).to be_empty
+ expect(subject.send(:filter_clauses).map(&:term)).to contain_exactly(lt: '2022-01-01 23:00', time_zone: 'UTC')
+ end
+ end
end