diff --git a/app/models/item/dyeworks.rb b/app/models/item/dyeworks.rb index a5ccb9d0..7908e582 100644 --- a/app/models/item/dyeworks.rb +++ b/app/models/item/dyeworks.rb @@ -20,26 +20,69 @@ class Item # Whether this is a Dyeworks item that can be dyed in the NC Mall ~right now, # either at any time or as a limited-time event. (Owls tracks this, not us!) def dyeworks_dyeable? - dyeworks_permanent? || dyeworks_limited? + dyeworks_permanent? || dyeworks_limited_active? end # Whether this is one of the few Dyeworks items that can be dyed in the NC # Mall at any time, rather than as part of a limited-time event. (Owls tracks # this, not us!) - DYEWORKS_PERMANENT_PATTERN = /Permanent Dyeworks/i + DYEWORKS_PERMANENT_PATTERN = /Permanent\s*Dyeworks/i def dyeworks_permanent? return false if nc_trade_value.nil? nc_trade_value.value_text.match?(DYEWORKS_PERMANENT_PATTERN) end - # Whether this is a Dyeworks item that can be dyed in the NC Mall ~right now, - # but only as part of a limited-time event. (Owls tracks this, not us!) - DYEWORKS_LIMITED_PATTERN = /Limited Dyeworks/i + # Whether this is a Dyeworks item that can be dyed in the NC Mall ~right + # now, as part of a limited-time event. (Owls tracks this, not us!) + # + # If we aren't sure of the final date, this will still return `true`, on + # the assumption it *is* dyeable right now and we just don't understand the + # details of what Owls told us. + def dyeworks_limited_active? + return false unless dyeworks_limited? + return true if dyeworks_limited_final_date.nil? + + # NOTE: The application is configured to NST, so this should be + # equivalent to `Date.today`, but this is clearer and more correct imo! + today_in_nst = Time.find_zone("Pacific Time (US & Canada)").today + + today_in_nst <= dyeworks_limited_final_date + end + + # Whether this is a Dyeworks item that can only be dyed as part of a + # limited-time event. (This may return true even if the end date has + # passed, see `dyeworks_limited_active?`.) (Owls tracks this, not us!) + DYEWORKS_LIMITED_PATTERN = /Limited\s*Dyeworks/i def dyeworks_limited? return false if nc_trade_value.nil? nc_trade_value.value_text.match?(DYEWORKS_LIMITED_PATTERN) end + # If this is a limited-time Dyeworks item, this is the date we think the + # event will end on. Even if `dyeworks_limited?` returns true, this could + # still be `nil`, if we fail to parse this. (Owls tracks this, not us!) + DYEWORKS_LIMITED_FINAL_DATE_PATTERN = + /Dyeable\s*Thru\s*(?[a-z]+)\s*(?[0-9]+)/i + def dyeworks_limited_final_date + return nil unless dyeworks_limited? + + match = nc_trade_value.value_text. + match(DYEWORKS_LIMITED_FINAL_DATE_PATTERN) + return nil if match.nil? + + # Parse this " " date as the *next* such date: parse it as + # this year at first, then add a year if it turns out to be in the past. + # + # NOTE: This could return strange results if the Owls date contains + # something surprising! But the heuristic nature helps with e.g. + # flexibility if they abbreviate months, so let's lean into `Date.parse`. + match => {month:, day:} + date = Date.parse("#{month} #{day}, #{Date.today.year}") + date += 1.year if date < Date.today + + date + end + # Infer what base item this Dyeworks item probably relates to, based on # their names. We only use this when a new item is modeled to initialize # the `dyeworks_base_item` relationship in the database; after that, we diff --git a/app/views/items/sources.html.haml b/app/views/items/sources.html.haml index af526ed4..201a3657 100644 --- a/app/views/items/sources.html.haml +++ b/app/views/items/sources.html.haml @@ -80,6 +80,13 @@ "Dyeworks items are." } (Permanent) + - elsif item.dyeworks_limited_final_date.present? + %span.dyeworks-timeframe{ + title: "This recipe is part of a limited-time Dyeworks " + + "event. The last day you can dye this is " + + "#{item.dyeworks_limited_final_date.to_fs(:month_and_day)}." + } + (Thru #{item.dyeworks_limited_final_date.to_fs(:month_and_day)}) - elsif item.dyeworks_limited? %span.dyeworks-timeframe{ title: "This recipe is part of a limited-time Dyeworks " + diff --git a/config/initializers/date_formats.rb b/config/initializers/date_formats.rb new file mode 100644 index 00000000..bf383589 --- /dev/null +++ b/config/initializers/date_formats.rb @@ -0,0 +1 @@ +Date::DATE_FORMATS[:month_and_day] = "%B %e"