globalize3 for items

This commit is contained in:
Emi Matchu 2013-01-13 20:10:01 -06:00
parent 1439e4a74c
commit ef2423e87f
3 changed files with 60 additions and 19 deletions

View file

@ -10,13 +10,16 @@ class PetsController < ApplicationController
redirect_to roulette_path
else
raise Pet::PetNotFound unless params[:name]
@pet = Pet.load(params[:name])
@pet = Pet.load(params[:name], :item_scope => Item.with_translations)
if user_signed_in?
points = current_user.contribute! @pet
else
@pet.save
points = true
end
@pet.translate_items
respond_to do |format|
format.html do
path = destination + @pet.wardrobe_query

View file

@ -302,7 +302,7 @@ class Item < ActiveRecord::Base
end
end
def self.collection_from_pet_type_and_registries(pet_type, info_registry, asset_registry)
def self.collection_from_pet_type_and_registries(pet_type, info_registry, asset_registry, scope=Item.scoped)
# bear in mind that registries are arrays with many nil elements,
# due to how the parser works
@ -317,7 +317,7 @@ class Item < ActiveRecord::Base
# Collect existing relationships
existing_relationships_by_item_id_and_swf_asset_id = {}
existing_items = Item.find_all_by_id(item_ids, :include => :parent_swf_asset_relationships)
existing_items = scope.find_all_by_id(item_ids, :include => :parent_swf_asset_relationships)
existing_items.each do |item|
items[item.id] = item
relationships_by_swf_asset_id = {}

View file

@ -16,7 +16,13 @@ class Pet < ActiveRecord::Base
joins(:pet_type).where(PetType.arel_table[:id].in(color_ids))
}
def load!
def load!(options={})
options[:item_scope] ||= Item.scoped
options[:locale] ||= I18n.default_locale
original_locale = I18n.locale
I18n.locale = options[:locale]
require 'ostruct'
begin
neopets_language_code = I18n.translate('neopets_language_code')
@ -36,18 +42,27 @@ class Pet < ActiveRecord::Base
end
contents = OpenStruct.new(envelope.messages[0].data.body)
pet_data = OpenStruct.new(contents.custom_pet)
self.pet_type = PetType.find_or_initialize_by_species_id_and_color_id(
pet_data.species_id.to_i,
pet_data.color_id.to_i
)
self.pet_type.body_id = pet_data.body_id
self.pet_type.origin_pet = self
biology = pet_data.biology_by_zone
biology[0] = nil # remove effects if present
@pet_state = self.pet_type.add_pet_state_from_biology! biology
@pet_state.label_by_pet(self, pet_data.owner)
@items = Item.collection_from_pet_type_and_registries(self.pet_type,
contents.object_info_registry, contents.object_asset_registry)
# in case this is running in a thread, explicitly grab an ActiveRecord
# connection, to avoid connection conflicts
Pet.connection_pool.with_connection do
self.pet_type = PetType.find_or_initialize_by_species_id_and_color_id(
pet_data.species_id.to_i,
pet_data.color_id.to_i
)
self.pet_type.body_id = pet_data.body_id
self.pet_type.origin_pet = self
biology = pet_data.biology_by_zone
biology[0] = nil # remove effects if present
@pet_state = self.pet_type.add_pet_state_from_biology! biology
@pet_state.label_by_pet(self, pet_data.owner)
@items = Item.collection_from_pet_type_and_registries(self.pet_type,
contents.object_info_registry, contents.object_asset_registry,
options[:item_scope])
end
I18n.locale = original_locale
true
end
@ -74,7 +89,6 @@ class Pet < ActiveRecord::Base
{}.tap do |candidates|
if @items
@items.each do |item|
puts "#{item.name}: #{item.translations_needed}"
item.needed_translations.each do |locale|
candidates[locale] ||= []
candidates[locale] << item
@ -83,6 +97,30 @@ class Pet < ActiveRecord::Base
end
end
end
def translate_items
candidates = self.item_translation_candidates
until candidates.empty?
last_pet_loaded = nil
reloaded_pets = Parallel.map(candidates.keys, :in_threads => 8) do |locale|
Rails.logger.info "Reloading #{name} in #{locale}"
last_pet_loaded = Pet.load(name, :item_scope => Item.with_translations,
:locale => locale)
end
reloaded_pets.map(&:save!)
previous_candidates = candidates
candidates = last_pet_loaded.item_translation_candidates
if previous_candidates == candidates
# This condition should never happen if Neopets responds with correct
# data, but, if Neopets somehow responds with incorrect data, this
# condition could throw us into an infinite loop if uncaught. Better
# safe than sorry when working with external services.
raise "No change when reloading #{name} for #{candidates}"
end
end
end
before_validation do
pet_type.save!
@ -99,9 +137,9 @@ class Pet < ActiveRecord::Base
end
end
def self.load(name)
def self.load(name, options={})
pet = Pet.find_or_initialize_by_name(name)
pet.load!
pet.load!(options)
pet
end