93 lines
2.7 KiB
Ruby
93 lines
2.7 KiB
Ruby
require 'rocketamf/remote_gateway'
|
|
require 'open-uri'
|
|
|
|
class NeopetsUser
|
|
include ActiveModel::Conversion
|
|
extend ActiveModel::Naming
|
|
|
|
NEOPETS_URL_ORIGIN = ENV['NEOPETS_URL_ORIGIN'] || 'http://www.neopets.com'
|
|
GATEWAY_URL = NEOPETS_URL_ORIGIN + '/amfphp/gateway.php'
|
|
GET_PETS_METHOD = RocketAMF::RemoteGateway.new(GATEWAY_URL).
|
|
service('MobileService').action('getPets')
|
|
|
|
attr_accessor :username
|
|
attr_reader :hangers, :list_id
|
|
|
|
def initialize(app_user)
|
|
@app_user = app_user
|
|
end
|
|
|
|
def list_id=(list_id)
|
|
# TODO: use null lists instead
|
|
@list_id = list_id
|
|
if list_id == 'true'
|
|
@closet_list = nil
|
|
@hangers_owned = true
|
|
elsif list_id == 'false'
|
|
@closet_list = nil
|
|
@hangers_owned = false
|
|
elsif list_id.present?
|
|
@closet_list = @app_user.closet_lists.find(list_id)
|
|
@hangers_owned = @closet_list.hangers_owned?
|
|
end
|
|
end
|
|
|
|
def load!
|
|
neopets_language_code = I18n.compatible_neopets_language_code_for(I18n.locale)
|
|
begin
|
|
envelope = GET_PETS_METHOD.request([@username]).post(
|
|
:timeout => 4,
|
|
:headers => {
|
|
'Cookie' => "lang=#{neopets_language_code}"
|
|
}
|
|
)
|
|
rescue RocketAMF::RemoteGateway::AMFError => e
|
|
raise NotFound, e.message
|
|
rescue RocketAMF::RemoteGateway::ConnectionError => e
|
|
raise NotFound, e.message, e.backtrace
|
|
end
|
|
|
|
|
|
pets_data = envelope.messages[0].data.body
|
|
raise NotFound if pets_data == false
|
|
pets = pets_data.map { |pet| Pet.find_or_initialize_by(name: pet['name']) }
|
|
items = pets.each(&:load!).map(&:items).flatten
|
|
item_ids = items.map(&:id)
|
|
item_quantities = {}
|
|
items.each do |i|
|
|
item_quantities[i] ||= 0
|
|
item_quantities[i] += 1
|
|
end
|
|
|
|
# TODO: DRY up with NeopetsPage
|
|
# We don't want to insert duplicate hangers of what a user owns if they
|
|
# already have it in another list (e.g. imports to Items You Own *after*
|
|
# curating their Up For Trade list), so we check for the hanger's presence
|
|
# in *all* items the user owns or wants (whichever is appropriate for this
|
|
# request).
|
|
hangers_scope = @app_user.closet_hangers.where(owned: @hangers_owned)
|
|
existing_hanger_item_ids = hangers_scope.select(:item_id).
|
|
where(item_id: item_ids).map(&:item_id)
|
|
|
|
@hangers = []
|
|
item_quantities.each do |item, quantity|
|
|
next if existing_hanger_item_ids.include?(item.id)
|
|
hanger = hangers_scope.build
|
|
hanger.item = item
|
|
hanger.quantity = quantity
|
|
hanger.list = @closet_list
|
|
@hangers << hanger
|
|
end
|
|
end
|
|
|
|
def save_hangers!
|
|
ClosetHanger.transaction { @hangers.each(&:save!) }
|
|
end
|
|
|
|
def persisted?
|
|
false
|
|
end
|
|
|
|
class NotFound < RuntimeError; end
|
|
end
|
|
|