search: fix parsing of invalid metatag values.

* Change `age:` metatag to require time units. This means e.g.
  `age:<600` no longer works; instead you have to say `age:<600sec`.

* Allow time units in the `age:` metatag to be abbreviated as long as
  they're unambiguous. This means `age:<60sec`, `age:<5min`, and
  `age:<5mon` now work, in addition to `age:<60s` and `age:<60seconds`.

* Allow the `ratio:` metatag to be written like `ratio:16/9` in addition
  to `ratio:16:9`.

* Fix invalid date searches like `date:foo` or `date:05-15-2021`
  to return nothing instead of raising an "undefined method
  'beginning_of_day' for nil" exception. (`date:05-15-2021` is invalid
  because it's parsed as DD-MM-YYYY).

* Fix invalid searches like `score:foo`, `ratio:foo`, and `mpixels:foo`
  to return nothing instead of being treated like `score:0`, `ratio:0`,
  `mpixels:0`.

* Fix `age:<60m` to return nothing instead of silently being treated
  like `age:<60seconds`.

* Fix `age:foo` to return nothing instead of silently being treated like
  `age:0d` (return all uploads from today).

Fixes #4389.
This commit is contained in:
evazion
2021-11-02 00:41:05 -05:00
parent 788dcbd87b
commit a5ed8c72c9
3 changed files with 130 additions and 48 deletions

View File

@@ -1,27 +1,32 @@
require 'abbrev'
module DurationParser
def self.parse(string)
string =~ /(\d+)(s(econds?)?|mi(nutes?)?|h(ours?)?|d(ays?)?|w(eeks?)?|mo(nths?)?|y(ears?)?)?/i
abbrevs = Abbrev.abbrev(%w[seconds minutes hours days weeks months years])
size = $1.to_i
unit = $2
raise unless string =~ /(.*?)([a-z]+)\z/i
size = Float($1)
unit = abbrevs.fetch($2.downcase)
case unit
when /^s/i
when "seconds"
size.seconds
when /^mi/i
when "minutes"
size.minutes
when /^h/i
when "hours"
size.hours
when /^d/i
when "days"
size.days
when /^w/i
when "weeks"
size.weeks
when /^mo/i
size.months
when /^y/i
size.years
when "months"
size * (365.25.days / 12)
when "years"
size * (365.25.days)
else
size.seconds
raise NotImplementedError
end
rescue
raise ArgumentError, "'#{string}' is not a valid duration"
end
end