Skip to content

Commit

Permalink
Fix account_id, max_id and min_id params not working in search (m…
Browse files Browse the repository at this point in the history
  • Loading branch information
Gargron committed Sep 8, 2023
1 parent e9b528e commit 3a67984
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 7 deletions.
2 changes: 1 addition & 1 deletion app/lib/search_query_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 5 additions & 6 deletions app/lib/search_query_transformer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -225,17 +225,16 @@ def language_code_from_term(term)
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
Expand Down
22 changes: 22 additions & 0 deletions app/services/statuses_search_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ def call(query, account = nil, options = {})
@limit = options[:limit].to_i
@offset = options[:offset].to_i

convert_deprecated_options!
status_search_results
end

Expand All @@ -28,4 +29,25 @@ def status_search_results
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
4 changes: 4 additions & 0 deletions lib/mastodon/snowflake.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ def id_at(timestamp, with_random: true)
id
end

def to_time(id)
Time.at((id >> 16) / 1000).utc
end

private

def already_defined?
Expand Down
20 changes: 20 additions & 0 deletions spec/lib/search_query_transformer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,24 @@
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

0 comments on commit 3a67984

Please sign in to comment.