basic neopia api integration

This commit is contained in:
Emi Matchu 2013-12-08 22:59:36 -06:00
parent fef87d664a
commit 7c6e607612
11 changed files with 138 additions and 41 deletions

View file

@ -211,6 +211,7 @@ View.Hash = function (wardrobe) {
STRING: 2,
INTEGER_ARRAY: 3
}, KEYS = {
biologies: TYPES.INTEGER_ARRAY,
closet: TYPES.INTEGER_ARRAY,
color: TYPES.INTEGER,
name: TYPES.STRING,
@ -252,6 +253,9 @@ View.Hash = function (wardrobe) {
}
}
if(new_data.biologies) {
wardrobe.outfits.setPetStateAssetsByIds(new_data.biologies);
}
if(new_data.color !== data.color || new_data.species !== data.species) {
wardrobe.outfits.setPetTypeByColorAndSpecies(new_data.color, new_data.species);
}
@ -372,7 +376,7 @@ View.Hash = function (wardrobe) {
singleOutfitResponse('updatePetState', function (pet_state) {
var pet_type = wardrobe.outfits.getPetType();
if(pet_state.id != data.state && pet_type && (data.state || pet_state.id != pet_type.pet_states[0].id)) {
changeQuery({state: pet_state.id});
changeQuery({biologies: undefined, state: pet_state.id});
}
});
@ -384,6 +388,7 @@ View.Hash = function (wardrobe) {
wardrobe.outfits.bind('loadOutfit', function (outfit) {
changeQuery({
biologies: undefined,
closet: outfit.getClosetItemIds(),
color: outfit.pet_type.color_id,
objects: outfit.getWornItemIds(),

View file

@ -476,10 +476,27 @@ function Wardrobe() {
}
}
this.setPetStateAssetsByIds = function (assetIds, petStateOnLoad) {
this.pet_state = PetState.createFromAssetIds(assetIds);
this.pet_state.loadAssets(petStateOnLoad);
}
this.setPetStateById = function (id, petStateOnLoad) {
if(!id && this.pet_type) {
if(this.pet_state) {
var candidate;
for(var i = 0; i < this.pet_type.pet_states.length; i++) {
candidate = this.pet_type.pet_states[i];
if(arraysMatch(this.pet_state.assetIds, candidate.assetIds)) {
id = candidate.id;
break;
}
}
}
if(!id) {
id = this.pet_type.pet_states[0].id;
}
}
if(id) {
this.pet_state = PetState.find(id);
this.pet_state_id = id;
@ -712,6 +729,7 @@ function Wardrobe() {
this.id = id;
this.gender_mood_description = '';
this.assetIds = [];
this.assets = [];
this.loadAssets = function (success) {
@ -722,6 +740,9 @@ function Wardrobe() {
$.getJSON('/pet_states/' + pet_state.id + '/swf_assets.json',
function (data) {
pet_state.assets = $.map(data, function (obj) { return new BiologyAsset(obj) });
pet_state.assetIds = $.map(pet_state.assets, function (asset) {
return asset.id;
});
loaded = true;
success(pet_state);
});
@ -730,11 +751,32 @@ function Wardrobe() {
this.update = function (data) {
this.gender_mood_description = data.gender_mood_description;
this.assetIds = data.swf_asset_ids;
}
PetState.cache[id] = this;
}
PetState.createFromAssetIds = function (assetIds) {
// Fun lame hacks to be able to create from biology asset IDs. Not even a
// real PetState, gasp!
assetIds.sort();
var petState = {
id: null,
gender_mood_description: '',
assets: [],
assetIds: assetIds,
loadAssets: function (success) {
$.getJSON('/swf_assets.json', {ids: {biology: assetIds}}, function (data) {
this.assets = $.map(data, function (obj) { return new BiologyAsset(obj) });
success(petState);
});
},
update: $.noop
};
return petState;
}
PetState.find = function (id) {
var pet_state = PetState.cache[id];
if(!pet_state) {
@ -1001,6 +1043,10 @@ function Wardrobe() {
}
}
this.setPetStateAssetsByIds = function (assetIds) {
outfit.setPetStateAssetsByIds(assetIds, controller.event('updatePetState'));
}
this.setPetStateById = function (pet_state_id) {
outfit.setPetStateById(pet_state_id, controller.event('updatePetState'));
}

View file

@ -27,6 +27,10 @@ class ApplicationController < ActionController::Base
I18n.default_locale
end
def local_only
raise AccessDenied unless request.ip == '127.0.0.1'
end
def localized_fragment_exist?(key)
localized_key = localize_fragment_key(key, locale)
fragment_exist?(localized_key)

View file

@ -3,6 +3,9 @@ class PetsController < ApplicationController
rescue_from PetType::DownloadError, SwfAsset::DownloadError, :with => :asset_download_error
rescue_from Pet::DownloadError, :with => :pet_download_error
protect_from_forgery except: :submit
before_filter :local_only, only: :submit
cache_sweeper :user_sweeper
def load
@ -11,14 +14,7 @@ class PetsController < ApplicationController
else
raise Pet::PetNotFound unless params[:name]
@pet = Pet.load(params[:name], :item_scope => Item.includes(:translations))
if user_signed_in?
points = current_user.contribute! @pet
else
@pet.save
points = true
end
@pet.translate_items
points = contribute(current_user, @pet)
respond_to do |format|
format.html do
@ -33,8 +29,26 @@ class PetsController < ApplicationController
end
end
def submit
viewer_data = HashWithIndifferentAccess.new(JSON.parse(params[:viewer_data]))
@pet = Pet.from_viewer_data(viewer_data, :item_scope => Item.includes(:translations))
@user = params[:user_id].present? ? User.find(params[:user_id]) : nil
render json: {points: contribute(@user, @pet)}
end
protected
def contribute(user, pet)
if user.present?
points = user.contribute! pet
else
pet.save!
points = true
end
pet.translate_items
points
end
def destination
case (params[:destination] || params[:origin])
when 'wardrobe' then wardrobe_path + '#'

View file

@ -50,6 +50,10 @@ module OutfitsHelper
content_tag(:dd, search_query_description(base, filter_key))
end
def remote_load_pet_path
"http://#{Rails.configuration.neopia_host}/api/1/pet/customization"
end
def outfit_creation_summary(outfit)
user = outfit.user
user_link = link_to(user.name, user_contributions_path(user))

View file

@ -272,8 +272,10 @@ class Item < ActiveRecord::Base
end
def origin_registry_info=(info)
Rails.logger.debug("info! #{info}")
# bear in mind that numbers from registries are floats
self.species_support_ids = info[:species_support].map(&:to_i)
species_support_strs = info['species_support'] || []
self.species_support_ids = species_support_strs.map(&:to_i)
attribute_names.each do |attribute|
value = info[attribute.to_sym]
if value

View file

@ -18,11 +18,16 @@ class Pet < ActiveRecord::Base
}
def load!(options={})
options[:item_scope] ||= Item.scoped
options[:locale] ||= I18n.default_locale
I18n.with_locale(options.delete(:locale)) do
use_viewer_data(fetch_viewer_data(options.delete(:timeout)), options)
end
true
end
def use_viewer_data(viewer_data, options={})
options[:item_scope] ||= Item.scoped
I18n.with_locale(options[:locale]) do
viewer_data = fetch_viewer_data(options[:timeout])
pet_data = viewer_data[:custom_pet]
self.pet_type = PetType.find_or_initialize_by_species_id_and_color_id(
@ -40,9 +45,6 @@ class Pet < ActiveRecord::Base
options[:item_scope])
end
true
end
def fetch_viewer_data(timeout=4)
begin
neopets_language_code = I18n.compatible_neopets_language_code_for(I18n.locale)
@ -170,6 +172,12 @@ class Pet < ActiveRecord::Base
pet
end
def self.from_viewer_data(viewer_data, options={})
pet = Pet.find_or_initialize_by_name(viewer_data[:custom_pet][:name])
pet.use_viewer_data(viewer_data, options)
pet
end
class PetNotFound < Exception;end
class DownloadError < Exception;end
end

View file

@ -38,7 +38,11 @@ class PetState < ActiveRecord::Base
order("glitched ASC, (mood_id = 1) DESC, COUNT(effect_assets.remote_id) ASC, COUNT(parents_swf_assets.swf_asset_id) DESC, female ASC, SUM(parents_swf_assets.swf_asset_id) ASC")
def as_json(options={})
serializable_hash :only => [:id], :methods => [:gender_mood_description]
{
id: id,
gender_mood_description: gender_mood_description,
swf_asset_ids: swf_asset_ids_array
}
end
def reassign_children_to!(main_pet_state)
@ -66,13 +70,17 @@ class PetState < ActiveRecord::Base
end
def sort_swf_asset_ids!
self.swf_asset_ids = swf_asset_ids.split(',').map(&:to_i).sort.join(',')
self.swf_asset_ids = swf_asset_ids_array.sort.join(',')
end
def swf_asset_ids
self['swf_asset_ids']
end
def swf_asset_ids_array
swf_asset_ids.split(',').map(&:to_i)
end
def swf_asset_ids=(ids)
self['swf_asset_ids'] = ids
end

View file

@ -10,18 +10,18 @@
%h1= t 'app_name'
%h2= t '.tagline'
= form_tag load_pet_path, :id => 'load-pet-to-wardrobe' do
- localized_cache :action_suffix => 'main_load_pet_form_content' do
= origin_tag root_path
= destination_tag 'wardrobe'
= form_tag remote_load_pet_path, method: 'GET', id: 'load-pet-to-wardrobe' do
= hidden_field_tag 'impress_user', current_user.try(:id)
- localized_cache action_suffix: 'outfits#new main_load_pet_form_content' do
= hidden_field_tag 'redirect', "#{wardrobe_url}\#{q}"
%fieldset
%legend= t '.load_pet.legend'
= pet_name_tag :id => 'main-pet-name'
%button{:type => "submit"}
= t '.load_pet.submit'
= form_tag wardrobe_path, :method => 'get', :id => 'start-from-scratch' do
- localized_cache :action_suffix => 'start_from_scratch_form_content' do
- localized_cache action_suffix: 'outfits#new start_from_scratch_form' do
= form_tag wardrobe_path, method: 'GET', id: 'start-from-scratch', authenticity_token: false do
%fieldset
%legend= t '.start_from_scratch.legend'
= pet_attribute_select 'color', @colors, 8
@ -60,8 +60,8 @@
%div
%h4= t '.modeling_hub.tagline'
%p= t '.modeling_hub.description'
= form_tag load_pet_path do
= origin_tag root_path
= form_tag remote_load_pet_path, method: 'GET' do
= hidden_field_tag 'redirect', "#{root_url}\#{q}"
= pet_name_tag :placeholder => t('.modeling_hub.load_pet.placeholder')
= submit_tag t('.modeling_hub.load_pet.submit')

View file

@ -0,0 +1,5 @@
if Rails.env.production?
Rails.configuration.neopia_host = 'neopia.openneo.net'
else
Rails.configuration.neopia_host = 'localhost:3200'
end

View file

@ -49,6 +49,7 @@ OpenneoImpressItems::Application.routes.draw do
match '/users/current-user/outfits' => 'outfits#index', :as => :current_user_outfits
match '/pets/load' => 'pets#load', :method => :post, :as => :load_pet
match '/pets/submit' => 'pets#submit', :method => :post
match '/modeling' => 'pets#bulk', :as => :bulk_pets
match '/login' => 'sessions#new', :as => :login