Files
danbooru/app/logical/duration_parser.rb
evazion a5ed8c72c9 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.
2021-11-02 01:54:05 -05:00

33 lines
666 B
Ruby

require 'abbrev'
module DurationParser
def self.parse(string)
abbrevs = Abbrev.abbrev(%w[seconds minutes hours days weeks months years])
raise unless string =~ /(.*?)([a-z]+)\z/i
size = Float($1)
unit = abbrevs.fetch($2.downcase)
case unit
when "seconds"
size.seconds
when "minutes"
size.minutes
when "hours"
size.hours
when "days"
size.days
when "weeks"
size.weeks
when "months"
size * (365.25.days / 12)
when "years"
size * (365.25.days)
else
raise NotImplementedError
end
rescue
raise ArgumentError, "'#{string}' is not a valid duration"
end
end