Add Owls values to the item page
Eyy it's time!! Long-requested, finally here lol
This commit is contained in:
parent
494f82601f
commit
5dcb1dedb4
7 changed files with 106 additions and 2 deletions
1
Gemfile
1
Gemfile
|
@ -56,6 +56,7 @@ gem 'parallel', '~> 1.23'
|
||||||
|
|
||||||
# For miscellaneous HTTP requests.
|
# For miscellaneous HTTP requests.
|
||||||
gem "httparty", "~> 0.21.0"
|
gem "httparty", "~> 0.21.0"
|
||||||
|
gem "addressable", "~> 2.8"
|
||||||
|
|
||||||
# For debugging.
|
# For debugging.
|
||||||
gem 'web-console', '~> 4.2', group: :development
|
gem 'web-console', '~> 4.2', group: :development
|
||||||
|
|
|
@ -308,6 +308,7 @@ PLATFORMS
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
RocketAMF!
|
RocketAMF!
|
||||||
|
addressable (~> 2.8)
|
||||||
bootsnap (~> 1.16)
|
bootsnap (~> 1.16)
|
||||||
devise (~> 4.9, >= 4.9.2)
|
devise (~> 4.9, >= 4.9.2)
|
||||||
devise-encryptable (~> 0.2.0)
|
devise-encryptable (~> 0.2.0)
|
||||||
|
|
|
@ -119,6 +119,19 @@ module ItemsHelper
|
||||||
render(partial: 'items/item_link', locals: {item: item})
|
render(partial: 'items/item_link', locals: {item: item})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def nc_trade_value_updated_at_text(nc_trade_value)
|
||||||
|
return nil if nc_trade_value.updated_at.nil?
|
||||||
|
|
||||||
|
# Render both "[X] [days] ago", and also the exact date, only including the
|
||||||
|
# year if it's not this same year.
|
||||||
|
time_ago_str = time_ago_in_words nc_trade_value.updated_at
|
||||||
|
date_str = nc_trade_value.updated_at.year != Date.today.year ?
|
||||||
|
nc_trade_value.updated_at.strftime("%b %-d") :
|
||||||
|
nc_trade_value.updated_at.strftime("%b %-d, %Y")
|
||||||
|
|
||||||
|
"Last updated: #{date_str} (#{time_ago_str} ago)"
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def build_on_pet_types(species, special_color=nil, &block)
|
def build_on_pet_types(species, special_color=nil, &block)
|
||||||
|
|
|
@ -129,8 +129,17 @@ class Item < ApplicationRecord
|
||||||
distinct
|
distinct
|
||||||
}
|
}
|
||||||
|
|
||||||
def closeted?
|
def nc_trade_value
|
||||||
@owned || @wanted
|
return nil unless nc?
|
||||||
|
begin
|
||||||
|
OwlsValueGuide.find_by_name(name(:en))
|
||||||
|
rescue OwlsValueGuide::NotFound => error
|
||||||
|
Rails.logger.debug("No NC trade value listed for #{name(:en)} (#{id})")
|
||||||
|
return nil
|
||||||
|
rescue OwlsValueGuide::NetworkError => error
|
||||||
|
Rails.logger.error("Couldn't load nc_trade_value: #{error.full_message}")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Return an OrderedHash mapping users to the number of times they
|
# Return an OrderedHash mapping users to the number of times they
|
||||||
|
|
75
app/services/owls_value_guide.rb
Normal file
75
app/services/owls_value_guide.rb
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
module OwlsValueGuide
|
||||||
|
include HTTParty
|
||||||
|
|
||||||
|
ITEMDATA_URL_TEMPLATE = Addressable::Template.new(
|
||||||
|
"https://neo-owls.net/itemdata/{item_name}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def self.find_by_name(item_name)
|
||||||
|
# Load the itemdata, pulling from the Rails cache if possible.
|
||||||
|
cache_key = "OwlsValueGuide/itemdata/#{item_name}"
|
||||||
|
data = Rails.cache.fetch(cache_key, expires_in: 15.minutes) do
|
||||||
|
load_itemdata(item_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
if data == :not_found
|
||||||
|
raise NotFound
|
||||||
|
end
|
||||||
|
|
||||||
|
# Owls has records of some items that it explicitly marks as having no
|
||||||
|
# listed value. We don't care about that distinction, just return nil!
|
||||||
|
return nil if data['owls_value'].blank?
|
||||||
|
|
||||||
|
Value.new(data['owls_value'], parse_last_updated(data['last_updated']))
|
||||||
|
end
|
||||||
|
|
||||||
|
Value = Struct.new(:value_text, :updated_at)
|
||||||
|
|
||||||
|
class Error < StandardError;end
|
||||||
|
class NetworkError < Error;end
|
||||||
|
class NotFound < Error;end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def self.load_itemdata(item_name)
|
||||||
|
Rails.logger.info "[OwlsValueGuide] Loading value for #{item_name.inspect}"
|
||||||
|
|
||||||
|
url = ITEMDATA_URL_TEMPLATE.expand(item_name: item_name)
|
||||||
|
begin
|
||||||
|
res = get(url)
|
||||||
|
rescue StandardError => error
|
||||||
|
raise NetworkError, "Couldn't connect to Owls: #{error.message}"
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.code == 404
|
||||||
|
# Instead of raising immediately, return `:not_found` to save this
|
||||||
|
# result in the cache, then raise *after* we exit the cache block. That
|
||||||
|
# way, we won't make repeat requests for items we have that Owls
|
||||||
|
# doesn't.
|
||||||
|
return :not_found
|
||||||
|
end
|
||||||
|
|
||||||
|
if res.code != 200
|
||||||
|
raise NetworkError, "Owls returned status code #{res.code} (expected 200)"
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
res.parsed_response
|
||||||
|
rescue HTTParty::Error => error
|
||||||
|
raise NetworkError, "Owls returned unsupported data format: #{error.message}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.parse_last_updated(date_str)
|
||||||
|
return nil if date_str.blank?
|
||||||
|
|
||||||
|
begin
|
||||||
|
Date.strptime(date_str, '%Y-%m-%d')
|
||||||
|
rescue Date::Error
|
||||||
|
Rails.logger.error(
|
||||||
|
"[OwlsValueGuide] unexpected last_updated format: #{date_str.inspect}"
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -9,6 +9,10 @@
|
||||||
- unless @item.rarity.blank?
|
- unless @item.rarity.blank?
|
||||||
== #{t '.rarity'}: #{@item.rarity_index} (#{@item.rarity})
|
== #{t '.rarity'}: #{@item.rarity_index} (#{@item.rarity})
|
||||||
= link_to t('.resources.jn_items'), jn_items_url_for(@item)
|
= link_to t('.resources.jn_items'), jn_items_url_for(@item)
|
||||||
|
- if @item.nc_trade_value
|
||||||
|
= link_to t('.resources.owls', value: @item.nc_trade_value.value_text),
|
||||||
|
"https://www.neopets.com/~owls",
|
||||||
|
title: nc_trade_value_updated_at_text(@item.nc_trade_value)
|
||||||
- unless @item.nc?
|
- unless @item.nc?
|
||||||
= link_to t('.resources.shop_wizard'), shop_wizard_url_for(@item)
|
= link_to t('.resources.shop_wizard'), shop_wizard_url_for(@item)
|
||||||
= link_to t('.resources.super_shop_wizard'), super_shop_wizard_url_for(@item)
|
= link_to t('.resources.super_shop_wizard'), super_shop_wizard_url_for(@item)
|
||||||
|
|
|
@ -302,6 +302,7 @@ en:
|
||||||
rarity: Rarity
|
rarity: Rarity
|
||||||
resources:
|
resources:
|
||||||
jn_items: JN Items
|
jn_items: JN Items
|
||||||
|
owls: "Owls: %{value}"
|
||||||
shop_wizard: Shop Wizard
|
shop_wizard: Shop Wizard
|
||||||
super_shop_wizard: Super Wizard
|
super_shop_wizard: Super Wizard
|
||||||
trading_post: Trades
|
trading_post: Trades
|
||||||
|
|
Loading…
Reference in a new issue