mirror of
https://github.com/discourse/discourse.git
synced 2024-11-29 20:04:02 +08:00
FEATURE: implement before and after filters in search remove max_age and min_age
supports - before:monday - after:june - before:2001 - before:2001-01-22
This commit is contained in:
parent
b35186bfe2
commit
e00850a1ab
|
@ -2723,7 +2723,7 @@ en:
|
||||||
<tr><td><code>category:foo</code></td><td><code>user:foo</code></td><td><code>group:foo</code></td><td><code>badge:foo</code></td><td></td></tr>
|
<tr><td><code>category:foo</code></td><td><code>user:foo</code></td><td><code>group:foo</code></td><td><code>badge:foo</code></td><td></td></tr>
|
||||||
<tr><td><code>in:likes</code></td><td><code>in:posted</code></td><td><code>in:watching</code></td><td><code>in:tracking</code></td><td><code>in:private</code></td></tr>
|
<tr><td><code>in:likes</code></td><td><code>in:posted</code></td><td><code>in:watching</code></td><td><code>in:tracking</code></td><td><code>in:private</code></td></tr>
|
||||||
<tr><td><code>in:bookmarks</code></td><td><code>in:first</code></td><td colspan=3></td></tr>
|
<tr><td><code>in:bookmarks</code></td><td><code>in:first</code></td><td colspan=3></td></tr>
|
||||||
<tr><td><code>posts_count:num</code></td><td><code>min_age:days</code></td><td><code>max_age:days</code></td> <td colspan=2></td></tr>
|
<tr><td><code>posts_count:num</code></td><td><code>before:days or date</code></td><td><code>after:days or date</code></td> <td colspan=2></td></tr>
|
||||||
</table>
|
</table>
|
||||||
</p>
|
</p>
|
||||||
<h3>Examples</h3>
|
<h3>Examples</h3>
|
||||||
|
|
|
@ -94,6 +94,40 @@ class Search
|
||||||
data
|
data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.word_to_date(str)
|
||||||
|
|
||||||
|
if str =~ /^[0-9]{1,3}$/
|
||||||
|
return Time.zone.now.beginning_of_day.days_ago(str.to_i)
|
||||||
|
end
|
||||||
|
|
||||||
|
if str =~ /^([12][0-9]{3})(-([0-1]?[0-9]))?(-([0-3]?[0-9]))?$/
|
||||||
|
year = $1.to_i
|
||||||
|
month = $2 ? $3.to_i : 1
|
||||||
|
day = $4 ? $5.to_i : 1
|
||||||
|
|
||||||
|
return if day==0 || month==0 || day > 31 || month > 12
|
||||||
|
|
||||||
|
return Time.zone.parse("#{year}-#{month}-#{day}") rescue nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if str.downcase == "yesterday"
|
||||||
|
return Time.zone.now.beginning_of_day.yesterday
|
||||||
|
end
|
||||||
|
|
||||||
|
titlecase = str.downcase.titlecase
|
||||||
|
|
||||||
|
if Date::DAYNAMES.include?(titlecase)
|
||||||
|
return Time.zone.now.beginning_of_week(str.downcase.to_sym)
|
||||||
|
end
|
||||||
|
|
||||||
|
if idx = (Date::MONTHNAMES.find_index(titlecase) ||
|
||||||
|
Date::ABBR_MONTHNAMES.find_index(titlecase))
|
||||||
|
delta = Time.zone.now.month - idx
|
||||||
|
delta += 12 if delta < 0
|
||||||
|
Time.zone.now.beginning_of_month.months_ago(delta)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def initialize(term, opts=nil)
|
def initialize(term, opts=nil)
|
||||||
@opts = opts || {}
|
@opts = opts || {}
|
||||||
@guardian = @opts[:guardian] || Guardian.new
|
@guardian = @opts[:guardian] || Guardian.new
|
||||||
|
@ -251,14 +285,20 @@ class Search
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
advanced_filter(/min_age:(\d+)/) do |posts,match|
|
advanced_filter(/before:(.*)/) do |posts,match|
|
||||||
n = match.to_i
|
if date = Search.word_to_date(match)
|
||||||
posts.where("topics.created_at > ?", n.days.ago)
|
posts.where("posts.created_at < ?", date)
|
||||||
|
else
|
||||||
|
posts
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
advanced_filter(/max_age:(\d+)/) do |posts,match|
|
advanced_filter(/after:(.*)/) do |posts,match|
|
||||||
n = match.to_i
|
if date = Search.word_to_date(match)
|
||||||
posts.where("topics.created_at < ?", n.days.ago)
|
posts.where("posts.created_at > ?", date)
|
||||||
|
else
|
||||||
|
posts
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -408,15 +408,21 @@ describe Search do
|
||||||
|
|
||||||
describe 'Advanced search' do
|
describe 'Advanced search' do
|
||||||
|
|
||||||
it 'supports min_age and max_age in:first user:' do
|
it 'supports before and after in:first user:' do
|
||||||
topic = Fabricate(:topic, created_at: 3.months.ago)
|
|
||||||
Fabricate(:post, raw: 'hi this is a test 123 123', topic: topic)
|
time = Time.zone.parse('2001-05-20 2:55')
|
||||||
|
freeze_time(time)
|
||||||
|
|
||||||
|
topic = Fabricate(:topic)
|
||||||
|
Fabricate(:post, raw: 'hi this is a test 123 123', topic: topic, created_at: time.months_ago(2))
|
||||||
_post = Fabricate(:post, raw: 'boom boom shake the room', topic: topic)
|
_post = Fabricate(:post, raw: 'boom boom shake the room', topic: topic)
|
||||||
|
|
||||||
expect(Search.execute('test min_age:100').posts.length).to eq(1)
|
expect(Search.execute('test before:1').posts.length).to eq(1)
|
||||||
expect(Search.execute('test min_age:10').posts.length).to eq(0)
|
expect(Search.execute('test before:2001-04-20').posts.length).to eq(1)
|
||||||
expect(Search.execute('test max_age:10').posts.length).to eq(1)
|
expect(Search.execute('test before:2001').posts.length).to eq(0)
|
||||||
expect(Search.execute('test max_age:100').posts.length).to eq(0)
|
expect(Search.execute('test before:monday').posts.length).to eq(1)
|
||||||
|
|
||||||
|
expect(Search.execute('test after:jan').posts.length).to eq(1)
|
||||||
|
|
||||||
expect(Search.execute('test in:first').posts.length).to eq(1)
|
expect(Search.execute('test in:first').posts.length).to eq(1)
|
||||||
expect(Search.execute('boom').posts.length).to eq(1)
|
expect(Search.execute('boom').posts.length).to eq(1)
|
||||||
|
@ -512,5 +518,34 @@ describe Search do
|
||||||
Post.exec_sql("SELECT to_tsvector('bbb') @@ " << ts_query)
|
Post.exec_sql("SELECT to_tsvector('bbb') @@ " << ts_query)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context '#word_to_date' do
|
||||||
|
it 'parses relative dates correctly' do
|
||||||
|
time = Time.zone.parse('2001-02-20 2:55')
|
||||||
|
freeze_time(time)
|
||||||
|
|
||||||
|
expect(Search.word_to_date('yesterday')).to eq(time.beginning_of_day.yesterday)
|
||||||
|
expect(Search.word_to_date('suNday')).to eq(Time.zone.parse('2001-02-18'))
|
||||||
|
expect(Search.word_to_date('thursday')).to eq(Time.zone.parse('2001-02-15'))
|
||||||
|
expect(Search.word_to_date('deCember')).to eq(Time.zone.parse('2000-12-01'))
|
||||||
|
expect(Search.word_to_date('deC')).to eq(Time.zone.parse('2000-12-01'))
|
||||||
|
expect(Search.word_to_date('january')).to eq(Time.zone.parse('2001-01-01'))
|
||||||
|
expect(Search.word_to_date('jan')).to eq(Time.zone.parse('2001-01-01'))
|
||||||
|
|
||||||
|
|
||||||
|
expect(Search.word_to_date('100')).to eq(time.beginning_of_day.days_ago(100))
|
||||||
|
|
||||||
|
expect(Search.word_to_date('invalid')).to eq(nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'parses absolute dates correctly' do
|
||||||
|
expect(Search.word_to_date('2001-1-20')).to eq(Time.zone.parse('2001-01-20'))
|
||||||
|
expect(Search.word_to_date('2030-10-2')).to eq(Time.zone.parse('2030-10-02'))
|
||||||
|
expect(Search.word_to_date('2030-10')).to eq(Time.zone.parse('2030-10-01'))
|
||||||
|
expect(Search.word_to_date('2030')).to eq(Time.zone.parse('2030-01-01'))
|
||||||
|
expect(Search.word_to_date('2030-01-32')).to eq(nil)
|
||||||
|
expect(Search.word_to_date('10000')).to eq(nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user