From 24202d51f028b748c342aa81bc05a739e5125480 Mon Sep 17 00:00:00 2001 From: evazion Date: Sun, 8 Sep 2019 15:32:31 -0500 Subject: [PATCH] api: support the `expires_in` param on all GET requests. `expires_in` is an alternative to `expiry` that supports durations other than days: * https://danbooru.donmai.us/posts.json?expires_in=30s * https://danbooru.donmai.us/posts.json?expires_in=5min * https://danbooru.donmai.us/posts.json?expires_in=1hour * https://danbooru.donmai.us/posts.json?expires_in=1week * https://danbooru.donmai.us/posts.json?expires_in=1month --- app/logical/application_responder.rb | 9 +++++-- app/logical/duration_parser.rb | 27 +++++++++++++++++++ app/models/tag.rb | 24 +---------------- .../functional/application_controller_test.rb | 7 +++++ 4 files changed, 42 insertions(+), 25 deletions(-) create mode 100644 app/logical/duration_parser.rb diff --git a/app/logical/application_responder.rb b/app/logical/application_responder.rb index 502578284..40e4b85ca 100644 --- a/app/logical/application_responder.rb +++ b/app/logical/application_responder.rb @@ -3,9 +3,14 @@ class ApplicationResponder < ActionController::Responder # this is called by respond_with for non-html, non-js responses. def to_format + params = request.params + if get? - expiry = request.params["expiry"] - controller.expires_in expiry.to_i.days if expiry.present? + if params["expires_in"] + controller.expires_in(DurationParser.parse(params["expires_in"])) + elsif request.params["expiry"] + controller.expires_in(params["expiry"].to_i.days) + end end if format == :xml diff --git a/app/logical/duration_parser.rb b/app/logical/duration_parser.rb new file mode 100644 index 000000000..48d9fc28e --- /dev/null +++ b/app/logical/duration_parser.rb @@ -0,0 +1,27 @@ +module DurationParser + def self.parse(string) + string =~ /(\d+)(s(econds?)?|mi(nutes?)?|h(ours?)?|d(ays?)?|w(eeks?)?|mo(nths?)?|y(ears?)?)?/i + + size = $1.to_i + unit = $2 + + case unit + when /^s/i + size.seconds + when /^mi/i + size.minutes + when /^h/i + size.hours + when /^d/i + size.days + when /^w/i + size.weeks + when /^mo/i + size.months + when /^y/i + size.years + else + size.seconds + end + end +end diff --git a/app/models/tag.rb b/app/models/tag.rb index 0d8f7e616..2785325a0 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -313,29 +313,7 @@ class Tag < ApplicationRecord end when :age - object =~ /(\d+)(s(econds?)?|mi(nutes?)?|h(ours?)?|d(ays?)?|w(eeks?)?|mo(nths?)?|y(ears?)?)?/i - - size = $1.to_i - unit = $2 - - case unit - when /^s/i - size.seconds.ago - when /^mi/i - size.minutes.ago - when /^h/i - size.hours.ago - when /^d/i - size.days.ago - when /^w/i - size.weeks.ago - when /^mo/i - size.months.ago - when /^y/i - size.years.ago - else - size.seconds.ago - end + DurationParser.parse(object).ago when :ratio object =~ /\A(\d+(?:\.\d+)?):(\d+(?:\.\d+)?)\Z/i diff --git a/test/functional/application_controller_test.rb b/test/functional/application_controller_test.rb index e56b048bd..febba5acc 100644 --- a/test/functional/application_controller_test.rb +++ b/test/functional/application_controller_test.rb @@ -199,6 +199,13 @@ class ApplicationControllerTest < ActionDispatch::IntegrationTest assert_equal("max-age=#{1.day}, private", response.headers["Cache-Control"]) end + should "support the expires_in parameter" do + get posts_path, as: :json, params: { expires_in: "5min" } + + assert_response :success + assert_equal("max-age=#{5.minutes}, private", response.headers["Cache-Control"]) + end + should "return the correct root element name for empty xml responses" do get tags_path, as: :xml