impress/app/helpers/items_helper.rb

274 lines
7.7 KiB
Ruby
Raw Normal View History

require "addressable/template"
2010-05-15 10:47:46 -07:00
module ItemsHelper
2010-06-08 07:39:23 -07:00
module PetTypeImage
Template = Addressable::Template.new(
"https://pets.neopets.com/cp/{hash}/{emotion}/{size}.png"
)
2010-06-08 07:39:23 -07:00
Emotions = {
happy: 1,
sad: 2,
angry: 3,
ill: 4,
2010-06-08 07:39:23 -07:00
}
2010-06-08 07:39:23 -07:00
Sizes = {
face: 1, # 50x50
face_3x: 6, # 150x150
thumb: 2, # 150x150
full: 4, # 300x300
large: 5, # 500x500
xlarge: 7, # 640x640
zoom: 3, # 80x80
autocrop: 9, # <varies>
}
SizeUpgrades = {
face: :face_3x,
thumb: :full,
full: :xlarge,
2010-06-08 07:39:23 -07:00
}
end
def pet_type_image_url(pet_type, emotion: :happy, size: :face)
PetTypeImage::Template.expand(
hash: pet_type.basic_image_hash || pet_type.image_hash,
emotion: PetTypeImage::Emotions.fetch(emotion),
size: PetTypeImage::Sizes.fetch(size),
).to_s
end
2010-06-08 07:39:23 -07:00
def standard_species_search_links
all_species = Species.alphabetical.map(&:id)
PetType.random_basic_per_species(all_species).map do |pet_type|
human_name = pet_type.species.human_name
image = pet_type_image pet_type, :happy, :zoom,
alt: human_name, title: human_name
2010-06-08 07:39:23 -07:00
query = "species:#{pet_type.species.name}"
link_to(image, items_path(:q => query))
end.join.html_safe
2010-06-08 07:39:23 -07:00
end
def closet_list_verb(owned)
ClosetHanger.verb(:you, owned)
end
2012-08-06 18:15:31 -07:00
def owned_icon
2013-01-01 19:15:17 -08:00
image_tag 'owned.png', :title => t('items.item.owned.description'),
:alt => t('items.item.owned.abbr')
2012-08-06 18:15:31 -07:00
end
def wanted_icon
2013-01-01 19:15:17 -08:00
image_tag 'wanted.png', :title => t('items.item.wanted.description'),
:alt => t('items.item.wanted.abbr')
2012-08-06 18:15:31 -07:00
end
2011-07-12 22:21:48 -07:00
def closeted_icons_for(item)
content = ''.html_safe
2012-08-06 18:15:31 -07:00
content << owned_icon if item.owned?
content << wanted_icon if item.wanted?
content_tag :div, content, :class => 'closeted-icons'
2011-07-12 22:21:48 -07:00
end
2012-08-06 18:15:31 -07:00
# NOTE: Changing this requires bumping the cache at `_closet_list.html.haml`!
2012-08-06 18:15:31 -07:00
def nc_icon
image_tag 'nc.png', :title => t('items.item.nc.description'),
:alt => t('items.item.nc.abbr'), :class => 'nc-icon'
2012-08-06 18:15:31 -07:00
end
# NOTE: Changing this requires bumping the cache at `_closet_list.html.haml`!
2010-09-08 19:49:39 -07:00
def nc_icon_for(item)
2012-08-06 18:15:31 -07:00
nc_icon if item.nc?
2010-09-08 19:49:39 -07:00
end
# NOTE: Changing this requires bumping the cache at `_closet_list.html.haml`!
def item_thumbnail_for(item)
image_tag item.thumbnail_url, alt: "Thumbnail for #{item.name}",
title: item.description, loading: "lazy"
end
def time_with_only_month_if_old(first_seen_at)
# For this month and the previous month, show the full date, so people can
# understand *exactly* how recent it was.
beginning_of_prev_month = Date.today.beginning_of_month - 1.month
if first_seen_at >= beginning_of_prev_month
return first_seen_at.strftime("%b %e, %Y")
end
# Otherwise, show just the month and the year, to be concise. (We'll offer
# the full date as a tooltip, too.)
first_seen_at.strftime("%b %Y")
end
JN_ITEMS_URL_TEMPLATE = Addressable::Template.new(
"https://items.jellyneo.net/search/?name_type=3{&name}"
)
def jn_items_url_for(item)
JN_ITEMS_URL_TEMPLATE.expand(name: item.name).to_s
2010-09-08 19:49:39 -07:00
end
IMPRESS_2020_ITEM_URL_TEMPLATE = Addressable::Template.new(
"#{Rails.configuration.impress_2020_origin}/items/{id}"
)
def impress_2020_url_for(item)
IMPRESS_2020_ITEM_URL_TEMPLATE.expand(id: item.id).to_s
end
SHOP_WIZARD_URL_TEMPLATE = Addressable::Template.new(
"https://www.neopets.com/shops/wizard.phtml{?string}"
)
Add more PB item info and links to Item Getting Guide I add some infrastructural support for inferring an item's paintbrush color (if any), and a field to the database to manually track an item's paint brush item name! This is both useful for tracking which colors are even *available* via paint brush, and also for working with colors with unusual paint brush names, like the "Get Off My Lawn Paint Brush" (for Elderly pets). Here's the script I ran to backfill this for current colors and their paint brushes! ```rb Color.find_by_name("Baby").update!(pb_item_name: "Baby Paint Brush") Color.find_by_name("Biscuit").update!(pb_item_name: "Biscuit Paint Brush") Color.find_by_name("Blue").update!(pb_item_name: "Blue Paint Brush") Color.find_by_name("Brown").update!(pb_item_name: "Brown Paint Brush") Color.find_by_name("Camouflage").update!(pb_item_name: "Camouflage Paint Brush") Color.find_by_name("Candy").update!(pb_item_name: "Candy Paint Brush") Color.find_by_name("Checkered").update!(pb_item_name: "Checkered Paint Brush") Color.find_by_name("Christmas").update!(pb_item_name: "Christmas Paint Brush") Color.find_by_name("Cloud").update!(pb_item_name: "Cloud Paint Brush") Color.find_by_name("Darigan").update!(pb_item_name: "Darigan Paint Brush") Color.find_by_name("Dimensional").update!(pb_item_name: "Dimensional Paint Brush") Color.find_by_name("Disco").update!(pb_item_name: "Disco Fever Paint Brush") Color.find_by_name("Electric").update!(pb_item_name: "Electric Blue Paint Brush") Color.find_by_name("Eventide").update!(pb_item_name: "Eventide Paint Brush") Color.find_by_name("Faerie").update!(pb_item_name: "Faerie Paint Brush") Color.find_by_name("Fire").update!(pb_item_name: "Fire, Fire, Your Pants On Fire Paint Brush") Color.find_by_name("Elderlyboy").update!(pb_item_name: "Get Off My Lawn Paint Brush") Color.find_by_name("Elderlygirl").update!(pb_item_name: "Get Off My Lawn Paint Brush") Color.find_by_name("Ghost").update!(pb_item_name: "Ghost Paint Brush") Color.find_by_name("Glowing").update!(pb_item_name: "Glowing Paint Brush") Color.find_by_name("Gold").update!(pb_item_name: "Golden Paint Brush") Color.find_by_name("Green").update!(pb_item_name: "Green Paint Brush") Color.find_by_name("Grey").update!(pb_item_name: "Grey Paint Brush") Color.find_by_name("Halloween").update!(pb_item_name: "Halloween Paint Brush") Color.find_by_name("Invisible").update!(pb_item_name: "Invisible Paint Brush") Color.find_by_name("Desert").update!(pb_item_name: "Lost Desert Paint Brush") Color.find_by_name("Maractite").update!(pb_item_name: "Maractite Paint Brush") Color.find_by_name("Maraquan").update!(pb_item_name: "Maraquan Paint Brush") Color.find_by_name("Marble").update!(pb_item_name: "Marble Paint Brush") Color.find_by_name("Island").update!(pb_item_name: "Mystery Island Paint Brush") Color.find_by_name("Oil Paint").update!(pb_item_name: "Oil Paint Brush") Color.find_by_name("Orange").update!(pb_item_name: "Orange Paint Brush") Color.find_by_name("Origami").update!(pb_item_name: "Origami Paint Brush") Color.find_by_name("Pastel").update!(pb_item_name: "Pastel Paint Brush") Color.find_by_name("Pink").update!(pb_item_name: "Pink Paint Brush") Color.find_by_name("Pirate").update!(pb_item_name: "Pirate Paint Brush") Color.find_by_name("Plushie").update!(pb_item_name: "Plushie Paint Brush") Color.find_by_name("Polka Dot").update!(pb_item_name: "Polka Dot Paint Brush") Color.find_by_name("Purple").update!(pb_item_name: "Purple Paint Brush") Color.find_by_name("Rainbow").update!(pb_item_name: "Rainbow Paint Brush") Color.find_by_name("Red").update!(pb_item_name: "Red Paint Brush") Color.find_by_name("Relic").update!(pb_item_name: "Relic Paint Brush") Color.find_by_name("Royalboy").update!(pb_item_name: "Royal Paint Brush") Color.find_by_name("Royalgirl").update!(pb_item_name: "Royal Paint Brush") Color.find_by_name("Sketch").update!(pb_item_name: "Scritchy Sketchy Paint Brush") Color.find_by_name("Shadow").update!(pb_item_name: "Shadow Paint Brush") Color.find_by_name("Silver").update!(pb_item_name: "Silver Paint Brush") Color.find_by_name("Skunk").update!(pb_item_name: "Skunk Paint Brush") Color.find_by_name("Snow").update!(pb_item_name: "Snow Paint Brush") Color.find_by_name("Speckled").update!(pb_item_name: "Speckled Paint Brush") Color.find_by_name("Split").update!(pb_item_name: "Split Paint Brush") Color.find_by_name("Spotted").update!(pb_item_name: "Spotted Paint Brush") Color.find_by_name("Starry").update!(pb_item_name: "Starry Paint Brush") Color.find_by_name("Stealthy").update!(pb_item_name: "Stealth Paint Brush") Color.find_by_name("Steampunk").update!(pb_item_name: "Steampunk Paint Brush") Color.find_by_name("Strawberry").update!(pb_item_name: "Strawberry Fields Forever Paint Brush") Color.find_by_name("Striped").update!(pb_item_name: "Striped Paint Brush") Color.find_by_name("Swamp Gas").update!(pb_item_name: "Swamp Gas Paint Brush") Color.find_by_name("Toy").update!(pb_item_name: "Toy Paint Brush") Color.find_by_name("Transparent").update!(pb_item_name: "Transparent Paint Brush") Color.find_by_name("Tyrannian").update!(pb_item_name: "Tyrannian Paint Brush") Color.find_by_name("Usuki Boy").update!(pb_item_name: "Usuki Paint Brush") Color.find_by_name("Usuki Girl").update!(pb_item_name: "Usuki Paint Brush") Color.find_by_name("Valentine").update!(pb_item_name: "Valentine Paint Brush") Color.find_by_name("Water").update!(pb_item_name: "Water Paint Brush") Color.find_by_name("White").update!(pb_item_name: "White Paint Brush") Color.find_by_name("Woodland").update!(pb_item_name: "Woodland Paint Brush") Color.find_by_name("Wraith").update!(pb_item_name: "Wraith Paint Brush") Color.find_by_name("Yellow").update!(pb_item_name: "Yellow Paint Brush") Color.find_by_name("Zombie").update!(pb_item_name: "Zombie Paint Brush") ```
2024-05-22 15:41:46 -07:00
def shop_wizard_url_for(item_or_name)
item_or_name = item_or_name.name if item_or_name.is_a? Item
SHOP_WIZARD_URL_TEMPLATE.expand(string: item_or_name).to_s
end
TRADING_POST_URL_TEMPLATE = Addressable::Template.new(
"https://www.neopets.com/island/tradingpost.phtml?type=browse&criteria=item_exact{&search_string}"
)
Add more PB item info and links to Item Getting Guide I add some infrastructural support for inferring an item's paintbrush color (if any), and a field to the database to manually track an item's paint brush item name! This is both useful for tracking which colors are even *available* via paint brush, and also for working with colors with unusual paint brush names, like the "Get Off My Lawn Paint Brush" (for Elderly pets). Here's the script I ran to backfill this for current colors and their paint brushes! ```rb Color.find_by_name("Baby").update!(pb_item_name: "Baby Paint Brush") Color.find_by_name("Biscuit").update!(pb_item_name: "Biscuit Paint Brush") Color.find_by_name("Blue").update!(pb_item_name: "Blue Paint Brush") Color.find_by_name("Brown").update!(pb_item_name: "Brown Paint Brush") Color.find_by_name("Camouflage").update!(pb_item_name: "Camouflage Paint Brush") Color.find_by_name("Candy").update!(pb_item_name: "Candy Paint Brush") Color.find_by_name("Checkered").update!(pb_item_name: "Checkered Paint Brush") Color.find_by_name("Christmas").update!(pb_item_name: "Christmas Paint Brush") Color.find_by_name("Cloud").update!(pb_item_name: "Cloud Paint Brush") Color.find_by_name("Darigan").update!(pb_item_name: "Darigan Paint Brush") Color.find_by_name("Dimensional").update!(pb_item_name: "Dimensional Paint Brush") Color.find_by_name("Disco").update!(pb_item_name: "Disco Fever Paint Brush") Color.find_by_name("Electric").update!(pb_item_name: "Electric Blue Paint Brush") Color.find_by_name("Eventide").update!(pb_item_name: "Eventide Paint Brush") Color.find_by_name("Faerie").update!(pb_item_name: "Faerie Paint Brush") Color.find_by_name("Fire").update!(pb_item_name: "Fire, Fire, Your Pants On Fire Paint Brush") Color.find_by_name("Elderlyboy").update!(pb_item_name: "Get Off My Lawn Paint Brush") Color.find_by_name("Elderlygirl").update!(pb_item_name: "Get Off My Lawn Paint Brush") Color.find_by_name("Ghost").update!(pb_item_name: "Ghost Paint Brush") Color.find_by_name("Glowing").update!(pb_item_name: "Glowing Paint Brush") Color.find_by_name("Gold").update!(pb_item_name: "Golden Paint Brush") Color.find_by_name("Green").update!(pb_item_name: "Green Paint Brush") Color.find_by_name("Grey").update!(pb_item_name: "Grey Paint Brush") Color.find_by_name("Halloween").update!(pb_item_name: "Halloween Paint Brush") Color.find_by_name("Invisible").update!(pb_item_name: "Invisible Paint Brush") Color.find_by_name("Desert").update!(pb_item_name: "Lost Desert Paint Brush") Color.find_by_name("Maractite").update!(pb_item_name: "Maractite Paint Brush") Color.find_by_name("Maraquan").update!(pb_item_name: "Maraquan Paint Brush") Color.find_by_name("Marble").update!(pb_item_name: "Marble Paint Brush") Color.find_by_name("Island").update!(pb_item_name: "Mystery Island Paint Brush") Color.find_by_name("Oil Paint").update!(pb_item_name: "Oil Paint Brush") Color.find_by_name("Orange").update!(pb_item_name: "Orange Paint Brush") Color.find_by_name("Origami").update!(pb_item_name: "Origami Paint Brush") Color.find_by_name("Pastel").update!(pb_item_name: "Pastel Paint Brush") Color.find_by_name("Pink").update!(pb_item_name: "Pink Paint Brush") Color.find_by_name("Pirate").update!(pb_item_name: "Pirate Paint Brush") Color.find_by_name("Plushie").update!(pb_item_name: "Plushie Paint Brush") Color.find_by_name("Polka Dot").update!(pb_item_name: "Polka Dot Paint Brush") Color.find_by_name("Purple").update!(pb_item_name: "Purple Paint Brush") Color.find_by_name("Rainbow").update!(pb_item_name: "Rainbow Paint Brush") Color.find_by_name("Red").update!(pb_item_name: "Red Paint Brush") Color.find_by_name("Relic").update!(pb_item_name: "Relic Paint Brush") Color.find_by_name("Royalboy").update!(pb_item_name: "Royal Paint Brush") Color.find_by_name("Royalgirl").update!(pb_item_name: "Royal Paint Brush") Color.find_by_name("Sketch").update!(pb_item_name: "Scritchy Sketchy Paint Brush") Color.find_by_name("Shadow").update!(pb_item_name: "Shadow Paint Brush") Color.find_by_name("Silver").update!(pb_item_name: "Silver Paint Brush") Color.find_by_name("Skunk").update!(pb_item_name: "Skunk Paint Brush") Color.find_by_name("Snow").update!(pb_item_name: "Snow Paint Brush") Color.find_by_name("Speckled").update!(pb_item_name: "Speckled Paint Brush") Color.find_by_name("Split").update!(pb_item_name: "Split Paint Brush") Color.find_by_name("Spotted").update!(pb_item_name: "Spotted Paint Brush") Color.find_by_name("Starry").update!(pb_item_name: "Starry Paint Brush") Color.find_by_name("Stealthy").update!(pb_item_name: "Stealth Paint Brush") Color.find_by_name("Steampunk").update!(pb_item_name: "Steampunk Paint Brush") Color.find_by_name("Strawberry").update!(pb_item_name: "Strawberry Fields Forever Paint Brush") Color.find_by_name("Striped").update!(pb_item_name: "Striped Paint Brush") Color.find_by_name("Swamp Gas").update!(pb_item_name: "Swamp Gas Paint Brush") Color.find_by_name("Toy").update!(pb_item_name: "Toy Paint Brush") Color.find_by_name("Transparent").update!(pb_item_name: "Transparent Paint Brush") Color.find_by_name("Tyrannian").update!(pb_item_name: "Tyrannian Paint Brush") Color.find_by_name("Usuki Boy").update!(pb_item_name: "Usuki Paint Brush") Color.find_by_name("Usuki Girl").update!(pb_item_name: "Usuki Paint Brush") Color.find_by_name("Valentine").update!(pb_item_name: "Valentine Paint Brush") Color.find_by_name("Water").update!(pb_item_name: "Water Paint Brush") Color.find_by_name("White").update!(pb_item_name: "White Paint Brush") Color.find_by_name("Woodland").update!(pb_item_name: "Woodland Paint Brush") Color.find_by_name("Wraith").update!(pb_item_name: "Wraith Paint Brush") Color.find_by_name("Yellow").update!(pb_item_name: "Yellow Paint Brush") Color.find_by_name("Zombie").update!(pb_item_name: "Zombie Paint Brush") ```
2024-05-22 15:41:46 -07:00
def trading_post_url_for(item_or_name)
item_or_name = item_or_name.name if item_or_name.is_a? Item
TRADING_POST_URL_TEMPLATE.expand(search_string: item_or_name).to_s
end
AUCTION_GENIE_URL_TEMPLATE = Addressable::Template.new(
"https://www.neopets.com/genie.phtml?type=process_genie&criteria=exact{&auctiongenie}"
)
def auction_genie_url_for(item)
AUCTION_GENIE_URL_TEMPLATE.expand(auctiongenie: item.name).to_s
end
def format_contribution_count(count)
" (&times;#{count})".html_safe if count > 1
end
2011-07-30 21:19:28 -07:00
def render_item_link(item)
render(partial: 'items/item_link', locals: {item: item})
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
NC_TRADE_VALUE_ESTIMATE_PATTERN = %r{
\A\s*
(?:
# Case 1: A single number
(?<single>[0-9]+)
|
# Case 2: A range from low to high
(?<low>[0-9]+)
\p{Dash_Punctuation}
(?<high>[0-9]+)
)
\s*\z
}x
def nc_trade_value_is_estimate(nc_trade_value)
nc_trade_value.value_text.match?(NC_TRADE_VALUE_ESTIMATE_PATTERN)
end
# Try to parse the NC trade value's text into something styled a bit more
# nicely for our use case.
def nc_trade_value_estimate_text(nc_trade_value)
match = nc_trade_value.value_text.match(NC_TRADE_VALUE_ESTIMATE_PATTERN)
return nc_trade_value if match.nil?
match => {single:, low:, high:}
if single.present?
pluralize single.to_i, "capsule"
elsif low.present? && high.present?
"#{low}#{high} capsules"
else
nc_trade_value
end
end
def nc_total_for(items)
items.map(&:current_nc_price).sum
end
def dyeworks_nc_total_for(items)
nc_total_for items.map(&:dyeworks_base_item)
end
def dyeworks_average_num_potions_for(items)
# Compute the number of expected potions for each (inverse of the odds),
# sum them, then round up.
items.map { |i| 1 / i.dyeworks_odds }.sum.ceil
end
def dyeworks_estimated_potions_cost_for(items)
# NOTE: You could do bundles too, but let's just keep it simple.
dyeworks_average_num_potions_for(items) * 125
end
def complexity_for(items)
max_name_length = items.map(&:name).map(&:length).max
max_name_length >= 40 ? "high" : "low"
end
def probability(p)
case p
when 1
"100%"
when 0
"0%"
else
"#{p.numerator} in #{p.denominator}"
end
end
def outfit_viewer_is_playing
cookies["DTIOutfitViewerIsPlaying"] == "true"
end
def item_fits?(item, pet_type)
item.appearances.any? { |a| a.fits? pet_type }
end
def species_face_tooltip(pet_type, item)
if item_fits?(item, pet_type)
"#{pet_type.species.human_name}"
else
"#{pet_type.species.human_name}: No data yet"
end
end
def item_zone_partial_fit?(appearances_in_zone, all_appearances)
appearances_in_zone.size < all_appearances.size
end
def item_zone_species_list(appearances_in_zone)
appearances_in_zone.map(&:species).uniq.map(&:human_name).sort.join(", ")
end
def pet_type_image(pet_type, emotion, size, **options)
src = pet_type_image_url(pet_type, emotion:, size:)
size_2x = PetTypeImage::SizeUpgrades[size]
srcset = if size_2x
[[pet_type_image_url(pet_type, emotion:, size: size_2x), "2x"]]
end
image_tag(src, srcset:, **options)
end
def item_header_user_lists_form_state
cookies.fetch("DTIItemPageUserListsFormState", "closed")
end
2010-05-15 10:47:46 -07:00
end