Merge branch 'globalized_search' into i18n
Conflicts: Gemfile app/controllers/application_controller.rb app/controllers/items_controller.rb app/controllers/outfits_controller.rb app/helpers/application_helper.rb app/views/items/show.html.haml config/locales/en-MEEP.yml config/locales/en.yml public/stylesheets/compiled/screen.css
This commit is contained in:
commit
d3b449a8f9
107 changed files with 1557 additions and 650 deletions
9
Gemfile
9
Gemfile
|
@ -43,13 +43,20 @@ gem 'neopets', :git => 'git://github.com/matchu/neopets.git'
|
||||||
|
|
||||||
gem "mini_magick", "~> 3.4"
|
gem "mini_magick", "~> 3.4"
|
||||||
|
|
||||||
gem "fog", "~> 1.1.2"
|
gem "fog", "~> 1.8.0"
|
||||||
gem "carrierwave", "~> 0.5.8"
|
gem "carrierwave", "~> 0.5.8"
|
||||||
|
|
||||||
gem "parallel", "~> 0.5.17"
|
gem "parallel", "~> 0.5.17"
|
||||||
|
|
||||||
gem "http_accept_language", :git => "git://github.com/iain/http_accept_language.git"
|
gem "http_accept_language", :git => "git://github.com/iain/http_accept_language.git"
|
||||||
|
|
||||||
|
gem "globalize3"
|
||||||
|
|
||||||
|
# My flex branch fixes a minor pagination bug. Once it's merged into the
|
||||||
|
# original gem, we can switch back.
|
||||||
|
gem "flex", :require => "flex/rails", :git => "git@github.com:matchu/flex.git"
|
||||||
|
gem "patron", "~> 0.4.18"
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem "bullet", "~> 4.1.5"
|
gem "bullet", "~> 4.1.5"
|
||||||
end
|
end
|
||||||
|
|
104
Gemfile.lock
104
Gemfile.lock
|
@ -1,8 +1,8 @@
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/eventmachine/eventmachine.git
|
remote: git://github.com/eventmachine/eventmachine.git
|
||||||
revision: 69151c3ebb3e4ecf2bb9b6e2fab2022dc34f8541
|
revision: d7c8a14dc494193a775add4b16c1e303cab5b285
|
||||||
specs:
|
specs:
|
||||||
eventmachine (1.0.0.beta.4)
|
eventmachine (1.0.0)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/iain/http_accept_language.git
|
remote: git://github.com/iain/http_accept_language.git
|
||||||
|
@ -12,9 +12,9 @@ GIT
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/igrigorik/em-http-request.git
|
remote: git://github.com/igrigorik/em-http-request.git
|
||||||
revision: ce50f322ce08d43a4a747cf333ea576765d764c4
|
revision: 322f2273fa7ea07c1eeb92755bf67f1f05058e54
|
||||||
specs:
|
specs:
|
||||||
em-http-request (1.0.1)
|
em-http-request (1.0.3)
|
||||||
addressable (>= 2.2.3)
|
addressable (>= 2.2.3)
|
||||||
cookiejar
|
cookiejar
|
||||||
em-socksify
|
em-socksify
|
||||||
|
@ -30,21 +30,21 @@ GIT
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/igrigorik/em-synchrony.git
|
remote: git://github.com/igrigorik/em-synchrony.git
|
||||||
revision: c7209a58f9eb92e1dc81fb141297f9f257c2fdcb
|
revision: fe592a4b9b5345bca329477cb8f2f8d186b6fc7f
|
||||||
specs:
|
specs:
|
||||||
em-synchrony (1.0.0)
|
em-synchrony (1.0.2)
|
||||||
eventmachine (>= 1.0.0.beta.1)
|
eventmachine (>= 1.0.0.beta.1)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/matchu/neopets.git
|
remote: git://github.com/matchu/neopets.git
|
||||||
revision: fe694681a302243d2937e811355473f358035403
|
revision: d33aaf63d4617d9236ef0d99452b3bdc577cbc8e
|
||||||
specs:
|
specs:
|
||||||
neopets (0.0.2)
|
neopets (0.1.0)
|
||||||
nokogiri (~> 1.5.2)
|
nokogiri (~> 1.5.2)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/oldmoe/mysqlplus.git
|
remote: git://github.com/oldmoe/mysqlplus.git
|
||||||
revision: 3dbaa7c00ff0bb75ad9538cdef176c72de35d231
|
revision: f07936d2eb9b0893994ed99fe82267b5e7770d06
|
||||||
specs:
|
specs:
|
||||||
mysqlplus (0.1.1)
|
mysqlplus (0.1.1)
|
||||||
|
|
||||||
|
@ -54,6 +54,15 @@ GIT
|
||||||
specs:
|
specs:
|
||||||
RocketAMF (1.0.0)
|
RocketAMF (1.0.0)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git@github.com:matchu/flex.git
|
||||||
|
revision: d62f508f795ecdbb383f406865daa72368b43ba5
|
||||||
|
specs:
|
||||||
|
flex (0.4.1)
|
||||||
|
multi_json (~> 1.3.4)
|
||||||
|
progressbar (~> 0.11.0)
|
||||||
|
prompter (~> 0.1.5)
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: http://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
|
@ -88,17 +97,17 @@ GEM
|
||||||
activemodel (= 3.0.19)
|
activemodel (= 3.0.19)
|
||||||
activesupport (= 3.0.19)
|
activesupport (= 3.0.19)
|
||||||
activesupport (3.0.19)
|
activesupport (3.0.19)
|
||||||
addressable (2.2.6)
|
addressable (2.3.2)
|
||||||
arel (2.0.10)
|
arel (2.0.10)
|
||||||
bcrypt-ruby (2.1.4)
|
bcrypt-ruby (2.1.4)
|
||||||
builder (2.1.2)
|
builder (2.1.2)
|
||||||
bullet (4.1.5)
|
bullet (4.1.6)
|
||||||
uniform_notifier (~> 1.0.0)
|
uniform_notifier (~> 1.0.0)
|
||||||
carrierwave (0.5.8)
|
carrierwave (0.5.8)
|
||||||
activesupport (~> 3.0)
|
activesupport (~> 3.0)
|
||||||
character-encodings (0.4.1)
|
character-encodings (0.4.1)
|
||||||
chronic (0.6.7)
|
chronic (0.6.7)
|
||||||
closure-compiler (1.1.4)
|
closure-compiler (1.1.8)
|
||||||
compass (0.10.6)
|
compass (0.10.6)
|
||||||
haml (>= 3.0.4)
|
haml (>= 3.0.4)
|
||||||
cookiejar (0.3.0)
|
cookiejar (0.3.0)
|
||||||
|
@ -106,27 +115,32 @@ GEM
|
||||||
bcrypt-ruby (~> 2.1.2)
|
bcrypt-ruby (~> 2.1.2)
|
||||||
warden (~> 1.0.2)
|
warden (~> 1.0.2)
|
||||||
diff-lcs (1.1.3)
|
diff-lcs (1.1.3)
|
||||||
em-socksify (0.1.0)
|
dye (0.1.4)
|
||||||
eventmachine
|
em-socksify (0.2.1)
|
||||||
|
eventmachine (>= 1.0.0.beta.4)
|
||||||
erubis (2.6.6)
|
erubis (2.6.6)
|
||||||
abstract (>= 1.0.0)
|
abstract (>= 1.0.0)
|
||||||
excon (0.9.6)
|
excon (0.16.10)
|
||||||
factory_girl (2.3.2)
|
factory_girl (2.6.4)
|
||||||
activesupport
|
activesupport (>= 2.3.9)
|
||||||
factory_girl_rails (1.4.0)
|
factory_girl_rails (1.7.0)
|
||||||
factory_girl (~> 2.3.0)
|
factory_girl (~> 2.6.0)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
fog (1.1.2)
|
fog (1.8.0)
|
||||||
builder
|
builder
|
||||||
excon (~> 0.9.0)
|
excon (~> 0.14)
|
||||||
formatador (~> 0.2.0)
|
formatador (~> 0.2.0)
|
||||||
mime-types
|
mime-types
|
||||||
multi_json (~> 1.0.3)
|
multi_json (~> 1.0)
|
||||||
net-scp (~> 1.0.4)
|
net-scp (~> 1.0.4)
|
||||||
net-ssh (>= 2.1.3)
|
net-ssh (>= 2.1.3)
|
||||||
nokogiri (~> 1.5.0)
|
nokogiri (~> 1.5.0)
|
||||||
ruby-hmac
|
ruby-hmac
|
||||||
formatador (0.2.1)
|
formatador (0.2.4)
|
||||||
|
globalize3 (0.3.0)
|
||||||
|
activemodel (>= 3.0.0)
|
||||||
|
activerecord (>= 3.0.0)
|
||||||
|
paper_trail (~> 2)
|
||||||
haml (3.0.25)
|
haml (3.0.25)
|
||||||
hoptoad_notifier (2.4.11)
|
hoptoad_notifier (2.4.11)
|
||||||
activesupport
|
activesupport
|
||||||
|
@ -146,20 +160,28 @@ GEM
|
||||||
mime-types (1.19)
|
mime-types (1.19)
|
||||||
mini_magick (3.4)
|
mini_magick (3.4)
|
||||||
subexec (~> 0.2.1)
|
subexec (~> 0.2.1)
|
||||||
msgpack (0.4.6)
|
msgpack (0.4.7)
|
||||||
multi_json (1.0.4)
|
multi_json (1.3.7)
|
||||||
mysql2 (0.2.6)
|
mysql2 (0.2.18)
|
||||||
net-scp (1.0.4)
|
net-scp (1.0.4)
|
||||||
net-ssh (>= 1.99.1)
|
net-ssh (>= 1.99.1)
|
||||||
net-ssh (2.3.0)
|
net-ssh (2.6.3)
|
||||||
newrelic_rpm (3.5.3.25)
|
newrelic_rpm (3.5.5.38)
|
||||||
nokogiri (1.5.3)
|
nokogiri (1.5.6)
|
||||||
open4 (1.3.0)
|
open4 (1.3.0)
|
||||||
openneo-auth-signatory (0.1.0)
|
openneo-auth-signatory (0.1.0)
|
||||||
ruby-hmac
|
ruby-hmac
|
||||||
parallel (0.5.17)
|
paper_trail (2.7.0)
|
||||||
|
activerecord (~> 3.0)
|
||||||
|
railties (~> 3.0)
|
||||||
|
parallel (0.5.21)
|
||||||
|
patron (0.4.18)
|
||||||
polyglot (0.3.3)
|
polyglot (0.3.3)
|
||||||
rack (1.2.6)
|
progressbar (0.11.0)
|
||||||
|
prompter (0.1.5)
|
||||||
|
dye (>= 0.1.1)
|
||||||
|
yard (>= 0.6.3)
|
||||||
|
rack (1.2.7)
|
||||||
rack-fiber_pool (0.9.2)
|
rack-fiber_pool (0.9.2)
|
||||||
rack-mount (0.6.14)
|
rack-mount (0.6.14)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
|
@ -183,9 +205,9 @@ GEM
|
||||||
rdiscount (1.6.8)
|
rdiscount (1.6.8)
|
||||||
rdoc (3.12)
|
rdoc (3.12)
|
||||||
json (~> 1.4)
|
json (~> 1.4)
|
||||||
redis (2.2.2)
|
redis (3.0.2)
|
||||||
redis-namespace (1.1.0)
|
redis-namespace (1.2.1)
|
||||||
redis (< 3.0.0)
|
redis (~> 3.0.0)
|
||||||
resque (1.15.0)
|
resque (1.15.0)
|
||||||
json (~> 1.4.6)
|
json (~> 1.4.6)
|
||||||
redis-namespace (>= 0.10.0)
|
redis-namespace (>= 0.10.0)
|
||||||
|
@ -214,14 +236,14 @@ GEM
|
||||||
rspec-rails (2.0.1)
|
rspec-rails (2.0.1)
|
||||||
rspec (~> 2.0.0)
|
rspec (~> 2.0.0)
|
||||||
ruby-hmac (0.4.0)
|
ruby-hmac (0.4.0)
|
||||||
rufus-scheduler (2.0.16)
|
rufus-scheduler (2.0.17)
|
||||||
tzinfo (>= 0.3.23)
|
tzinfo (>= 0.3.23)
|
||||||
sanitize (2.0.3)
|
sanitize (2.0.3)
|
||||||
nokogiri (>= 1.4.4, < 1.6)
|
nokogiri (>= 1.4.4, < 1.6)
|
||||||
sinatra (1.2.8)
|
sinatra (1.2.8)
|
||||||
rack (~> 1.1)
|
rack (~> 1.1)
|
||||||
tilt (>= 1.2.2, < 2.0)
|
tilt (>= 1.2.2, < 2.0)
|
||||||
subexec (0.2.1)
|
subexec (0.2.2)
|
||||||
swf_converter (0.0.3)
|
swf_converter (0.0.3)
|
||||||
thor (0.14.6)
|
thor (0.14.6)
|
||||||
tilt (1.3.3)
|
tilt (1.3.3)
|
||||||
|
@ -230,14 +252,15 @@ GEM
|
||||||
polyglot (>= 0.3.1)
|
polyglot (>= 0.3.1)
|
||||||
tzinfo (0.3.35)
|
tzinfo (0.3.35)
|
||||||
uniform_notifier (1.0.2)
|
uniform_notifier (1.0.2)
|
||||||
vegas (0.1.8)
|
vegas (0.1.11)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
warden (1.0.6)
|
warden (1.0.6)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
whenever (0.7.3)
|
whenever (0.7.3)
|
||||||
activesupport (>= 2.3.4)
|
activesupport (>= 2.3.4)
|
||||||
chronic (~> 0.6.3)
|
chronic (~> 0.6.3)
|
||||||
will_paginate (3.0.2)
|
will_paginate (3.0.4)
|
||||||
|
yard (0.8.3)
|
||||||
yui-compressor (0.9.6)
|
yui-compressor (0.9.6)
|
||||||
POpen4 (>= 0.1.4)
|
POpen4 (>= 0.1.4)
|
||||||
|
|
||||||
|
@ -257,7 +280,9 @@ DEPENDENCIES
|
||||||
em-synchrony!
|
em-synchrony!
|
||||||
eventmachine!
|
eventmachine!
|
||||||
factory_girl_rails (~> 1.0)
|
factory_girl_rails (~> 1.0)
|
||||||
fog (~> 1.1.2)
|
flex!
|
||||||
|
fog (~> 1.8.0)
|
||||||
|
globalize3
|
||||||
haml (~> 3.0.18)
|
haml (~> 3.0.18)
|
||||||
hoptoad_notifier
|
hoptoad_notifier
|
||||||
http_accept_language!
|
http_accept_language!
|
||||||
|
@ -272,6 +297,7 @@ DEPENDENCIES
|
||||||
nokogiri (~> 1.5.2)
|
nokogiri (~> 1.5.2)
|
||||||
openneo-auth-signatory (~> 0.1.0)
|
openneo-auth-signatory (~> 0.1.0)
|
||||||
parallel (~> 0.5.17)
|
parallel (~> 0.5.17)
|
||||||
|
patron (~> 0.4.18)
|
||||||
rack-fiber_pool
|
rack-fiber_pool
|
||||||
rails (= 3.0.19)
|
rails (= 3.0.19)
|
||||||
rdiscount (~> 1.6.5)
|
rdiscount (~> 1.6.5)
|
||||||
|
|
|
@ -57,7 +57,7 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def valid_locale?(locale)
|
def valid_locale?(locale)
|
||||||
locale && I18n.available_locales.include?(locale.to_sym)
|
locale && I18n.usable_locales.include?(locale.to_sym)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -188,15 +188,17 @@ class ClosetHangersController < ApplicationController
|
||||||
|
|
||||||
def find_closet_lists_by_owned(closet_lists)
|
def find_closet_lists_by_owned(closet_lists)
|
||||||
return {} if closet_lists == []
|
return {} if closet_lists == []
|
||||||
closet_lists.alphabetical.includes(:hangers => :item).
|
closet_lists.alphabetical.includes(:hangers => {:item => :translations}).
|
||||||
group_by(&:hangers_owned)
|
group_by(&:hangers_owned)
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_unlisted_closet_hangers_by_owned(visible_groups)
|
def find_unlisted_closet_hangers_by_owned(visible_groups)
|
||||||
unless visible_groups.empty?
|
unless visible_groups.empty?
|
||||||
@user.closet_hangers.unlisted.
|
@user.closet_hangers.unlisted.
|
||||||
owned_before_wanted.alphabetical_by_item_name.includes(:item).
|
owned_before_wanted.alphabetical_by_item_name.
|
||||||
where(:owned => [visible_groups]).group_by(&:owned)
|
includes(:item => :translations).
|
||||||
|
where(:owned => [visible_groups]).
|
||||||
|
group_by(&:owned)
|
||||||
else
|
else
|
||||||
{}
|
{}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
class ItemZoneSetsController < ApplicationController
|
class ItemZoneSetsController < ApplicationController
|
||||||
caches_page :index
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render :json => Zone::ItemZoneSets.keys.sort.as_json
|
render :json => Zone.all_plain_labels
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
class ItemsController < ApplicationController
|
class ItemsController < ApplicationController
|
||||||
before_filter :set_query
|
before_filter :set_query
|
||||||
|
rescue_from Item::Search::Error, :with => :search_error
|
||||||
|
|
||||||
def index
|
def index
|
||||||
if params.has_key?(:q)
|
if params.has_key?(:q)
|
||||||
|
@ -8,25 +9,21 @@ class ItemsController < ApplicationController
|
||||||
per_page = params[:per_page].to_i
|
per_page = params[:per_page].to_i
|
||||||
per_page = 50 if per_page && per_page > 50
|
per_page = 50 if per_page && per_page > 50
|
||||||
else
|
else
|
||||||
per_page = nil
|
per_page = 30
|
||||||
end
|
end
|
||||||
@items = Item.search(@query, current_user).alphabetize.paginate :page => params[:page], :per_page => per_page
|
# Note that we sort by name by hand, since we might have to use
|
||||||
|
# fallbacks after the fact
|
||||||
|
@items = Item::Search::Query.from_text(@query, current_user).
|
||||||
|
paginate(:page => params[:page], :per_page => per_page)
|
||||||
assign_closeted!
|
assign_closeted!
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { render }
|
format.html { render }
|
||||||
format.json { render :json => {:items => @items, :total_pages => @items.total_pages} }
|
format.json { render :json => {:items => @items, :total_pages => @items.total_pages} }
|
||||||
format.js { render :json => {:items => @items, :total_pages => @items.total_pages}, :callback => params[:callback] }
|
format.js { render :json => {:items => @items, :total_pages => @items.total_pages}, :callback => params[:callback] }
|
||||||
end
|
end
|
||||||
rescue Item::SearchError
|
|
||||||
@items = []
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { flash.now[:alert] = $!.message }
|
|
||||||
format.json { render :json => {:error => $!.message} }
|
|
||||||
format.js { render :json => {:error => $!.message}, :callback => params[:callback] }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
elsif params.has_key?(:ids) && params[:ids].is_a?(Array)
|
elsif params.has_key?(:ids) && params[:ids].is_a?(Array)
|
||||||
@items = Item.find(params[:ids])
|
@items = Item.includes(:translations).find(params[:ids])
|
||||||
assign_closeted!
|
assign_closeted!
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json { render :json => @items }
|
format.json { render :json => @items }
|
||||||
|
@ -35,7 +32,7 @@ class ItemsController < ApplicationController
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html {
|
format.html {
|
||||||
unless localized_fragment_exist?('items#index newest_items')
|
unless localized_fragment_exist?('items#index newest_items')
|
||||||
@newest_items = Item.newest.limit(18)
|
@newest_items = Item.newest.includes(:translations).limit(18)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
format.js { render :json => {:error => '$q required'}}
|
format.js { render :json => {:error => '$q required'}}
|
||||||
|
@ -48,6 +45,15 @@ class ItemsController < ApplicationController
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
|
unless localized_fragment_exist?("items/#{@item.id} info")
|
||||||
|
@occupied_zones = @item.occupied_zones(
|
||||||
|
:scope => Zone.includes_translations.alphabetical
|
||||||
|
)
|
||||||
|
@restricted_zones = @item.restricted_zones(
|
||||||
|
:scope => Zone.includes_translations.alphabetical
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
unless localized_fragment_exist?("items/#{@item.id} contributors")
|
unless localized_fragment_exist?("items/#{@item.id} contributors")
|
||||||
@contributors_with_counts = @item.contributors_with_counts
|
@contributors_with_counts = @item.contributors_with_counts
|
||||||
end
|
end
|
||||||
|
@ -96,7 +102,8 @@ class ItemsController < ApplicationController
|
||||||
raise ActiveRecord::RecordNotFound, 'Pet type not found'
|
raise ActiveRecord::RecordNotFound, 'Pet type not found'
|
||||||
end
|
end
|
||||||
|
|
||||||
@items = @pet_type.needed_items.alphabetize
|
@items = @pet_type.needed_items.includes(:translations).
|
||||||
|
alphabetize_by_translations
|
||||||
assign_closeted!
|
assign_closeted!
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
@ -110,6 +117,16 @@ class ItemsController < ApplicationController
|
||||||
def assign_closeted!
|
def assign_closeted!
|
||||||
current_user.assign_closeted_to_items!(@items) if user_signed_in?
|
current_user.assign_closeted_to_items!(@items) if user_signed_in?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def search_error(e)
|
||||||
|
@items = []
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { flash.now[:alert] = e.message; render }
|
||||||
|
format.json { render :json => {:error => e.message} }
|
||||||
|
format.js { render :json => {:error => e.message},
|
||||||
|
:callback => params[:callback] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def set_query
|
def set_query
|
||||||
@query = params[:q]
|
@query = params[:q]
|
||||||
|
|
|
@ -42,12 +42,13 @@ class OutfitsController < ApplicationController
|
||||||
|
|
||||||
def new
|
def new
|
||||||
unless localized_fragment_exist?(:action_suffix => 'start_from_scratch_form_content')
|
unless localized_fragment_exist?(:action_suffix => 'start_from_scratch_form_content')
|
||||||
@colors = Color.all_ordered_by_name
|
@colors = Color.alphabetical
|
||||||
@species = Species.all_ordered_by_name
|
@species = Species.alphabetical
|
||||||
end
|
end
|
||||||
|
|
||||||
unless localized_fragment_exist?('outfits#new newest_items')
|
unless localized_fragment_exist?('outfits#new newest_items')
|
||||||
@newest_items = Item.newest.select([:id, :name, :thumbnail_url]).limit(9)
|
@newest_items = Item.newest.select([:id, :name, :thumbnail_url]).
|
||||||
|
includes(:translations).limit(9)
|
||||||
end
|
end
|
||||||
|
|
||||||
unless localized_fragment_exist?('outfits#new latest_contribution')
|
unless localized_fragment_exist?('outfits#new latest_contribution')
|
||||||
|
@ -65,8 +66,13 @@ class OutfitsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def start
|
def start
|
||||||
|
# Start URLs are always in English, so let's make sure we search in
|
||||||
|
# English.
|
||||||
|
I18n.locale = I18n.default_locale
|
||||||
|
|
||||||
@species = Species.find_by_name params[:species_name]
|
@species = Species.find_by_name params[:species_name]
|
||||||
@color = Color.find_by_name params[:color_name]
|
@color = Color.find_by_name params[:color_name]
|
||||||
|
|
||||||
if @species && @color
|
if @species && @color
|
||||||
redirect_to wardrobe_path(:species => @species.id, :color => @color.id)
|
redirect_to wardrobe_path(:species => @species.id, :color => @color.id)
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
class PetAttributesController < ApplicationController
|
class PetAttributesController < ApplicationController
|
||||||
caches_page :index
|
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render :json => {
|
render :json => {
|
||||||
:color => Color.all_ordered_by_name,
|
:color => Color.alphabetical,
|
||||||
:species => Species.all_ordered_by_name
|
:species => Species.alphabetical
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,13 +10,16 @@ class PetsController < ApplicationController
|
||||||
redirect_to roulette_path
|
redirect_to roulette_path
|
||||||
else
|
else
|
||||||
raise Pet::PetNotFound unless params[:name]
|
raise Pet::PetNotFound unless params[:name]
|
||||||
@pet = Pet.load(params[:name])
|
@pet = Pet.load(params[:name], :item_scope => Item.includes(:translations))
|
||||||
if user_signed_in?
|
if user_signed_in?
|
||||||
points = current_user.contribute! @pet
|
points = current_user.contribute! @pet
|
||||||
else
|
else
|
||||||
@pet.save
|
@pet.save
|
||||||
points = true
|
points = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@pet.translate_items
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
path = destination + @pet.wardrobe_query
|
path = destination + @pet.wardrobe_query
|
||||||
|
|
|
@ -3,7 +3,7 @@ class SitemapController < ApplicationController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.xml { @items = Item.sitemap }
|
format.xml { @items = Item.includes(:translations).sitemap }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@ class SwfAssetsController < ApplicationController
|
||||||
def index
|
def index
|
||||||
if params[:item_id]
|
if params[:item_id]
|
||||||
item = Item.find(params[:item_id])
|
item = Item.find(params[:item_id])
|
||||||
@swf_assets = item.swf_assets
|
@swf_assets = item.swf_assets.includes_depth
|
||||||
if params[:body_id]
|
if params[:body_id]
|
||||||
@swf_assets = @swf_assets.fitting_body_id(params[:body_id])
|
@swf_assets = @swf_assets.fitting_body_id(params[:body_id])
|
||||||
else
|
else
|
||||||
|
@ -15,33 +15,32 @@ class SwfAssetsController < ApplicationController
|
||||||
end
|
end
|
||||||
elsif params[:pet_type_id] && params[:item_ids]
|
elsif params[:pet_type_id] && params[:item_ids]
|
||||||
pet_type = PetType.find(params[:pet_type_id], :select => [:body_id, :species_id])
|
pet_type = PetType.find(params[:pet_type_id], :select => [:body_id, :species_id])
|
||||||
items = Item.find(params[:item_ids], :select => [:id, :species_support_ids])
|
|
||||||
compatible_items = items.select { |i| i.support_species?(pet_type.species) }
|
|
||||||
compatible_item_ids = compatible_items.map(&:id)
|
|
||||||
|
|
||||||
@swf_assets = SwfAsset.object_assets.
|
@swf_assets = SwfAsset.object_assets.includes_depth.
|
||||||
fitting_body_id(pet_type.body_id).
|
fitting_body_id(pet_type.body_id).
|
||||||
for_item_ids(compatible_item_ids).
|
for_item_ids(params[:item_ids]).
|
||||||
with_parent_ids
|
with_parent_ids
|
||||||
json = @swf_assets.map { |a| a.as_json(:parent_id => a.parent_id.to_i, :for => 'wardrobe') }
|
json = @swf_assets.map { |a| a.as_json(:parent_id => a.parent_id.to_i, :for => 'wardrobe') }
|
||||||
elsif params[:pet_state_id]
|
elsif params[:pet_state_id]
|
||||||
@swf_assets = PetState.find(params[:pet_state_id]).swf_assets.all
|
@swf_assets = PetState.find(params[:pet_state_id]).swf_assets.
|
||||||
|
includes_depth.all
|
||||||
pet_state_id = params[:pet_state_id].to_i
|
pet_state_id = params[:pet_state_id].to_i
|
||||||
json = @swf_assets.map { |a| a.as_json(:parent_id => pet_state_id, :for => 'wardrobe') }
|
json = @swf_assets.map { |a| a.as_json(:parent_id => pet_state_id, :for => 'wardrobe') }
|
||||||
elsif params[:pet_type_id]
|
elsif params[:pet_type_id]
|
||||||
@swf_assets = PetType.find(params[:pet_type_id]).pet_states.emotion_order.first.swf_assets
|
@swf_assets = PetType.find(params[:pet_type_id]).pet_states.emotion_order
|
||||||
|
.first.swf_assets.includes_depth
|
||||||
elsif params[:ids]
|
elsif params[:ids]
|
||||||
@swf_assets = []
|
@swf_assets = []
|
||||||
if params[:ids][:biology]
|
if params[:ids][:biology]
|
||||||
@swf_assets += SwfAsset.biology_assets.where(:remote_id => params[:ids][:biology]).all
|
@swf_assets += SwfAsset.includes_depth.biology_assets.where(:remote_id => params[:ids][:biology]).all
|
||||||
end
|
end
|
||||||
if params[:ids][:object]
|
if params[:ids][:object]
|
||||||
@swf_assets += SwfAsset.object_assets.where(:remote_id => params[:ids][:object]).all
|
@swf_assets += SwfAsset.includes_depth.object_assets.where(:remote_id => params[:ids][:object]).all
|
||||||
end
|
end
|
||||||
elsif params[:body_id] && params[:item_ids]
|
elsif params[:body_id] && params[:item_ids]
|
||||||
# DEPRECATED in favor of pet_type_id and item_ids
|
# DEPRECATED in favor of pet_type_id and item_ids
|
||||||
swf_assets = SwfAsset.arel_table
|
swf_assets = SwfAsset.arel_table
|
||||||
@swf_assets = SwfAsset.object_assets.
|
@swf_assets = SwfAsset.includes_depth.object_assets.
|
||||||
select('swf_assets.*, parents_swf_assets.parent_id').
|
select('swf_assets.*, parents_swf_assets.parent_id').
|
||||||
fitting_body_id(params[:body_id]).
|
fitting_body_id(params[:body_id]).
|
||||||
for_item_ids(params[:item_ids])
|
for_item_ids(params[:item_ids])
|
||||||
|
|
18
app/flex/flex_search.rb
Normal file
18
app/flex/flex_search.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# inspect the methods loaded in this module and their usage
|
||||||
|
# in the rails console by just typing:
|
||||||
|
# >> puts FlexSearch.flex.info
|
||||||
|
# you can eventually restrict the info to a single method by pasing its name:
|
||||||
|
# >> puts FlexSearch.flex.info :search
|
||||||
|
# see the detailed doc for this feature at https://github.com/ddnexus/flex/wiki/Selfdoc
|
||||||
|
|
||||||
|
module FlexSearch
|
||||||
|
|
||||||
|
extend self
|
||||||
|
|
||||||
|
include Flex::Loader
|
||||||
|
flex.load_search_source
|
||||||
|
|
||||||
|
# you may need to add more method here, usually wrapper methods
|
||||||
|
# that use one of the autogenerated methods from the loaded templates
|
||||||
|
|
||||||
|
end
|
83
app/flex/flex_search.yml
Normal file
83
app/flex/flex_search.yml
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
# Add here your search queries
|
||||||
|
# see the detailed Source documentation at https://github.com/ddnexus/flex/wiki/Sources
|
||||||
|
|
||||||
|
|
||||||
|
# ANCHORS litheral key: it will not be used as template
|
||||||
|
# you can store here fragments of queries to reuse in the templates below
|
||||||
|
ANCHORS:
|
||||||
|
- &name_partial
|
||||||
|
multi_match:
|
||||||
|
query: <<name>>
|
||||||
|
fields: <<fields>>
|
||||||
|
type: phrase
|
||||||
|
- &species_support_id_partial
|
||||||
|
term:
|
||||||
|
species_support_id: <<species_support_id>>
|
||||||
|
- &occupied_zone_id_partial
|
||||||
|
terms:
|
||||||
|
occupied_zone_id: <<occupied_zone_id>>
|
||||||
|
- &restricted_zone_id_partial
|
||||||
|
terms:
|
||||||
|
restricted_zone_id: <<restricted_zone_id>>
|
||||||
|
- &user_closet_hangers_ownership_partial
|
||||||
|
has_child:
|
||||||
|
type: closet_hanger
|
||||||
|
query:
|
||||||
|
bool:
|
||||||
|
must:
|
||||||
|
- term:
|
||||||
|
user_id: <<user_id>>
|
||||||
|
- term:
|
||||||
|
owned: <<user_closet_hanger_ownership>>
|
||||||
|
|
||||||
|
_names:
|
||||||
|
*name_partial
|
||||||
|
|
||||||
|
_negative_names:
|
||||||
|
*name_partial
|
||||||
|
|
||||||
|
_species_support_ids:
|
||||||
|
*species_support_id_partial
|
||||||
|
|
||||||
|
_negative_species_support_ids:
|
||||||
|
*species_support_id_partial
|
||||||
|
|
||||||
|
_occupied_zone_ids:
|
||||||
|
*occupied_zone_id_partial
|
||||||
|
|
||||||
|
_negative_occupied_zone_ids:
|
||||||
|
*occupied_zone_id_partial
|
||||||
|
|
||||||
|
_restricted_zone_ids:
|
||||||
|
*restricted_zone_id_partial
|
||||||
|
|
||||||
|
_negative_restricted_zone_ids:
|
||||||
|
*restricted_zone_id_partial
|
||||||
|
|
||||||
|
_user_closet_hanger_ownerships:
|
||||||
|
*user_closet_hangers_ownership_partial
|
||||||
|
|
||||||
|
_negative_user_closet_hanger_ownerships:
|
||||||
|
*user_closet_hangers_ownership_partial
|
||||||
|
|
||||||
|
item_search:
|
||||||
|
- query:
|
||||||
|
bool:
|
||||||
|
must:
|
||||||
|
- term:
|
||||||
|
is_nc: <<is_nc= ~>>
|
||||||
|
- term:
|
||||||
|
is_pb: <<is_pb= ~>>
|
||||||
|
- <<_names= ~>>
|
||||||
|
- <<_species_support_ids= ~>>
|
||||||
|
- <<_occupied_zone_ids= ~>>
|
||||||
|
- <<_restricted_zone_ids= ~>>
|
||||||
|
- <<_user_closet_hanger_ownerships= ~>>
|
||||||
|
must_not:
|
||||||
|
- <<_negative_names= ~>>
|
||||||
|
- <<_negative_species_support_ids= ~>>
|
||||||
|
- <<_negative_occupied_zone_ids= ~>>
|
||||||
|
- <<_negative_restricted_zone_ids= ~>>
|
||||||
|
- <<_negative_user_closet_hanger_ownerships= ~>>
|
||||||
|
sort:
|
||||||
|
- name.<<locale>>.untouched
|
36
app/flex/flex_search_extender.rb
Normal file
36
app/flex/flex_search_extender.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# see the detailed Extenders documentation at https://github.com/ddnexus/flex/wiki/Extenders
|
||||||
|
|
||||||
|
module FlexSearchExtender
|
||||||
|
|
||||||
|
# set this method to restrict this extender to certain types of results
|
||||||
|
# see the other Flex extenders for reference (https://github.com/ddnexus/flex/tree/master/lib/flex/result)
|
||||||
|
def self.should_extend?(response)
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def scoped_loaded_collection(options)
|
||||||
|
options[:scopes] ||= {}
|
||||||
|
@loaded_collection ||= begin
|
||||||
|
records = []
|
||||||
|
# returns a structure like {Comment=>[{"_id"=>"123", ...}, {...}], BlogPost=>[...]}
|
||||||
|
h = Flex::Utils.group_array_by(collection) do |d|
|
||||||
|
d.mapped_class(should_raise=true)
|
||||||
|
end
|
||||||
|
h.each do |klass, docs|
|
||||||
|
scope = options[:scopes][klass.name] || klass.scoped
|
||||||
|
records |= scope.find(docs.map(&:_id))
|
||||||
|
end
|
||||||
|
class_ids = collection.map { |d| [d.mapped_class.to_s, d._id] }
|
||||||
|
# Reorder records to preserve order from search results
|
||||||
|
records = class_ids.map do |class_str, id|
|
||||||
|
records.detect do |record|
|
||||||
|
record.class.to_s == class_str && record.id.to_s == id.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
records.extend Flex::Result::Collection
|
||||||
|
records.setup(self['hits']['total'], variables)
|
||||||
|
records
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -43,7 +43,10 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def canonical_path(resource)
|
def canonical_path(resource)
|
||||||
|
original_locale = I18n.locale
|
||||||
|
I18n.locale = I18n.default_locale
|
||||||
content_for :meta, tag(:link, :rel => 'canonical', :href => url_for(resource))
|
content_for :meta, tag(:link, :rel => 'canonical', :href => url_for(resource))
|
||||||
|
I18n.locale = original_locale
|
||||||
end
|
end
|
||||||
|
|
||||||
def contact_email
|
def contact_email
|
||||||
|
@ -100,9 +103,18 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def locale_options
|
def locale_options
|
||||||
I18n.available_locales.map do |available_locale|
|
current_locale_is_public = false
|
||||||
|
options = I18n.public_locales.map do |available_locale|
|
||||||
|
current_locale_is_public = true if I18n.locale == available_locale
|
||||||
[translate('locale_name', :locale => available_locale), available_locale]
|
[translate('locale_name', :locale => available_locale), available_locale]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
unless current_locale_is_public
|
||||||
|
name = translate('locale_name', :locale => I18n.locale) + ' (alpha)'
|
||||||
|
options << [name, I18n.locale]
|
||||||
|
end
|
||||||
|
|
||||||
|
options
|
||||||
end
|
end
|
||||||
|
|
||||||
def localized_cache(key={}, &block)
|
def localized_cache(key={}, &block)
|
||||||
|
|
|
@ -20,7 +20,7 @@ module ItemsHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def standard_species_search_links
|
def standard_species_search_links
|
||||||
build_on_pet_types(Species.all) do |pet_type|
|
build_on_pet_types(Species.alphabetical) do |pet_type|
|
||||||
image = pet_type_image(pet_type, :happy, :zoom)
|
image = pet_type_image(pet_type, :happy, :zoom)
|
||||||
query = "species:#{pet_type.species.name}"
|
query = "species:#{pet_type.species.name}"
|
||||||
link_to(image, items_path(:q => query))
|
link_to(image, items_path(:q => query))
|
||||||
|
@ -73,7 +73,7 @@ module ItemsHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_zones(zones, method=:label)
|
def list_zones(zones, method=:label)
|
||||||
zones.sort { |x,y| x.label <=> y.label }.map(&method).join(', ')
|
zones.map(&method).join(', ')
|
||||||
end
|
end
|
||||||
|
|
||||||
def nc_icon
|
def nc_icon
|
||||||
|
@ -125,7 +125,8 @@ module ItemsHelper
|
||||||
def build_on_pet_types(species, special_color=nil, &block)
|
def build_on_pet_types(species, special_color=nil, &block)
|
||||||
species_ids = species.map(&:id)
|
species_ids = species.map(&:id)
|
||||||
pet_types = special_color ?
|
pet_types = special_color ?
|
||||||
PetType.where(:color_id => special_color.id, :species_id => species_ids).order(:species_id) :
|
PetType.where(:color_id => special_color.id, :species_id => species_ids).
|
||||||
|
order(:species_id).includes_child_translations :
|
||||||
PetType.random_basic_per_species(species.map(&:id))
|
PetType.random_basic_per_species(species.map(&:id))
|
||||||
pet_types.map(&block).join.html_safe
|
pet_types.map(&block).join.html_safe
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class ClosetHanger < ActiveRecord::Base
|
class ClosetHanger < ActiveRecord::Base
|
||||||
|
include Flex::Model
|
||||||
|
|
||||||
belongs_to :item
|
belongs_to :item
|
||||||
belongs_to :list, :class_name => 'ClosetList'
|
belongs_to :list, :class_name => 'ClosetList'
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
|
@ -29,6 +31,17 @@ class ClosetHanger < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
before_validation :merge_quantities, :set_owned_by_list
|
before_validation :merge_quantities, :set_owned_by_list
|
||||||
|
|
||||||
|
flex.parent :item, 'item' => 'closet_hanger'
|
||||||
|
flex.sync self
|
||||||
|
|
||||||
|
def flex_source
|
||||||
|
{
|
||||||
|
:user_id => user_id,
|
||||||
|
:item_id => item_id,
|
||||||
|
:owned => owned?
|
||||||
|
}.to_json
|
||||||
|
end
|
||||||
|
|
||||||
def verb(subject=:someone)
|
def verb(subject=:someone)
|
||||||
self.class.verb(subject, owned?)
|
self.class.verb(subject, owned?)
|
||||||
|
@ -56,23 +69,28 @@ class ClosetHanger < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
hanger = self.where(conditions).first
|
hanger = self.where(conditions).first
|
||||||
unless hanger
|
|
||||||
hanger = self.new
|
|
||||||
hanger.user_id = conditions[:user_id]
|
|
||||||
hanger.item_id = conditions[:item_id]
|
|
||||||
# One of the following will be nil, and that's okay. If owned is nil,
|
|
||||||
# we'll cover for it before validation, as always.
|
|
||||||
hanger.owned = conditions[:owned]
|
|
||||||
hanger.list_id = conditions[:list_id]
|
|
||||||
end
|
|
||||||
|
|
||||||
unless quantity == 0
|
if quantity > 0
|
||||||
Rails.logger.debug("Logging to #{hanger.id} quantity #{quantity}")
|
# If quantity is non-zero, create/update the corresponding hanger.
|
||||||
|
|
||||||
|
unless hanger
|
||||||
|
hanger = self.new
|
||||||
|
hanger.user_id = conditions[:user_id]
|
||||||
|
hanger.item_id = conditions[:item_id]
|
||||||
|
# One of the following will be nil, and that's okay. If owned is nil,
|
||||||
|
# we'll cover for it before validation, as always.
|
||||||
|
hanger.owned = conditions[:owned]
|
||||||
|
hanger.list_id = conditions[:list_id]
|
||||||
|
end
|
||||||
|
|
||||||
hanger.quantity = quantity
|
hanger.quantity = quantity
|
||||||
hanger.save!
|
hanger.save!
|
||||||
else
|
elsif hanger
|
||||||
hanger.destroy if hanger
|
# If quantity is zero and there's a hanger, destroy it.
|
||||||
|
hanger.destroy
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# If quantity is zero and there's no hanger, good. Do nothing.
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
class Color < PetAttribute
|
class Color < ActiveRecord::Base
|
||||||
fetch_objects!
|
translates :name
|
||||||
|
|
||||||
Basic = %w(blue green red yellow).map { |name| find_by_name(name) }
|
scope :alphabetical, lambda { includes(:translations).order(Color::Translation.arel_table[:name]) }
|
||||||
BasicIds = Basic.map(&:id)
|
scope :basic, where(:basic => true)
|
||||||
|
scope :standard, where(:standard => true)
|
||||||
|
scope :nonstandard, where(:standard => false)
|
||||||
|
|
||||||
def self.basic_ids
|
def as_json(options={})
|
||||||
BasicIds
|
{:id => id, :name => human_name}
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.nonstandard_ids
|
def human_name
|
||||||
@nonstandard_ids ||= File.read(Rails.root.join('config', 'nonstandard_colors.txt')).
|
name.split(' ').map { |word| word.capitalize }.join(' ')
|
||||||
chomp.split("\n").map { |name| Color.find_by_name(name).id }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
class Item < ActiveRecord::Base
|
class Item < ActiveRecord::Base
|
||||||
|
include Flex::Model
|
||||||
include PrettyParam
|
include PrettyParam
|
||||||
|
|
||||||
|
set_inheritance_column 'inheritance_type' # PHP Impress used "type" to describe category
|
||||||
|
|
||||||
SwfAssetType = 'object'
|
SwfAssetType = 'object'
|
||||||
|
|
||||||
|
translates :name, :description, :rarity
|
||||||
|
|
||||||
has_many :closet_hangers
|
has_many :closet_hangers
|
||||||
has_one :contribution, :as => :contributed
|
has_one :contribution, :as => :contributed
|
||||||
|
@ -15,18 +20,16 @@ class Item < ActiveRecord::Base
|
||||||
SPECIAL_COLOR_DESCRIPTION_REGEX =
|
SPECIAL_COLOR_DESCRIPTION_REGEX =
|
||||||
/This item is only wearable by Neopets painted ([a-zA-Z]+)\.|WARNING: This [a-zA-Z]+ can be worn by ([a-zA-Z]+) [a-zA-Z]+ ONLY!/
|
/This item is only wearable by Neopets painted ([a-zA-Z]+)\.|WARNING: This [a-zA-Z]+ can be worn by ([a-zA-Z]+) [a-zA-Z]+ ONLY!/
|
||||||
|
|
||||||
SPECIAL_PAINTBRUSH_COLORS_PATH = Rails.root.join('config', 'colors_with_unique_bodies.txt')
|
|
||||||
SPECIAL_PAINTBRUSH_COLORS = File.read(SPECIAL_PAINTBRUSH_COLORS_PATH).split("\n").map { |name| Color.find_by_name(name) }
|
|
||||||
|
|
||||||
set_table_name 'objects' # Neo & PHP Impress call them objects, but the class name is a conflict (duh!)
|
|
||||||
set_inheritance_column 'inheritance_type' # PHP Impress used "type" to describe category
|
|
||||||
|
|
||||||
cattr_reader :per_page
|
cattr_reader :per_page
|
||||||
@@per_page = 30
|
@@per_page = 30
|
||||||
|
|
||||||
scope :alphabetize, order('name ASC')
|
scope :alphabetize, order(arel_table[:name])
|
||||||
|
scope :alphabetize_by_translations, lambda {
|
||||||
|
it = Item::Translation.arel_table
|
||||||
|
order(it[:name])
|
||||||
|
}
|
||||||
|
|
||||||
scope :join_swf_assets, joins(:swf_assets).group('objects.id')
|
scope :join_swf_assets, joins(:swf_assets).group(arel_table[:id])
|
||||||
|
|
||||||
scope :newest, order(arel_table[:created_at].desc) if arel_table[:created_at]
|
scope :newest, order(arel_table[:created_at].desc) if arel_table[:created_at]
|
||||||
|
|
||||||
|
@ -35,9 +38,31 @@ class Item < ActiveRecord::Base
|
||||||
scope :sold_in_mall, where(:sold_in_mall => true)
|
scope :sold_in_mall, where(:sold_in_mall => true)
|
||||||
scope :not_sold_in_mall, where(:sold_in_mall => false)
|
scope :not_sold_in_mall, where(:sold_in_mall => false)
|
||||||
|
|
||||||
scope :sitemap, select([:id, :name]).order(:id).limit(49999)
|
scope :sitemap, select([arel_table[:id], arel_table[:name]]).
|
||||||
|
order(arel_table[:id]).limit(49999)
|
||||||
|
|
||||||
scope :with_closet_hangers, joins(:closet_hangers)
|
scope :with_closet_hangers, joins(:closet_hangers)
|
||||||
|
|
||||||
|
flex.sync self
|
||||||
|
|
||||||
|
def flex_source
|
||||||
|
indexed_attributes = {
|
||||||
|
:is_nc => self.nc?,
|
||||||
|
:is_pb => self.pb?,
|
||||||
|
:species_support_id => self.species_support_ids,
|
||||||
|
:occupied_zone_id => self.occupied_zone_ids,
|
||||||
|
:restricted_zone_id => self.restricted_zone_ids,
|
||||||
|
:name => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
I18n.usable_locales_with_neopets_language_code.each do |locale|
|
||||||
|
I18n.with_locale(locale) do
|
||||||
|
indexed_attributes[:name][locale] = self.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
indexed_attributes.to_json
|
||||||
|
end
|
||||||
|
|
||||||
def closeted?
|
def closeted?
|
||||||
@owned || @wanted
|
@owned || @wanted
|
||||||
|
@ -72,6 +97,10 @@ class Item < ActiveRecord::Base
|
||||||
def nc?
|
def nc?
|
||||||
NCRarities.include?(rarity_index)
|
NCRarities.include?(rarity_index)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def pb?
|
||||||
|
(self.description == PAINTBRUSH_SET_DESCRIPTION)
|
||||||
|
end
|
||||||
|
|
||||||
def owned?
|
def owned?
|
||||||
@owned
|
@owned
|
||||||
|
@ -81,17 +110,27 @@ class Item < ActiveRecord::Base
|
||||||
@wanted
|
@wanted
|
||||||
end
|
end
|
||||||
|
|
||||||
def restricted_zones
|
def restricted_zones(options={})
|
||||||
unless @restricted_zones
|
options[:scope] ||= Zone.scoped
|
||||||
@restricted_zones = []
|
options[:scope].find(restricted_zone_ids)
|
||||||
|
end
|
||||||
|
|
||||||
|
def restricted_zone_ids
|
||||||
|
unless @restricted_zone_ids
|
||||||
|
@restricted_zone_ids = []
|
||||||
zones_restrict.split(//).each_with_index do |switch, id|
|
zones_restrict.split(//).each_with_index do |switch, id|
|
||||||
@restricted_zones << Zone.find(id.to_i + 1) if switch == '1'
|
@restricted_zone_ids << (id.to_i + 1) if switch == '1'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@restricted_zones
|
@restricted_zone_ids
|
||||||
|
end
|
||||||
|
|
||||||
|
def occupied_zone_ids
|
||||||
|
occupied_zones.map(&:id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def occupied_zones
|
def occupied_zones(options={})
|
||||||
|
options[:scope] ||= Zone.scoped
|
||||||
all_body_ids = []
|
all_body_ids = []
|
||||||
zone_body_ids = {}
|
zone_body_ids = {}
|
||||||
selected_assets = swf_assets.select('body_id, zone_id').each do |swf_asset|
|
selected_assets = swf_assets.select('body_id, zone_id').each do |swf_asset|
|
||||||
|
@ -100,12 +139,11 @@ class Item < ActiveRecord::Base
|
||||||
body_ids << swf_asset.body_id unless body_ids.include?(swf_asset.body_id)
|
body_ids << swf_asset.body_id unless body_ids.include?(swf_asset.body_id)
|
||||||
all_body_ids << swf_asset.body_id unless all_body_ids.include?(swf_asset.body_id)
|
all_body_ids << swf_asset.body_id unless all_body_ids.include?(swf_asset.body_id)
|
||||||
end
|
end
|
||||||
zones = []
|
zones = options[:scope].find(zone_body_ids.keys)
|
||||||
|
zones_by_id = zones.inject({}) { |h, z| h[z.id] = z; h }
|
||||||
total_body_ids = all_body_ids.size
|
total_body_ids = all_body_ids.size
|
||||||
zone_body_ids.each do |zone_id, body_ids|
|
zone_body_ids.each do |zone_id, body_ids|
|
||||||
zone = Zone.find(zone_id)
|
zones_by_id[zone_id].sometimes = true if body_ids.size < total_body_ids
|
||||||
zone.sometimes = true if body_ids.size < total_body_ids
|
|
||||||
zones << zone
|
|
||||||
end
|
end
|
||||||
zones
|
zones
|
||||||
end
|
end
|
||||||
|
@ -120,17 +158,21 @@ class Item < ActiveRecord::Base
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def determine_special_color
|
def determine_special_color
|
||||||
if description.include?(PAINTBRUSH_SET_DESCRIPTION)
|
I18n.with_locale(I18n.default_locale) do
|
||||||
downcased_name = name.downcase
|
# Rather than go find the special description in all locales, let's just
|
||||||
SPECIAL_PAINTBRUSH_COLORS.each do |color|
|
# run this logic in English.
|
||||||
return color if downcased_name.include?(color.name)
|
if description.include?(PAINTBRUSH_SET_DESCRIPTION)
|
||||||
|
downcased_name = name.downcase
|
||||||
|
Color.nonstandard.each do |color|
|
||||||
|
return color if downcased_name.include?(color.name)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
match = description.match(SPECIAL_COLOR_DESCRIPTION_REGEX)
|
match = description.match(SPECIAL_COLOR_DESCRIPTION_REGEX)
|
||||||
if match
|
if match
|
||||||
color = match[1] || match[2]
|
color = match[1] || match[2]
|
||||||
return Color.find_by_name(color.downcase)
|
return Color.find_by_name(color.downcase)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
public
|
public
|
||||||
|
@ -146,45 +188,18 @@ class Item < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def supported_species
|
def supported_species
|
||||||
@supported_species ||= species_support_ids.blank? ? Species.all : species_support_ids.sort.map { |id| Species.find(id) }
|
body_ids = swf_assets.select([:body_id]).map(&:body_id)
|
||||||
|
return Species.all if body_ids.include?(0)
|
||||||
|
|
||||||
|
pet_types = PetType.where(:body_id => body_ids).select([:species_id])
|
||||||
|
species_ids = pet_types.map(&:species_id).uniq
|
||||||
|
Species.find(species_ids)
|
||||||
end
|
end
|
||||||
|
|
||||||
def support_species?(species)
|
def support_species?(species)
|
||||||
species_support_ids.blank? || species_support_ids.include?(species.id)
|
species_support_ids.blank? || species_support_ids.include?(species.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.search(query, user=nil)
|
|
||||||
raise SearchError, "Please provide a search query" unless query
|
|
||||||
query = query.strip
|
|
||||||
raise SearchError, "Search queries should be at least 3 characters" if query.length < 3
|
|
||||||
query_conditions = [Condition.new]
|
|
||||||
in_phrase = false
|
|
||||||
query.each_char do |c|
|
|
||||||
if c == ' ' && !in_phrase
|
|
||||||
query_conditions << Condition.new
|
|
||||||
elsif c == '"'
|
|
||||||
in_phrase = !in_phrase
|
|
||||||
elsif c == ':' && !in_phrase
|
|
||||||
query_conditions.last.to_filter!
|
|
||||||
elsif c == '-' && !in_phrase && query_conditions.last.empty?
|
|
||||||
query_conditions.last.negate!
|
|
||||||
else
|
|
||||||
query_conditions.last << c
|
|
||||||
end
|
|
||||||
end
|
|
||||||
limited_filters_used = []
|
|
||||||
query_conditions.inject(self.scoped) do |scope, condition|
|
|
||||||
if condition.filter? && LimitedSearchFilters.include?(condition.filter)
|
|
||||||
if limited_filters_used.include?(condition.filter)
|
|
||||||
raise SearchError, "The #{condition.filter} filter is complex; please only use one per search. Thanks!"
|
|
||||||
else
|
|
||||||
limited_filters_used << condition.filter
|
|
||||||
end
|
|
||||||
end
|
|
||||||
condition.narrow(scope, user)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def as_json(options = {})
|
def as_json(options = {})
|
||||||
{
|
{
|
||||||
:description => description,
|
:description => description,
|
||||||
|
@ -230,6 +245,12 @@ class Item < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def body_specific?
|
||||||
|
# If there are species support IDs (it's not empty), the item is
|
||||||
|
# body-specific. If it's empty, it fits everyone the same.
|
||||||
|
!species_support_ids.empty?
|
||||||
|
end
|
||||||
|
|
||||||
def origin_registry_info=(info)
|
def origin_registry_info=(info)
|
||||||
# bear in mind that numbers from registries are floats
|
# bear in mind that numbers from registries are floats
|
||||||
|
@ -252,6 +273,12 @@ class Item < ActiveRecord::Base
|
||||||
def parent_swf_asset_relationships_to_update=(rels)
|
def parent_swf_asset_relationships_to_update=(rels)
|
||||||
@parent_swf_asset_relationships_to_update = rels
|
@parent_swf_asset_relationships_to_update = rels
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def needed_translations
|
||||||
|
translatable_locales = Set.new(I18n.locales_with_neopets_language_code)
|
||||||
|
translated_locales = Set.new(translations.map(&:locale))
|
||||||
|
translatable_locales - translated_locales
|
||||||
|
end
|
||||||
|
|
||||||
def self.all_by_ids_or_children(ids, swf_assets)
|
def self.all_by_ids_or_children(ids, swf_assets)
|
||||||
swf_asset_ids = []
|
swf_asset_ids = []
|
||||||
|
@ -284,7 +311,7 @@ class Item < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
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,
|
# bear in mind that registries are arrays with many nil elements,
|
||||||
# due to how the parser works
|
# due to how the parser works
|
||||||
|
|
||||||
|
@ -299,7 +326,7 @@ class Item < ActiveRecord::Base
|
||||||
|
|
||||||
# Collect existing relationships
|
# Collect existing relationships
|
||||||
existing_relationships_by_item_id_and_swf_asset_id = {}
|
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|
|
existing_items.each do |item|
|
||||||
items[item.id] = item
|
items[item.id] = item
|
||||||
relationships_by_swf_asset_id = {}
|
relationships_by_swf_asset_id = {}
|
||||||
|
@ -656,214 +683,4 @@ class Item < ActiveRecord::Base
|
||||||
class SpiderHTTPError < SpiderError;end
|
class SpiderHTTPError < SpiderError;end
|
||||||
class SpiderJSONError < SpiderError;end
|
class SpiderJSONError < SpiderError;end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
SearchFilterScopes = []
|
|
||||||
LimitedSearchFilters = []
|
|
||||||
|
|
||||||
def self.search_filter(name, options={}, &block)
|
|
||||||
assume_complement = options.delete(:assume_complement) || true
|
|
||||||
name = name.to_s
|
|
||||||
SearchFilterScopes << name
|
|
||||||
LimitedSearchFilters << name if options[:limit]
|
|
||||||
|
|
||||||
(class << self; self; end).instance_eval do
|
|
||||||
if options[:full]
|
|
||||||
define_method "search_filter_#{name}", &options[:full]
|
|
||||||
else
|
|
||||||
if assume_complement
|
|
||||||
define_method "search_filter_not_#{name}", &Item.search_filter_block(options, false, &block)
|
|
||||||
end
|
|
||||||
define_method "search_filter_#{name}", &Item.search_filter_block(options, true, &block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.single_search_filter(name, options={}, &block)
|
|
||||||
options[:assume_complement] = false
|
|
||||||
search_filter name, options, &block
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.search_filter_block(options, positive, &block)
|
|
||||||
Proc.new { |str, user, scope|
|
|
||||||
condition = block.arity == 1 ? block.call(str) : block.call(str, user)
|
|
||||||
unless positive
|
|
||||||
condition = condition.to_sql if condition.respond_to?(:to_sql)
|
|
||||||
condition = "!(#{condition})"
|
|
||||||
end
|
|
||||||
scope = scope.send(options[:scope]) if options[:scope]
|
|
||||||
scope.where(condition)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
search_filter :name do |name|
|
|
||||||
arel_table[:name].matches("%#{name}%")
|
|
||||||
end
|
|
||||||
|
|
||||||
search_filter :description do |description|
|
|
||||||
arel_table[:description].matches("%#{description}%")
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.adjective_filters
|
|
||||||
@adjective_filters ||= {
|
|
||||||
'nc' => arel_table[:rarity_index].in(NCRarities),
|
|
||||||
'pb' => arel_table[:description].eq(PAINTBRUSH_SET_DESCRIPTION)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
search_filter :is do |adjective|
|
|
||||||
filter = adjective_filters[adjective]
|
|
||||||
unless filter
|
|
||||||
raise SearchError,
|
|
||||||
"We don't know how an item can be \"#{adjective}\". " +
|
|
||||||
"Did you mean is:nc or is:pb?"
|
|
||||||
end
|
|
||||||
filter
|
|
||||||
end
|
|
||||||
|
|
||||||
USER_ADJECTIVES = {
|
|
||||||
'own' => true,
|
|
||||||
'owns' => true,
|
|
||||||
'owned' => true,
|
|
||||||
'want' => false,
|
|
||||||
'wants' => false,
|
|
||||||
'wanted' => false,
|
|
||||||
'all' => nil,
|
|
||||||
'items' => nil
|
|
||||||
}
|
|
||||||
def self.parse_user_adjective(adjective, user)
|
|
||||||
unless USER_ADJECTIVES.has_key?(adjective)
|
|
||||||
raise SearchError, "We don't understand user:#{adjective}. " +
|
|
||||||
"Find items you own with user:owns, items you want with user:wants, or " +
|
|
||||||
"both with user:all"
|
|
||||||
end
|
|
||||||
|
|
||||||
unless user
|
|
||||||
raise SearchError, "It looks like you're not logged in, so you don't own any items."
|
|
||||||
end
|
|
||||||
|
|
||||||
USER_ADJECTIVES[adjective]
|
|
||||||
end
|
|
||||||
|
|
||||||
search_filter :user do |adjective, user|
|
|
||||||
# Though joins may seem more efficient here for the positive case, we need
|
|
||||||
# to be able to handle cases like "user:owns user:wants", which breaks on
|
|
||||||
# the JOIN approach. Just have to look up the IDs in advance.
|
|
||||||
|
|
||||||
owned_value = parse_user_adjective(adjective, user)
|
|
||||||
hangers = ClosetHanger.arel_table
|
|
||||||
items = user.closeted_items
|
|
||||||
items = items.where(ClosetHanger.arel_table[:owned].eq(owned_value)) unless owned_value.nil?
|
|
||||||
item_ids = items.map(&:id)
|
|
||||||
# Though it's best to do arel_table[:id].in(item_ids), it breaks in this
|
|
||||||
# version of Arel, and other conditions will overwrite this one. Since IDs
|
|
||||||
# are guaranteed to be integers, let's just build our own string condition
|
|
||||||
# and be done with it.
|
|
||||||
|
|
||||||
if item_ids.empty?
|
|
||||||
raise SearchError, "You don't #{ClosetHanger.verb :you, owned_value} " +
|
|
||||||
"any items yet. Head to Your Items to add some!"
|
|
||||||
end
|
|
||||||
|
|
||||||
arel_table[:id].in(item_ids)
|
|
||||||
end
|
|
||||||
|
|
||||||
search_filter :only do |species_name|
|
|
||||||
begin
|
|
||||||
id = Species.require_by_name(species_name).id
|
|
||||||
rescue Species::NotFound => e
|
|
||||||
raise SearchError, e.message
|
|
||||||
end
|
|
||||||
arel_table[:species_support_ids].eq(id.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
search_filter :species do |species_name|
|
|
||||||
begin
|
|
||||||
id = Species.require_by_name(species_name).id
|
|
||||||
rescue Species::NotFound => e
|
|
||||||
raise SearchError, e.message
|
|
||||||
end
|
|
||||||
ids = arel_table[:species_support_ids]
|
|
||||||
ids.eq('').or(ids.matches_any([
|
|
||||||
id,
|
|
||||||
"#{id},%",
|
|
||||||
"%,#{id},%",
|
|
||||||
"%,#{id}"
|
|
||||||
]))
|
|
||||||
end
|
|
||||||
|
|
||||||
single_search_filter :type, {:limit => true, :scope => :join_swf_assets} do |zone_set_name|
|
|
||||||
zone_set = Zone.find_set(zone_set_name)
|
|
||||||
raise SearchError, "Type \"#{zone_set_name}\" does not exist" unless zone_set
|
|
||||||
SwfAsset.arel_table[:zone_id].in(zone_set.map(&:id))
|
|
||||||
end
|
|
||||||
|
|
||||||
single_search_filter :not_type, :full => lambda { |zone_set_name, user, scope|
|
|
||||||
zone_set = Zone::ItemZoneSets[zone_set_name]
|
|
||||||
raise SearchError, "Type \"#{zone_set_name}\" does not exist" unless zone_set
|
|
||||||
psa = ParentSwfAssetRelationship.arel_table.alias
|
|
||||||
sa = SwfAsset.arel_table.alias
|
|
||||||
# Join to SWF assets, including the zone condition in the join so that
|
|
||||||
# SWFs that don't match end up being NULL rows. Then we take the max SWF
|
|
||||||
# asset ID, which is NULL if and only if there are no rows that matched
|
|
||||||
# the zone requirement. If that max was NULL, return the object.
|
|
||||||
item_ids = select(arel_table[:id]).joins(
|
|
||||||
"LEFT JOIN #{ParentSwfAssetRelationship.table_name} #{psa.name} ON " +
|
|
||||||
psa[:parent_type].eq(self.name).
|
|
||||||
and(psa[:parent_id].eq(arel_table[:id])).
|
|
||||||
to_sql
|
|
||||||
).
|
|
||||||
joins(
|
|
||||||
"LEFT JOIN #{SwfAsset.table_name} #{sa.name} ON " +
|
|
||||||
sa[:type].eq(SwfAssetType).
|
|
||||||
and(sa[:id].eq(psa[:swf_asset_id])).
|
|
||||||
and(sa[:zone_id].in(zone_set.map(&:id))).
|
|
||||||
to_sql
|
|
||||||
).
|
|
||||||
group("#{table_name}.id").
|
|
||||||
having("MAX(#{sa.name}.id) IS NULL"). # SwfAsset.arel_table[:id].maximum has no #eq
|
|
||||||
map(&:id)
|
|
||||||
scope.where(arel_table[:id].in(item_ids))
|
|
||||||
}
|
|
||||||
|
|
||||||
class Condition < String
|
|
||||||
attr_accessor :filter
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
@positive = true
|
|
||||||
end
|
|
||||||
|
|
||||||
def filter?
|
|
||||||
!@filter.nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_filter!
|
|
||||||
@filter = self.clone
|
|
||||||
self.replace ''
|
|
||||||
end
|
|
||||||
|
|
||||||
def negate!
|
|
||||||
@positive = !@positive
|
|
||||||
end
|
|
||||||
|
|
||||||
def narrow(scope, user)
|
|
||||||
if SearchFilterScopes.include?(filter)
|
|
||||||
polarized_filter = @positive ? filter : "not_#{filter}"
|
|
||||||
Item.send("search_filter_#{polarized_filter}", self, user, scope)
|
|
||||||
else
|
|
||||||
raise SearchError, "Filter #{filter} does not exist"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def filter
|
|
||||||
@filter || 'name'
|
|
||||||
end
|
|
||||||
|
|
||||||
def inspect
|
|
||||||
@filter ? "#{@filter}:#{super}" : super
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class SearchError < ArgumentError;end
|
|
||||||
end
|
end
|
||||||
|
|
8
app/models/item/search.rb
Normal file
8
app/models/item/search.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
class Item
|
||||||
|
module Search
|
||||||
|
def self.error(key, *args)
|
||||||
|
message = I18n.translate("items.search.errors.#{key}", *args)
|
||||||
|
raise Item::Search::Error, message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
7
app/models/item/search/contradiction.rb
Normal file
7
app/models/item/search/contradiction.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class Item
|
||||||
|
module Search
|
||||||
|
class Contradiction < Error
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
7
app/models/item/search/error.rb
Normal file
7
app/models/item/search/error.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class Item
|
||||||
|
module Search
|
||||||
|
class Error < RuntimeError
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
app/models/item/search/field.rb
Normal file
11
app/models/item/search/field.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class Item
|
||||||
|
module Search
|
||||||
|
class Field
|
||||||
|
attr_reader :key
|
||||||
|
|
||||||
|
def initialize(key)
|
||||||
|
@key = key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
app/models/item/search/fields/flag.rb
Normal file
20
app/models/item/search/fields/flag.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
class Item
|
||||||
|
module Search
|
||||||
|
module Fields
|
||||||
|
class Flag < Field
|
||||||
|
def <<(filter)
|
||||||
|
if @value.nil?
|
||||||
|
@value = filter.positive?
|
||||||
|
elsif @value != filter.positive?
|
||||||
|
raise Item::Search::Contradiction,
|
||||||
|
"flag #{key} both positive and negative"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_flex_params
|
||||||
|
{key => @value}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
34
app/models/item/search/fields/set_field.rb
Normal file
34
app/models/item/search/fields/set_field.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
class Item
|
||||||
|
module Search
|
||||||
|
module Fields
|
||||||
|
class SetField < Field
|
||||||
|
def initialize(*args)
|
||||||
|
super(*args)
|
||||||
|
@values = {true => Set.new, false => Set.new}
|
||||||
|
end
|
||||||
|
|
||||||
|
def <<(filter)
|
||||||
|
if @values[!filter.positive?].include?(filter.value)
|
||||||
|
raise Item::Search::Contradiction,
|
||||||
|
"positive #{key} and negative #{key} both contain #{filter.value}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@values[filter.positive?] << filter.value
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_flex_params
|
||||||
|
{
|
||||||
|
:"_#{key}s" => nil_if_empty(@values[true]),
|
||||||
|
:"_negative_#{key}s" => nil_if_empty(@values[false])
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def nil_if_empty(set)
|
||||||
|
set.map { |value| {key => value} } unless set.empty?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
29
app/models/item/search/fields/text_field.rb
Normal file
29
app/models/item/search/fields/text_field.rb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
class Item
|
||||||
|
module Search
|
||||||
|
module Fields
|
||||||
|
class TextField < Field
|
||||||
|
def initialize(*args)
|
||||||
|
super(*args)
|
||||||
|
@values = {true => '', false => ''}
|
||||||
|
end
|
||||||
|
|
||||||
|
def <<(filter)
|
||||||
|
@values[filter.positive?] << (filter.value + ' ')
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_flex_params
|
||||||
|
{
|
||||||
|
key => nil_if_empty(@values[true]),
|
||||||
|
:"negative_#{key}" => nil_if_empty(@values[false])
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def nil_if_empty(str)
|
||||||
|
str unless str.empty?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
17
app/models/item/search/filter.rb
Normal file
17
app/models/item/search/filter.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
class Item
|
||||||
|
module Search
|
||||||
|
class Filter
|
||||||
|
attr_reader :key, :value
|
||||||
|
|
||||||
|
def initialize(key, value, is_positive)
|
||||||
|
@key = key
|
||||||
|
@value = value
|
||||||
|
@is_positive = is_positive
|
||||||
|
end
|
||||||
|
|
||||||
|
def positive?
|
||||||
|
@is_positive
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
197
app/models/item/search/query.rb
Normal file
197
app/models/item/search/query.rb
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
class Item
|
||||||
|
module Search
|
||||||
|
class Query
|
||||||
|
FIELD_CLASSES = {
|
||||||
|
:is_nc => Fields::Flag,
|
||||||
|
:is_pb => Fields::Flag,
|
||||||
|
:species_support_id => Fields::SetField,
|
||||||
|
:occupied_zone_id => Fields::SetField,
|
||||||
|
:restricted_zone_id => Fields::SetField,
|
||||||
|
:name => Fields::SetField,
|
||||||
|
:user_closet_hanger_ownership => Fields::SetField
|
||||||
|
}
|
||||||
|
|
||||||
|
def initialize(filters, user)
|
||||||
|
@filters = filters
|
||||||
|
@user = user
|
||||||
|
end
|
||||||
|
|
||||||
|
def fields
|
||||||
|
initial_fields.tap do |fields|
|
||||||
|
@filters.each { |filter| fields[filter.key] << filter }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_flex_params
|
||||||
|
fields.values.map(&:to_flex_params).inject(&:merge)
|
||||||
|
end
|
||||||
|
|
||||||
|
def paginate(options={})
|
||||||
|
begin
|
||||||
|
flex_params = self.to_flex_params
|
||||||
|
rescue Item::Search::Contradiction
|
||||||
|
# If we have a contradictory query, no need to raise a stink about
|
||||||
|
# it, but no need to actually run a search, either.
|
||||||
|
return []
|
||||||
|
end
|
||||||
|
|
||||||
|
final_flex_params = {
|
||||||
|
:page => (options[:page] || 1),
|
||||||
|
:size => (options[:per_page] || 30),
|
||||||
|
:type => 'item'
|
||||||
|
}.merge(flex_params)
|
||||||
|
|
||||||
|
locales = I18n.fallbacks[I18n.locale] &
|
||||||
|
I18n.locales_with_neopets_language_code
|
||||||
|
final_flex_params[:locale] = locales.first
|
||||||
|
|
||||||
|
# Extend the names/negative_names queries with the corresponding
|
||||||
|
# localalized field names.
|
||||||
|
if final_flex_params[:_names] || final_flex_params[:_negative_names]
|
||||||
|
locale_entries = locales.map do |locale|
|
||||||
|
boost = (locale == I18n.locale) ? 4 : 1
|
||||||
|
"name.#{locale}^#{boost}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# We *could* have set _name_locales once as a partial, but Flex won't
|
||||||
|
# let us call partials from inside other partials. Whatever. Assign
|
||||||
|
# it to each name entry instead. I also feel bad doing this
|
||||||
|
# afterwards, since it's kinda the field's job to return proper flex
|
||||||
|
# params, but that's a refactor for another day.
|
||||||
|
[:_names, :_negative_names].each do |key|
|
||||||
|
if final_flex_params[key]
|
||||||
|
final_flex_params[key].each do |name_query|
|
||||||
|
name_query[:fields] = locale_entries
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Okay, yeah, looks like this really does deserve a refactor, like
|
||||||
|
# _names and _negative_names do. (Or Flex could just make all variables
|
||||||
|
# accessible from partials... hint, hint)
|
||||||
|
[:_user_closet_hanger_ownerships, :_negative_user_closet_hanger_ownerships].each do |key|
|
||||||
|
if final_flex_params[key]
|
||||||
|
Item::Search.error 'not_logged_in' unless @user
|
||||||
|
|
||||||
|
final_flex_params[key].each do |entry|
|
||||||
|
entry[:user_id] = @user.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
result = FlexSearch.item_search(final_flex_params)
|
||||||
|
result.scoped_loaded_collection(
|
||||||
|
:scopes => {'Item' => Item.includes(:translations)}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Load the text query labels from I18n, so that when we see, say,
|
||||||
|
# the filter "species:acara", we know it means species_support_id.
|
||||||
|
TEXT_KEYS_BY_LABEL = {}
|
||||||
|
OWNERSHIP_KEYWORDS = {}
|
||||||
|
I18n.available_locales.each do |locale|
|
||||||
|
TEXT_KEYS_BY_LABEL[locale] = {}
|
||||||
|
OWNERSHIP_KEYWORDS[locale] = {}
|
||||||
|
FIELD_CLASSES.keys.each do |key|
|
||||||
|
# A locale can specify multiple labels for a key by separating by
|
||||||
|
# commas: "occupies,zone,type"
|
||||||
|
labels = I18n.translate("items.search.labels.#{key}",
|
||||||
|
:locale => locale).split(',')
|
||||||
|
labels.each { |label| TEXT_KEYS_BY_LABEL[locale][label] = key }
|
||||||
|
|
||||||
|
{:owns => true, :wants => false}.each do |key, value|
|
||||||
|
translated_key = I18n.translate("items.search.labels.user_#{key}",
|
||||||
|
:locale => locale)
|
||||||
|
OWNERSHIP_KEYWORDS[locale][translated_key] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
TEXT_QUERY_RESOURCE_FINDERS = {
|
||||||
|
:species => lambda { |name|
|
||||||
|
species = Species.find_by_name(name)
|
||||||
|
unless species
|
||||||
|
Item::Search.error 'not_found.species', :species_name => name
|
||||||
|
end
|
||||||
|
species.id
|
||||||
|
},
|
||||||
|
:zone => lambda { |label|
|
||||||
|
zone_set = Zone.with_plain_label(label)
|
||||||
|
unless zone_set
|
||||||
|
Item::Search.error 'not_found.zone', :zone_name => name
|
||||||
|
end
|
||||||
|
zone_set.map(&:id)
|
||||||
|
},
|
||||||
|
:ownership => lambda { |keyword|
|
||||||
|
OWNERSHIP_KEYWORDS[I18n.locale][keyword].tap do |value|
|
||||||
|
if value.nil?
|
||||||
|
Item::Search.error 'not_found.ownership', :keyword => keyword
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEXT_QUERY_RESOURCE_TYPES_BY_KEY = {
|
||||||
|
:species_support_id => :species,
|
||||||
|
:occupied_zone_id => :zone,
|
||||||
|
:restricted_zone_id => :zone,
|
||||||
|
:user_closet_hanger_ownership => :ownership
|
||||||
|
}
|
||||||
|
|
||||||
|
TEXT_FILTER_EXPR = /([+-]?)(?:([a-z]+):)?(?:"([^"]+)"|(\S+))/
|
||||||
|
def self.from_text(text, user=nil)
|
||||||
|
filters = []
|
||||||
|
|
||||||
|
is_keyword = I18n.translate('items.search.flag_keywords.is')
|
||||||
|
text.scan(TEXT_FILTER_EXPR) do |sign, label, quoted_value, unquoted_value|
|
||||||
|
label ||= 'name'
|
||||||
|
raw_value = quoted_value || unquoted_value
|
||||||
|
is_positive = (sign != '-')
|
||||||
|
|
||||||
|
if label == is_keyword
|
||||||
|
# is-filters are weird. "-is:nc" is transposed to something more
|
||||||
|
# like "-nc:<nil>", then it's translated into a negative "is_nc"
|
||||||
|
# flag. Fun fact: "nc:foobar" and "-nc:foobar" also work. A bonus,
|
||||||
|
# I guess. There's probably a good way to refactor this to avoid
|
||||||
|
# the unintended bonus syntax, but this is a darn good cheap
|
||||||
|
# technique for the time being.
|
||||||
|
label = raw_value
|
||||||
|
raw_value = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
key = TEXT_KEYS_BY_LABEL[I18n.locale][label]
|
||||||
|
if key.nil?
|
||||||
|
message = I18n.translate('items.search.errors.not_found.label',
|
||||||
|
:label => label)
|
||||||
|
raise Item::Search::Error, message
|
||||||
|
end
|
||||||
|
|
||||||
|
if TEXT_QUERY_RESOURCE_TYPES_BY_KEY.has_key?(key)
|
||||||
|
resource_type = TEXT_QUERY_RESOURCE_TYPES_BY_KEY[key]
|
||||||
|
finder = TEXT_QUERY_RESOURCE_FINDERS[resource_type]
|
||||||
|
value = finder.call(raw_value)
|
||||||
|
else
|
||||||
|
value = raw_value
|
||||||
|
end
|
||||||
|
|
||||||
|
filters << Filter.new(key, value, is_positive)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.new(filters, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# The fields start out empty, then have the filters inserted into 'em,
|
||||||
|
# so that the fields can validate and aggregate their requirements.
|
||||||
|
def initial_fields
|
||||||
|
{}.tap do |fields|
|
||||||
|
FIELD_CLASSES.map do |key, klass|
|
||||||
|
fields[key] = klass.new(key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -84,7 +84,7 @@ class Outfit < ActiveRecord::Base
|
||||||
# ordered from bottom to top. Careful: this method is memoized, so if the
|
# ordered from bottom to top. Careful: this method is memoized, so if the
|
||||||
# image layers change after its first call we'll get bad results.
|
# image layers change after its first call we'll get bad results.
|
||||||
def image_layers
|
def image_layers
|
||||||
@image_layers ||= visible_assets_with_images.sort { |a, b| a.zone.depth <=> b.zone.depth }
|
@image_layers ||= visible_assets_with_images.sort { |a, b| a.depth <=> b.depth }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates and writes the thumbnail images for this outfit iff the new image
|
# Creates and writes the thumbnail images for this outfit iff the new image
|
||||||
|
@ -177,9 +177,10 @@ class Outfit < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def visible_assets
|
def visible_assets
|
||||||
biology_assets = pet_state.swf_assets
|
biology_assets = pet_state.swf_assets.includes(:zone)
|
||||||
object_assets = SwfAsset.object_assets.
|
object_assets = SwfAsset.object_assets.
|
||||||
fitting_body_id(pet_state.pet_type.body_id).for_item_ids(worn_item_ids)
|
fitting_body_id(pet_state.pet_type.body_id).for_item_ids(worn_item_ids).
|
||||||
|
includes(:zone)
|
||||||
|
|
||||||
# Now for fun with bitmasks! Rather than building a bunch of integer arrays
|
# Now for fun with bitmasks! Rather than building a bunch of integer arrays
|
||||||
# here, we instead go low-level and use bit-level operations. Build the
|
# here, we instead go low-level and use bit-level operations. Build the
|
||||||
|
|
|
@ -2,8 +2,8 @@ require 'rocketamf/remote_gateway'
|
||||||
|
|
||||||
class Pet < ActiveRecord::Base
|
class Pet < ActiveRecord::Base
|
||||||
GATEWAY_URL = 'http://www.neopets.com/amfphp/gateway.php'
|
GATEWAY_URL = 'http://www.neopets.com/amfphp/gateway.php'
|
||||||
AMF_SERVICE_NAME = 'CustomPetService'
|
PET_VIEWER = RocketAMF::RemoteGateway.new(GATEWAY_URL).
|
||||||
PET_VIEWER_METHOD = 'getViewerData'
|
service('CustomPetService').action('getViewerData')
|
||||||
PET_NOT_FOUND_REMOTE_ERROR = 'PHP: Unable to retrieve records from the database.'
|
PET_NOT_FOUND_REMOTE_ERROR = 'PHP: Unable to retrieve records from the database.'
|
||||||
WARDROBE_PATH = '/wardrobe'
|
WARDROBE_PATH = '/wardrobe'
|
||||||
|
|
||||||
|
@ -16,11 +16,22 @@ class Pet < ActiveRecord::Base
|
||||||
joins(:pet_type).where(PetType.arel_table[:id].in(color_ids))
|
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'
|
require 'ostruct'
|
||||||
begin
|
begin
|
||||||
envelope = Pet.amf_service.request(PET_VIEWER_METHOD, name, nil).
|
neopets_language_code = I18n.neopets_language_code_for(options[:locale])
|
||||||
fetch(:timeout => 2)
|
envelope = PET_VIEWER.request([name, 0]).post(
|
||||||
|
:timeout => 2,
|
||||||
|
:headers => {
|
||||||
|
'Cookie' => "lang=#{neopets_language_code}"
|
||||||
|
}
|
||||||
|
)
|
||||||
rescue RocketAMF::RemoteGateway::AMFError => e
|
rescue RocketAMF::RemoteGateway::AMFError => e
|
||||||
if e.message == PET_NOT_FOUND_REMOTE_ERROR
|
if e.message == PET_NOT_FOUND_REMOTE_ERROR
|
||||||
raise PetNotFound, "Pet #{name.inspect} does not exist"
|
raise PetNotFound, "Pet #{name.inspect} does not exist"
|
||||||
|
@ -31,18 +42,27 @@ class Pet < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
contents = OpenStruct.new(envelope.messages[0].data.body)
|
contents = OpenStruct.new(envelope.messages[0].data.body)
|
||||||
pet_data = OpenStruct.new(contents.custom_pet)
|
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,
|
# in case this is running in a thread, explicitly grab an ActiveRecord
|
||||||
pet_data.color_id.to_i
|
# connection, to avoid connection conflicts
|
||||||
)
|
Pet.connection_pool.with_connection do
|
||||||
self.pet_type.body_id = pet_data.body_id
|
self.pet_type = PetType.find_or_initialize_by_species_id_and_color_id(
|
||||||
self.pet_type.origin_pet = self
|
pet_data.species_id.to_i,
|
||||||
biology = pet_data.biology_by_zone
|
pet_data.color_id.to_i
|
||||||
biology[0] = nil # remove effects if present
|
)
|
||||||
@pet_state = self.pet_type.add_pet_state_from_biology! biology
|
self.pet_type.body_id = pet_data.body_id
|
||||||
@pet_state.label_by_pet(self, pet_data.owner)
|
self.pet_type.origin_pet = self
|
||||||
@items = Item.collection_from_pet_type_and_registries(self.pet_type,
|
biology = pet_data.biology_by_zone
|
||||||
contents.object_info_registry, contents.object_asset_registry)
|
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
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -64,6 +84,44 @@ class Pet < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
contributables
|
contributables
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def item_translation_candidates
|
||||||
|
{}.tap do |candidates|
|
||||||
|
if @items
|
||||||
|
@items.each do |item|
|
||||||
|
item.needed_translations.each do |locale|
|
||||||
|
candidates[locale] ||= []
|
||||||
|
candidates[locale] << item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
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}"
|
||||||
|
reloaded_pet = Pet.load(name, :item_scope => Item.includes(:translations),
|
||||||
|
:locale => locale)
|
||||||
|
Pet.connection_pool.with_connection { reloaded_pet.save! }
|
||||||
|
last_pet_loaded = reloaded_pet
|
||||||
|
end
|
||||||
|
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
|
before_validation do
|
||||||
pet_type.save!
|
pet_type.save!
|
||||||
|
@ -80,25 +138,12 @@ class Pet < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.load(name)
|
def self.load(name, options={})
|
||||||
pet = Pet.find_or_initialize_by_name(name)
|
pet = Pet.find_or_initialize_by_name(name)
|
||||||
pet.load!
|
pet.load!(options)
|
||||||
pet
|
pet
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def self.amf_service
|
|
||||||
@amf_service ||= gateway.service AMF_SERVICE_NAME
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.gateway
|
|
||||||
unless @gateway
|
|
||||||
@gateway = RocketAMF::RemoteGateway.new(GATEWAY_URL)
|
|
||||||
end
|
|
||||||
@gateway
|
|
||||||
end
|
|
||||||
|
|
||||||
class PetNotFound < Exception;end
|
class PetNotFound < Exception;end
|
||||||
class DownloadError < Exception;end
|
class DownloadError < Exception;end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,8 @@ class PetType < ActiveRecord::Base
|
||||||
IMAGE_CP_LOCATION_REGEX = %r{^/cp/(.+?)/1/1\.png$};
|
IMAGE_CP_LOCATION_REGEX = %r{^/cp/(.+?)/1/1\.png$};
|
||||||
IMAGE_CPN_ACCEPTABLE_NAME = /^[a-z0-9_]+$/
|
IMAGE_CPN_ACCEPTABLE_NAME = /^[a-z0-9_]+$/
|
||||||
|
|
||||||
|
belongs_to :species
|
||||||
|
belongs_to :color
|
||||||
has_one :contribution, :as => :contributed
|
has_one :contribution, :as => :contributed
|
||||||
has_many :pet_states
|
has_many :pet_states
|
||||||
has_many :pets
|
has_many :pets
|
||||||
|
@ -13,17 +15,20 @@ class PetType < ActiveRecord::Base
|
||||||
|
|
||||||
# Returns all pet types of a single standard color. The caller shouldn't care
|
# Returns all pet types of a single standard color. The caller shouldn't care
|
||||||
# which, though, in this implemention, it's always Blue. Don't depend on that.
|
# which, though, in this implemention, it's always Blue. Don't depend on that.
|
||||||
scope :single_standard_color, where(:color_id => Color::BasicIds[0])
|
scope :single_standard_color, lambda { where(:color_id => Color.standard.first) }
|
||||||
|
|
||||||
scope :nonstandard_colors, where(:color_id => Color.nonstandard_ids)
|
scope :nonstandard_colors, lambda { where(:color_id => Color.nonstandard) }
|
||||||
|
|
||||||
|
scope :includes_child_translations,
|
||||||
|
lambda { includes({:color => :translations, :species => :translations}) }
|
||||||
|
|
||||||
def self.standard_pet_types_by_species_id
|
def self.standard_pet_types_by_species_id
|
||||||
@standard_pet_types_by_species_id ||=
|
PetType.where(:color_id => Color.basic).includes_child_translations.
|
||||||
PetType.where(:color_id => Color::BasicIds).group_by(&:species_id)
|
group_by(&:species_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.standard_body_ids
|
def self.standard_body_ids
|
||||||
@standard_body_ids ||= [].tap do |body_ids|
|
[].tap do |body_ids|
|
||||||
standard_pet_types_by_species_id.each do |species_id, pet_types|
|
standard_pet_types_by_species_id.each do |species_id, pet_types|
|
||||||
body_ids.concat(pet_types.map(&:body_id))
|
body_ids.concat(pet_types.map(&:body_id))
|
||||||
end
|
end
|
||||||
|
@ -32,8 +37,9 @@ class PetType < ActiveRecord::Base
|
||||||
|
|
||||||
def self.random_basic_per_species(species_ids)
|
def self.random_basic_per_species(species_ids)
|
||||||
random_pet_types = []
|
random_pet_types = []
|
||||||
|
standards = self.standard_pet_types_by_species_id
|
||||||
species_ids.each do |species_id|
|
species_ids.each do |species_id|
|
||||||
pet_types = standard_pet_types_by_species_id[species_id]
|
pet_types = standards[species_id]
|
||||||
random_pet_types << pet_types[rand(pet_types.size)] if pet_types
|
random_pet_types << pet_types[rand(pet_types.size)] if pet_types
|
||||||
end
|
end
|
||||||
random_pet_types
|
random_pet_types
|
||||||
|
@ -51,40 +57,21 @@ class PetType < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def color_id=(new_color_id)
|
|
||||||
@color = nil
|
|
||||||
write_attribute('color_id', new_color_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def color=(new_color)
|
|
||||||
@color = new_color
|
|
||||||
write_attribute('color_id', @color.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def color
|
|
||||||
@color ||= Color.find(color_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def species_id=(new_species_id)
|
|
||||||
@species = nil
|
|
||||||
write_attribute('species_id', new_species_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def species=(new_species)
|
|
||||||
@species = new_species
|
|
||||||
write_attribute('species_id', @species.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def species
|
|
||||||
@species ||= Species.find(species_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def image_hash
|
def image_hash
|
||||||
self['image_hash'] || basic_image_hash
|
self['image_hash'] || basic_image_hash
|
||||||
end
|
end
|
||||||
|
|
||||||
def basic_image_hash
|
def basic_image_hash
|
||||||
BasicHashes[species.name][color.name]
|
I18n.with_locale(I18n.default_locale) do
|
||||||
|
# Probably should move the basic hashes into the database someday.
|
||||||
|
# Until then, access the hash using the English color/species names.
|
||||||
|
|
||||||
|
unless BasicHashes[species.name] && BasicHashes[species.name][color.name]
|
||||||
|
raise "basic image hash for #{species.name}, #{color.name} not found"
|
||||||
|
end
|
||||||
|
|
||||||
|
BasicHashes[species.name][color.name]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def human_name
|
def human_name
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
class Species < PetAttribute
|
class Species < ActiveRecord::Base
|
||||||
fetch_objects!
|
translates :name
|
||||||
|
|
||||||
def self.require_by_name(name)
|
scope :alphabetical, lambda { includes(:translations).order(Species::Translation.arel_table[:name]) }
|
||||||
species = Species.find_by_name(name)
|
|
||||||
raise NotFound, "Species \"#{name.humanize}\" does not exist" unless species
|
def as_json(options={})
|
||||||
species
|
{:id => id, :name => human_name}
|
||||||
end
|
end
|
||||||
|
|
||||||
class NotFound < ArgumentError;end
|
def human_name
|
||||||
|
name.capitalize
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,11 +5,21 @@ class StaticResource
|
||||||
@objects
|
@objects
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find(id)
|
def self.find(id_or_ids)
|
||||||
@objects[id-1]
|
if id_or_ids.is_a?(Array)
|
||||||
|
id_or_ids.uniq.map { |id| find_one(id) }
|
||||||
|
else
|
||||||
|
find_one(id_or_ids)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.count
|
def self.count
|
||||||
@objects.size
|
@objects.size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def self.find_one(id)
|
||||||
|
@objects[id - 1]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,6 +23,10 @@ class SwfAsset < ActiveRecord::Base
|
||||||
|
|
||||||
include SwfConverter
|
include SwfConverter
|
||||||
converts_swfs :size => IMAGE_SIZES[:large], :output_sizes => IMAGE_SIZES.values
|
converts_swfs :size => IMAGE_SIZES[:large], :output_sizes => IMAGE_SIZES.values
|
||||||
|
|
||||||
|
belongs_to :zone
|
||||||
|
|
||||||
|
scope :includes_depth, lambda { includes(:zone) }
|
||||||
|
|
||||||
def local_swf_path
|
def local_swf_path
|
||||||
LOCAL_ASSET_DIR.join(local_path_within_outfit_swfs)
|
LOCAL_ASSET_DIR.join(local_path_within_outfit_swfs)
|
||||||
|
@ -197,15 +201,7 @@ class SwfAsset < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def body_specific?
|
def body_specific?
|
||||||
# If we already have assigned this a non-zero body id, or if the asset is
|
self.zone.type_id < 3 || (@item && @item.body_specific?)
|
||||||
# in a body-specific zone, or if the item is explicitly labeled as
|
|
||||||
# body-specific (like Encased In Ice, which is body-specific but whose
|
|
||||||
# assets occupy Background Item), then this asset is body-specific.
|
|
||||||
(body_id? && body_id > 0) || self.zone.type_id < 3 || (@item && @item.explicitly_body_specific?)
|
|
||||||
end
|
|
||||||
|
|
||||||
def zone
|
|
||||||
Zone.find(zone_id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def origin_pet_type=(pet_type)
|
def origin_pet_type=(pet_type)
|
||||||
|
|
|
@ -1,51 +1,28 @@
|
||||||
class Zone < StaticResource
|
class Zone < ActiveRecord::Base
|
||||||
AttributeNames = ['id', 'label', 'depth', 'type_id']
|
translates :label, :plain_label
|
||||||
ItemZoneSets = {}
|
|
||||||
|
|
||||||
attr_reader *AttributeNames
|
|
||||||
# When selecting zones that an asset occupies, we allow the zone to set
|
# When selecting zones that an asset occupies, we allow the zone to set
|
||||||
# whether or not the zone is "sometimes" occupied. This is false by default.
|
# whether or not the zone is "sometimes" occupied. This is false by default.
|
||||||
attr_writer :sometimes
|
attr_writer :sometimes
|
||||||
|
|
||||||
def initialize(attributes)
|
scope :alphabetical, lambda {
|
||||||
AttributeNames.each do |name|
|
includes_translations.order(Zone::Translation.arel_table[:label])
|
||||||
instance_variable_set "@#{name}", attributes[name]
|
}
|
||||||
end
|
scope :includes_translations, lambda { includes(:translations) }
|
||||||
end
|
scope :with_plain_label, lambda { |label|
|
||||||
|
t = Zone::Translation.arel_table
|
||||||
|
includes(:translations).where(t[:plain_label].eq(Zone.plainify_label(label)))
|
||||||
|
}
|
||||||
|
|
||||||
def uncertain_label
|
def uncertain_label
|
||||||
@sometimes ? "#{label} sometimes" : label
|
@sometimes ? "#{label} sometimes" : label
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_set(name)
|
def self.all_plain_labels
|
||||||
ItemZoneSets[plain(name)]
|
Zone.select([:id]).includes(:translations).all.map(&:plain_label).uniq.sort
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.plain(name)
|
def self.plainify_label(label)
|
||||||
name.delete('\- /').downcase
|
label.delete('\- /').downcase
|
||||||
end
|
|
||||||
|
|
||||||
n = 0
|
|
||||||
@objects = YAML.load_file(Rails.root.join('config', 'zones.yml')).map do |a|
|
|
||||||
a['id'] = (n += 1)
|
|
||||||
obj = new(a)
|
|
||||||
if obj.type_id == 2 || obj.type_id == 3
|
|
||||||
plain_name = plain(obj.label)
|
|
||||||
|
|
||||||
ItemZoneSets[plain_name] ||= []
|
|
||||||
ItemZoneSets[plain_name] << obj
|
|
||||||
end
|
|
||||||
obj
|
|
||||||
end
|
|
||||||
n = nil
|
|
||||||
|
|
||||||
# Add aliases to keys like "lowerforegrounditem" to "lowerforeground"
|
|
||||||
# ...unless there's already such a key, like "backgrounditem" to "background",
|
|
||||||
# in which case we don't, because that'd be silly.
|
|
||||||
ItemZoneSets.keys.each do |name|
|
|
||||||
if name.end_with?('item')
|
|
||||||
stripped_name = name[0..-5]
|
|
||||||
ItemZoneSets[stripped_name] ||= ItemZoneSets[name]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
@import "partials/icon"
|
@import "partials/icon"
|
||||||
|
@import url(http://fonts.googleapis.com/css?family=Droid+Sans:400,700)
|
||||||
|
@import url(http://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic)
|
||||||
|
@import url(http://fonts.googleapis.com/css?family=Calligraffitti)
|
||||||
|
|
||||||
/* Reset
|
/* Reset
|
||||||
|
|
||||||
|
@ -249,30 +252,3 @@ dd
|
||||||
font-style: italic
|
font-style: italic
|
||||||
src: local("Delicious"), font-url("Delicious-Italic.otf")
|
src: local("Delicious"), font-url("Delicious-Italic.otf")
|
||||||
|
|
||||||
|
|
||||||
@font-face
|
|
||||||
font-family: 'Droid Serif'
|
|
||||||
font-style: normal
|
|
||||||
font-weight: normal
|
|
||||||
src: local("Droid Serif"), url("http://themes.googleusercontent.com/font?kit=70P0G8gxVDIV6F9om0DsKg") format("truetype")
|
|
||||||
|
|
||||||
|
|
||||||
@font-face
|
|
||||||
font-family: 'Droid Serif'
|
|
||||||
font-style: normal
|
|
||||||
font-weight: bold
|
|
||||||
src: local("Droid Serif"), url("http://themes.googleusercontent.com/font?kit=QQt14e8dY39u-eYBZmppwf5Jgr8ufe5A6KahQF76Xmg") format("truetype")
|
|
||||||
|
|
||||||
|
|
||||||
@font-face
|
|
||||||
font-family: 'Droid Sans'
|
|
||||||
font-style: normal
|
|
||||||
font-weight: normal
|
|
||||||
src: local("Droid Sans"), url("http://themes.googleusercontent.com/font?kit=POVDFY-UUf0WFR9DIMCU8g") format("truetype")
|
|
||||||
|
|
||||||
@font-face
|
|
||||||
font-family: 'Calligraffitti'
|
|
||||||
font-style: normal
|
|
||||||
font-weight: normal
|
|
||||||
src: local('Calligraffiti'), url('http://themes.googleusercontent.com/font?kit=vLVN2Y-z65rVu1R7lWdvyKIZAuDcNtpCWuPSaIR0Ie8') format('woff')
|
|
||||||
|
|
||||||
|
|
|
@ -53,13 +53,13 @@
|
||||||
#item-zones
|
#item-zones
|
||||||
%p
|
%p
|
||||||
%strong #{t '.zones.occupied_header'}:
|
%strong #{t '.zones.occupied_header'}:
|
||||||
= list_zones @item.occupied_zones, :uncertain_label
|
= list_zones @occupied_zones, :uncertain_label
|
||||||
%p
|
%p
|
||||||
%strong #{t '.zones.restricted_header'}:
|
%strong #{t '.zones.restricted_header'}:
|
||||||
- if @item.restricted_zones.empty?
|
- if @restricted_zones.empty?
|
||||||
= t '.zones.none'
|
= t '.zones.none'
|
||||||
- else
|
- else
|
||||||
= list_zones @item.restricted_zones
|
= list_zones @restricted_zones
|
||||||
|
|
||||||
#trade-hangers
|
#trade-hangers
|
||||||
- [true, false].each do |owned|
|
- [true, false].each do |owned|
|
||||||
|
|
36
config/flex.yml
Normal file
36
config/flex.yml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# ANCHORS litheral key: it will not be used as template
|
||||||
|
# you can store here fragments of structures to reuse below
|
||||||
|
ANCHORS:
|
||||||
|
-
|
||||||
|
|
||||||
|
# This is a dynamic index name The settings and mapping below will work with any index.
|
||||||
|
# The default index name generated by Flex is usually <application_name>_<environment>,
|
||||||
|
# but you may have changed it in the initializers/flex.rb or you can hardcode it if you prefer.
|
||||||
|
<%= Flex::Configuration.variables[:index] %>:
|
||||||
|
|
||||||
|
settings:
|
||||||
|
number_of_shards: 5
|
||||||
|
number_of_replicas: 1
|
||||||
|
|
||||||
|
# add your custom mappings here
|
||||||
|
mappings:
|
||||||
|
item:
|
||||||
|
properties:
|
||||||
|
# Name is an object of locale fields, which are in turn multi_fields.
|
||||||
|
# First, an analyzed string for searching. Second, an untouched
|
||||||
|
# string for sorting. Elasticsearch requires that both be expliticly
|
||||||
|
# named in the mapping, but will handle the copy implicitly.
|
||||||
|
name:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
<% I18n.usable_locales_with_neopets_language_code.each do |locale| %>
|
||||||
|
<%= locale %>:
|
||||||
|
type: multi_field
|
||||||
|
fields:
|
||||||
|
<%= locale %>:
|
||||||
|
type: string
|
||||||
|
index: analyzed
|
||||||
|
untouched:
|
||||||
|
type: string
|
||||||
|
index: not_analyzed
|
||||||
|
<% end %>
|
44
config/initializers/flex.rb
Normal file
44
config/initializers/flex.rb
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# see the detailed Configuration documentation at https://github.com/ddnexus/flex/wiki/Configuration
|
||||||
|
|
||||||
|
Flex::Configuration.configure do |config|
|
||||||
|
|
||||||
|
# you MUST add your indexed model names here
|
||||||
|
config.flex_models = %w[ Item ClosetHanger ]
|
||||||
|
|
||||||
|
# Add the your result extenders here
|
||||||
|
config.result_extenders |= [ FlexSearchExtender ]
|
||||||
|
|
||||||
|
# Add the default variables here
|
||||||
|
# see also the details Variables documentation at https://github.com/ddnexus/flex/wiki/Variables
|
||||||
|
# config.variables.add :index => 'my_index',
|
||||||
|
# :type => 'project',
|
||||||
|
# :anything => 'anything
|
||||||
|
|
||||||
|
# The custom url of your ElasticSearch server
|
||||||
|
# config.base_uri = 'http://localhost:9200'
|
||||||
|
|
||||||
|
# Set it to true to log the debug infos (true by default in development mode)
|
||||||
|
# config.debug = false
|
||||||
|
|
||||||
|
# Debug info are actually valid curl commands
|
||||||
|
# config.debug_to_curl = false
|
||||||
|
|
||||||
|
# The custom logger you want Flex to use. Default Rails.logger
|
||||||
|
# config.logger = Logger.new(STDERR)
|
||||||
|
|
||||||
|
# Custom config file path
|
||||||
|
# config.config_file = '/custom/path/to/flex.yml',
|
||||||
|
|
||||||
|
# Custom flex dir path
|
||||||
|
# config.flex_dir = '/custom/path/to/flex',
|
||||||
|
|
||||||
|
# The custom http_client you may want to implement
|
||||||
|
# config.http_client = 'Your::Client'
|
||||||
|
|
||||||
|
# The options passed to the http_client. They are client specific.
|
||||||
|
# config.http_client_options = {:timeout => 5}
|
||||||
|
|
||||||
|
# Experimental: checks the response and return a boolean (should raise?)
|
||||||
|
# config.raise_proc = proc{|response| response.status >= 400}
|
||||||
|
|
||||||
|
end
|
58
config/initializers/locale_meta.rb
Normal file
58
config/initializers/locale_meta.rb
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
module LocaleMeta
|
||||||
|
PUBLIC_LOCALES = []
|
||||||
|
USABLE_LOCALES = []
|
||||||
|
NEOPETS_LANGUAGE_CODES_BY_LOCALE = {}
|
||||||
|
LOCALES_WITH_NEOPETS_LANGUAGE_CODE = []
|
||||||
|
COMPATIBLE_LOCALES = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
config = YAML.load_file(Rails.root.join('config', 'locale_meta.yml'))
|
||||||
|
|
||||||
|
config.each do |locale_str, locale_meta|
|
||||||
|
locale = locale_str.to_sym
|
||||||
|
|
||||||
|
visibility = locale_meta['visibility']
|
||||||
|
if visibility == 'public'
|
||||||
|
LocaleMeta::PUBLIC_LOCALES << locale
|
||||||
|
LocaleMeta::USABLE_LOCALES << locale
|
||||||
|
elsif visibility == 'private'
|
||||||
|
LocaleMeta::USABLE_LOCALES << locale
|
||||||
|
end
|
||||||
|
|
||||||
|
if locale_meta.has_key?('neopets_language_code')
|
||||||
|
neopets_language_code = locale_meta['neopets_language_code']
|
||||||
|
LocaleMeta::NEOPETS_LANGUAGE_CODES_BY_LOCALE[locale] = neopets_language_code
|
||||||
|
LocaleMeta::LOCALES_WITH_NEOPETS_LANGUAGE_CODE << locale
|
||||||
|
elsif locale_meta.has_key?('compatible_with')
|
||||||
|
compatible_locale = locale_meta['compatible_with'].to_sym
|
||||||
|
LocaleMeta::COMPATIBLE_LOCALES[locale] = compatible_locale
|
||||||
|
else
|
||||||
|
raise "locale #{locale} must either have a neopets_language_code or " +
|
||||||
|
"be compatible_with a locale that does"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
LocaleMeta::USABLE_LOCALES_WITH_NEOPETS_LANGUAGE_CODE = LocaleMeta::USABLE_LOCALES &
|
||||||
|
LocaleMeta::LOCALES_WITH_NEOPETS_LANGUAGE_CODE
|
||||||
|
|
||||||
|
module I18n
|
||||||
|
def self.public_locales
|
||||||
|
LocaleMeta::PUBLIC_LOCALES
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.usable_locales
|
||||||
|
LocaleMeta::USABLE_LOCALES
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.locales_with_neopets_language_code
|
||||||
|
LocaleMeta::LOCALES_WITH_NEOPETS_LANGUAGE_CODE
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.usable_locales_with_neopets_language_code
|
||||||
|
LocaleMeta::USABLE_LOCALES_WITH_NEOPETS_LANGUAGE_CODE
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.neopets_language_code_for(locale)
|
||||||
|
LocaleMeta::NEOPETS_LANGUAGE_CODES_BY_LOCALE[locale]
|
||||||
|
end
|
||||||
|
end
|
47
config/locale_meta.yml
Normal file
47
config/locale_meta.yml
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
en:
|
||||||
|
visibility: public
|
||||||
|
neopets_language_code: en
|
||||||
|
|
||||||
|
en-MEEP:
|
||||||
|
visibility: public
|
||||||
|
compatible_with: en
|
||||||
|
|
||||||
|
pt:
|
||||||
|
visibility: private
|
||||||
|
neopets_language_code: pt
|
||||||
|
|
||||||
|
es:
|
||||||
|
visibility: none
|
||||||
|
neopets_language_code: es
|
||||||
|
|
||||||
|
nl:
|
||||||
|
visibility: none
|
||||||
|
neopets_language_code: nl
|
||||||
|
|
||||||
|
de:
|
||||||
|
visibility: none
|
||||||
|
neopets_language_code: de
|
||||||
|
|
||||||
|
fr:
|
||||||
|
visibility: none
|
||||||
|
neopets_language_code: fr
|
||||||
|
|
||||||
|
it:
|
||||||
|
visibility: none
|
||||||
|
neopets_language_code: it
|
||||||
|
|
||||||
|
zh-CN:
|
||||||
|
visibility: none
|
||||||
|
neopets_language_code: ch
|
||||||
|
|
||||||
|
zh-TW:
|
||||||
|
visibility: none
|
||||||
|
neopets_language_code: zh
|
||||||
|
|
||||||
|
ja:
|
||||||
|
visibility: none
|
||||||
|
neopets_language_code: ja
|
||||||
|
|
||||||
|
ko:
|
||||||
|
visibility: none
|
||||||
|
neopets_language_code: ko
|
|
@ -325,6 +325,30 @@ en:
|
||||||
contributors:
|
contributors:
|
||||||
header: Brought to you by
|
header: Brought to you by
|
||||||
footer: Thanks!
|
footer: Thanks!
|
||||||
|
|
||||||
|
search:
|
||||||
|
errors:
|
||||||
|
not_found:
|
||||||
|
label: Filter "%{label}" does not exist. Is it spelled correctly?
|
||||||
|
species:
|
||||||
|
Species "%{species_name}" does not exist. Is it spelled correctly?
|
||||||
|
zone: Zone "%{zone_name}" does not exist. Is it spelled correctly?
|
||||||
|
ownership:
|
||||||
|
I don't know what user:%{keyword} means. Is it spelled correctly?
|
||||||
|
not_logged_in:
|
||||||
|
The "user" filters are only available if you're logged in.
|
||||||
|
flag_keywords:
|
||||||
|
is: is
|
||||||
|
labels:
|
||||||
|
name: name
|
||||||
|
is_nc: nc
|
||||||
|
is_pb: pb
|
||||||
|
species_support_id: species
|
||||||
|
occupied_zone_id: occupies,zone,type
|
||||||
|
restricted_zone_id: restricts
|
||||||
|
user_closet_hanger_ownership: user
|
||||||
|
user_owns: owns
|
||||||
|
user_wants: wants
|
||||||
|
|
||||||
neopets_pages:
|
neopets_pages:
|
||||||
create:
|
create:
|
||||||
|
|
5
config/locales/pt.yml
Normal file
5
config/locales/pt.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
pt:
|
||||||
|
locale_name: Portuguese
|
||||||
|
|
||||||
|
# This is a placeholder Portuguese locale, so that we can test things
|
||||||
|
# involving its presence.
|
17
db/migrate/20130111213346_translate_items.rb
Normal file
17
db/migrate/20130111213346_translate_items.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
class TranslateItems < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
rename_table :objects, :items
|
||||||
|
Item.create_translation_table!({
|
||||||
|
:name => :string,
|
||||||
|
:description => :text,
|
||||||
|
:rarity => :string
|
||||||
|
}, {
|
||||||
|
:migrate_data => true
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
Item.drop_translation_table! :migrate_data => true
|
||||||
|
rename_table :items, :objects
|
||||||
|
end
|
||||||
|
end
|
11
db/migrate/20130121193957_create_species.rb
Normal file
11
db/migrate/20130121193957_create_species.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class CreateSpecies < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :species
|
||||||
|
Species.create_translation_table! :name => :string
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :species
|
||||||
|
Species.drop_translation_table!
|
||||||
|
end
|
||||||
|
end
|
14
db/migrate/20130121205607_create_colors.rb
Normal file
14
db/migrate/20130121205607_create_colors.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
class CreateColors < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :colors do |t|
|
||||||
|
t.boolean :basic
|
||||||
|
t.boolean :standard
|
||||||
|
end
|
||||||
|
Color.create_translation_table! :name => :string
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :colors
|
||||||
|
Color.drop_translation_table!
|
||||||
|
end
|
||||||
|
end
|
14
db/migrate/20130121221226_create_zones.rb
Normal file
14
db/migrate/20130121221226_create_zones.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
class CreateZones < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :zones do |t|
|
||||||
|
t.integer :depth
|
||||||
|
t.integer :type_id
|
||||||
|
end
|
||||||
|
Zone.create_translation_table! :label => :string, :plain_label => :string
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :zones
|
||||||
|
Zone.drop_translation_table!
|
||||||
|
end
|
||||||
|
end
|
105
db/schema.rb
105
db/schema.rb
|
@ -1,3 +1,4 @@
|
||||||
|
# encoding: UTF-8
|
||||||
# This file is auto-generated from the current state of the database. Instead
|
# This file is auto-generated from the current state of the database. Instead
|
||||||
# of editing this file, please use the migrations feature of Active Record to
|
# of editing this file, please use the migrations feature of Active Record to
|
||||||
# incrementally modify your database, and then regenerate this schema definition.
|
# incrementally modify your database, and then regenerate this schema definition.
|
||||||
|
@ -10,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20121006010446) do
|
ActiveRecord::Schema.define(:version => 20130121221226) do
|
||||||
|
|
||||||
create_table "auth_servers", :force => true do |t|
|
create_table "auth_servers", :force => true do |t|
|
||||||
t.string "short_name", :limit => 10, :null => false
|
t.string "short_name", :limit => 10, :null => false
|
||||||
|
@ -20,6 +21,13 @@ ActiveRecord::Schema.define(:version => 20121006010446) do
|
||||||
t.string "secret", :limit => 64, :null => false
|
t.string "secret", :limit => 64, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "campaigns", :force => true do |t|
|
||||||
|
t.integer "goal_cents", :null => false
|
||||||
|
t.integer "progress_cents", :null => false
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "closet_hangers", :force => true do |t|
|
create_table "closet_hangers", :force => true do |t|
|
||||||
t.integer "item_id"
|
t.integer "item_id"
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
|
@ -46,9 +54,20 @@ ActiveRecord::Schema.define(:version => 20121006010446) do
|
||||||
|
|
||||||
add_index "closet_lists", ["user_id"], :name => "index_closet_lists_on_user_id"
|
add_index "closet_lists", ["user_id"], :name => "index_closet_lists_on_user_id"
|
||||||
|
|
||||||
|
create_table "color_translations", :force => true do |t|
|
||||||
|
t.integer "color_id"
|
||||||
|
t.string "locale"
|
||||||
|
t.string "name"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "color_translations", ["color_id"], :name => "index_color_translations_on_color_id"
|
||||||
|
add_index "color_translations", ["locale"], :name => "index_color_translations_on_locale"
|
||||||
|
|
||||||
create_table "colors", :force => true do |t|
|
create_table "colors", :force => true do |t|
|
||||||
t.string "name"
|
t.boolean "basic"
|
||||||
t.boolean "basic", :default => false, :null => false
|
t.boolean "standard"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "contributions", :force => true do |t|
|
create_table "contributions", :force => true do |t|
|
||||||
|
@ -61,6 +80,14 @@ ActiveRecord::Schema.define(:version => 20121006010446) do
|
||||||
add_index "contributions", ["contributed_id", "contributed_type"], :name => "index_contributions_on_contributed_id_and_contributed_type"
|
add_index "contributions", ["contributed_id", "contributed_type"], :name => "index_contributions_on_contributed_id_and_contributed_type"
|
||||||
add_index "contributions", ["user_id"], :name => "index_contributions_on_user_id"
|
add_index "contributions", ["user_id"], :name => "index_contributions_on_user_id"
|
||||||
|
|
||||||
|
create_table "donations", :force => true do |t|
|
||||||
|
t.integer "amount_cents", :null => false
|
||||||
|
t.integer "campaign_id", :null => false
|
||||||
|
t.integer "user_id"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "forums", :force => true do |t|
|
create_table "forums", :force => true do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.text "description"
|
t.text "description"
|
||||||
|
@ -80,16 +107,20 @@ ActiveRecord::Schema.define(:version => 20121006010446) do
|
||||||
add_index "item_outfit_relationships", ["item_id"], :name => "index_item_outfit_relationships_on_item_id"
|
add_index "item_outfit_relationships", ["item_id"], :name => "index_item_outfit_relationships_on_item_id"
|
||||||
add_index "item_outfit_relationships", ["outfit_id", "is_worn"], :name => "index_item_outfit_relationships_on_outfit_id_and_is_worn"
|
add_index "item_outfit_relationships", ["outfit_id", "is_worn"], :name => "index_item_outfit_relationships_on_outfit_id_and_is_worn"
|
||||||
|
|
||||||
create_table "login_cookies", :force => true do |t|
|
create_table "item_translations", :force => true do |t|
|
||||||
t.integer "user_id", :null => false
|
t.integer "item_id"
|
||||||
t.integer "series", :null => false
|
t.string "locale"
|
||||||
t.integer "token", :null => false
|
t.string "name"
|
||||||
|
t.text "description"
|
||||||
|
t.string "rarity"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "login_cookies", ["user_id", "series"], :name => "login_cookies_user_id_and_series"
|
add_index "item_translations", ["item_id"], :name => "index_item_translations_on_item_id"
|
||||||
add_index "login_cookies", ["user_id"], :name => "login_cookies_user_id"
|
add_index "item_translations", ["locale"], :name => "index_item_translations_on_locale"
|
||||||
|
|
||||||
create_table "objects", :force => true do |t|
|
create_table "items", :force => true do |t|
|
||||||
t.text "zones_restrict", :null => false
|
t.text "zones_restrict", :null => false
|
||||||
t.text "thumbnail_url", :limit => 16777215, :null => false
|
t.text "thumbnail_url", :limit => 16777215, :null => false
|
||||||
t.string "name", :limit => 100, :null => false
|
t.string "name", :limit => 100, :null => false
|
||||||
|
@ -108,8 +139,25 @@ ActiveRecord::Schema.define(:version => 20121006010446) do
|
||||||
t.boolean "explicitly_body_specific", :default => false, :null => false
|
t.boolean "explicitly_body_specific", :default => false, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "objects", ["last_spidered"], :name => "objects_last_spidered"
|
add_index "items", ["last_spidered"], :name => "objects_last_spidered"
|
||||||
add_index "objects", ["name"], :name => "name"
|
add_index "items", ["name"], :name => "name"
|
||||||
|
|
||||||
|
create_table "login_cookies", :force => true do |t|
|
||||||
|
t.integer "user_id", :null => false
|
||||||
|
t.integer "series", :null => false
|
||||||
|
t.integer "token", :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "login_cookies", ["user_id", "series"], :name => "login_cookies_user_id_and_series"
|
||||||
|
add_index "login_cookies", ["user_id"], :name => "login_cookies_user_id"
|
||||||
|
|
||||||
|
create_table "outfit_features", :force => true do |t|
|
||||||
|
t.integer "outfit_id", :null => false
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
t.date "frontpage_start_date"
|
||||||
|
t.date "frontpage_end_date"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "outfits", :force => true do |t|
|
create_table "outfits", :force => true do |t|
|
||||||
t.integer "pet_state_id"
|
t.integer "pet_state_id"
|
||||||
|
@ -121,6 +169,7 @@ ActiveRecord::Schema.define(:version => 20121006010446) do
|
||||||
t.string "image"
|
t.string "image"
|
||||||
t.string "image_layers_hash"
|
t.string "image_layers_hash"
|
||||||
t.boolean "image_enqueued", :default => false, :null => false
|
t.boolean "image_enqueued", :default => false, :null => false
|
||||||
|
t.boolean "image_dirty", :default => false, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "outfits", ["pet_state_id"], :name => "index_outfits_on_pet_state_id"
|
add_index "outfits", ["pet_state_id"], :name => "index_outfits_on_pet_state_id"
|
||||||
|
@ -179,6 +228,20 @@ ActiveRecord::Schema.define(:version => 20121006010446) do
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "species", :force => true do |t|
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "species_translations", :force => true do |t|
|
||||||
|
t.integer "species_id"
|
||||||
|
t.string "locale"
|
||||||
|
t.string "name"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "species_translations", ["locale"], :name => "index_species_translations_on_locale"
|
||||||
|
add_index "species_translations", ["species_id"], :name => "index_species_translations_on_species_id"
|
||||||
|
|
||||||
create_table "swf_assets", :force => true do |t|
|
create_table "swf_assets", :force => true do |t|
|
||||||
t.string "type", :limit => 7, :null => false
|
t.string "type", :limit => 7, :null => false
|
||||||
t.integer "remote_id", :limit => 3, :null => false
|
t.integer "remote_id", :limit => 3, :null => false
|
||||||
|
@ -223,11 +286,21 @@ ActiveRecord::Schema.define(:version => 20121006010446) do
|
||||||
t.integer "wanted_closet_hangers_visibility", :default => 1, :null => false
|
t.integer "wanted_closet_hangers_visibility", :default => 1, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "zone_translations", :force => true do |t|
|
||||||
|
t.integer "zone_id"
|
||||||
|
t.string "locale"
|
||||||
|
t.string "label"
|
||||||
|
t.string "plain_label"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "zone_translations", ["locale"], :name => "index_zone_translations_on_locale"
|
||||||
|
add_index "zone_translations", ["zone_id"], :name => "index_zone_translations_on_zone_id"
|
||||||
|
|
||||||
create_table "zones", :force => true do |t|
|
create_table "zones", :force => true do |t|
|
||||||
t.integer "depth", :limit => 1, :null => false
|
t.integer "depth"
|
||||||
t.integer "type_id", :limit => 1, :null => false
|
t.integer "type_id"
|
||||||
t.string "type", :limit => 40, :null => false
|
|
||||||
t.string "label", :limit => 40, :null => false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
215
db/seeds.rb
215
db/seeds.rb
|
@ -1,7 +1,208 @@
|
||||||
# This file should contain all the record creation needed to seed the database with its default values.
|
Species.create(:id => 1, :name => "acara")
|
||||||
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
|
Species.create(:id => 2, :name => "aisha")
|
||||||
#
|
Species.create(:id => 3, :name => "blumaroo")
|
||||||
# Examples:
|
Species.create(:id => 4, :name => "bori")
|
||||||
#
|
Species.create(:id => 5, :name => "bruce")
|
||||||
# cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
|
Species.create(:id => 6, :name => "buzz")
|
||||||
# Mayor.create(:name => 'Daley', :city => cities.first)
|
Species.create(:id => 7, :name => "chia")
|
||||||
|
Species.create(:id => 8, :name => "chomby")
|
||||||
|
Species.create(:id => 9, :name => "cybunny")
|
||||||
|
Species.create(:id => 10, :name => "draik")
|
||||||
|
Species.create(:id => 11, :name => "elephante")
|
||||||
|
Species.create(:id => 12, :name => "eyrie")
|
||||||
|
Species.create(:id => 13, :name => "flotsam")
|
||||||
|
Species.create(:id => 14, :name => "gelert")
|
||||||
|
Species.create(:id => 15, :name => "gnorbu")
|
||||||
|
Species.create(:id => 16, :name => "grarrl")
|
||||||
|
Species.create(:id => 17, :name => "grundo")
|
||||||
|
Species.create(:id => 18, :name => "hissi")
|
||||||
|
Species.create(:id => 19, :name => "ixi")
|
||||||
|
Species.create(:id => 20, :name => "jetsam")
|
||||||
|
Species.create(:id => 21, :name => "jubjub")
|
||||||
|
Species.create(:id => 22, :name => "kacheek")
|
||||||
|
Species.create(:id => 23, :name => "kau")
|
||||||
|
Species.create(:id => 24, :name => "kiko")
|
||||||
|
Species.create(:id => 25, :name => "koi")
|
||||||
|
Species.create(:id => 26, :name => "korbat")
|
||||||
|
Species.create(:id => 27, :name => "kougra")
|
||||||
|
Species.create(:id => 28, :name => "krawk")
|
||||||
|
Species.create(:id => 29, :name => "kyrii")
|
||||||
|
Species.create(:id => 30, :name => "lenny")
|
||||||
|
Species.create(:id => 31, :name => "lupe")
|
||||||
|
Species.create(:id => 32, :name => "lutari")
|
||||||
|
Species.create(:id => 33, :name => "meerca")
|
||||||
|
Species.create(:id => 34, :name => "moehog")
|
||||||
|
Species.create(:id => 35, :name => "mynci")
|
||||||
|
Species.create(:id => 36, :name => "nimmo")
|
||||||
|
Species.create(:id => 37, :name => "ogrin")
|
||||||
|
Species.create(:id => 38, :name => "peophin")
|
||||||
|
Species.create(:id => 39, :name => "poogle")
|
||||||
|
Species.create(:id => 40, :name => "pteri")
|
||||||
|
Species.create(:id => 41, :name => "quiggle")
|
||||||
|
Species.create(:id => 42, :name => "ruki")
|
||||||
|
Species.create(:id => 43, :name => "scorchio")
|
||||||
|
Species.create(:id => 44, :name => "shoyru")
|
||||||
|
Species.create(:id => 45, :name => "skeith")
|
||||||
|
Species.create(:id => 46, :name => "techo")
|
||||||
|
Species.create(:id => 47, :name => "tonu")
|
||||||
|
Species.create(:id => 48, :name => "tuskaninny")
|
||||||
|
Species.create(:id => 49, :name => "uni")
|
||||||
|
Species.create(:id => 50, :name => "usul")
|
||||||
|
Species.create(:id => 51, :name => "wocky")
|
||||||
|
Species.create(:id => 52, :name => "xweetok")
|
||||||
|
Species.create(:id => 53, :name => "yurble")
|
||||||
|
Species.create(:id => 54, :name => "zafara")
|
||||||
|
|
||||||
|
Color.create(:id => 1, :name => "alien", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 2, :name => "apple", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 3, :name => "asparagus", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 4, :name => "aubergine", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 5, :name => "avocado", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 6, :name => "baby", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 7, :name => "biscuit", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 8, :name => "blue", :basic => true, :standard => true)
|
||||||
|
Color.create(:id => 9, :name => "blueberry", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 10, :name => "brown", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 11, :name => "camouflage", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 12, :name => "carrot", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 13, :name => "checkered", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 14, :name => "chocolate", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 15, :name => "chokato", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 16, :name => "christmas", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 17, :name => "clay", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 18, :name => "cloud", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 19, :name => "coconut", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 20, :name => "custard", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 21, :name => "darigan", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 22, :name => "desert", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 23, :name => "disco", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 24, :name => "durian", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 25, :name => "electric", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 26, :name => "faerie", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 27, :name => "fire", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 28, :name => "garlic", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 29, :name => "ghost", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 30, :name => "glowing", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 31, :name => "gold", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 32, :name => "gooseberry", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 33, :name => "grape", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 34, :name => "green", :basic => true, :standard => true)
|
||||||
|
Color.create(:id => 35, :name => "grey", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 36, :name => "halloween", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 37, :name => "ice", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 38, :name => "invisible", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 39, :name => "island", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 40, :name => "jelly", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 41, :name => "lemon", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 42, :name => "lime", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 43, :name => "mallow", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 44, :name => "maraquan", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 45, :name => "msp", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 46, :name => "mutant", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 47, :name => "orange", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 48, :name => "pea", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 49, :name => "peach", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 50, :name => "pear", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 51, :name => "pepper", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 52, :name => "pineapple", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 53, :name => "pink", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 54, :name => "pirate", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 55, :name => "plum", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 56, :name => "plushie", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 57, :name => "purple", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 58, :name => "quigukiboy", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 59, :name => "quigukigirl", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 60, :name => "rainbow", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 61, :name => "red", :basic => true, :standard => true)
|
||||||
|
Color.create(:id => 62, :name => "robot", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 63, :name => "royalboy", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 64, :name => "royalgirl", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 65, :name => "shadow", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 66, :name => "silver", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 67, :name => "sketch", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 68, :name => "skunk", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 69, :name => "snot", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 70, :name => "snow", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 71, :name => "speckled", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 72, :name => "split", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 73, :name => "sponge", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 74, :name => "spotted", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 75, :name => "starry", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 76, :name => "strawberry", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 77, :name => "striped", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 78, :name => "thornberry", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 79, :name => "tomato", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 80, :name => "tyrannian", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 81, :name => "usukiboy", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 82, :name => "usukigirl", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 83, :name => "white", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 84, :name => "yellow", :basic => true, :standard => true)
|
||||||
|
Color.create(:id => 85, :name => "zombie", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 86, :name => "onion", :basic => false, :standard => false)
|
||||||
|
Color.create(:id => 87, :name => "magma", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 88, :name => "relic", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 89, :name => "woodland", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 90, :name => "transparent", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 91, :name => "maractite", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 92, :name => "8-bit", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 93, :name => "swamp gas", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 94, :name => "water", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 95, :name => "wraith", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 96, :name => "eventide", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 97, :name => "elderlyboy", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 98, :name => "elderlygirl", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 99, :name => "stealthy", :basic => false, :standard => true)
|
||||||
|
Color.create(:id => 100, :name => "dimensional", :basic => false, :standard => true)
|
||||||
|
|
||||||
|
Zone.create(:id => 1, :label => "Music", :plain_label => "music", :depth => 1, :type_id => 4)
|
||||||
|
Zone.create(:id => 2, :label => "Sound Effects", :plain_label => "soundeffects", :depth => 2, :type_id => 4)
|
||||||
|
Zone.create(:id => 3, :label => "Background", :plain_label => "background", :depth => 3, :type_id => 3)
|
||||||
|
Zone.create(:id => 4, :label => "Biology Effects", :plain_label => "biologyeffects", :depth => 6, :type_id => 1)
|
||||||
|
Zone.create(:id => 5, :label => "Hind Biology", :plain_label => "hindbiology", :depth => 7, :type_id => 1)
|
||||||
|
Zone.create(:id => 6, :label => "Markings", :plain_label => "markings", :depth => 8, :type_id => 2)
|
||||||
|
Zone.create(:id => 7, :label => "Hind Disease", :plain_label => "hinddisease", :depth => 9, :type_id => 1)
|
||||||
|
Zone.create(:id => 8, :label => "Hind Cover", :plain_label => "hindcover", :depth => 10, :type_id => 2)
|
||||||
|
Zone.create(:id => 9, :label => "Hind Transient Biology", :plain_label => "hindtransientbiology", :depth => 11, :type_id => 1)
|
||||||
|
Zone.create(:id => 10, :label => "Hind Drippings", :plain_label => "hinddrippings", :depth => 12, :type_id => 1)
|
||||||
|
Zone.create(:id => 11, :label => "Backpack", :plain_label => "backpack", :depth => 13, :type_id => 2)
|
||||||
|
Zone.create(:id => 12, :label => "Wings Transient Biology", :plain_label => "wingstransientbiology", :depth => 14, :type_id => 1)
|
||||||
|
Zone.create(:id => 13, :label => "Wings", :plain_label => "wings", :depth => 15, :type_id => 2)
|
||||||
|
Zone.create(:id => 14, :label => "Hair Back", :plain_label => "hairback", :depth => 17, :type_id => 1)
|
||||||
|
Zone.create(:id => 15, :label => "Body", :plain_label => "body", :depth => 18, :type_id => 1)
|
||||||
|
Zone.create(:id => 16, :label => "Markings", :plain_label => "markings", :depth => 19, :type_id => 2)
|
||||||
|
Zone.create(:id => 17, :label => "Body Disease", :plain_label => "bodydisease", :depth => 20, :type_id => 1)
|
||||||
|
Zone.create(:id => 18, :label => "Feet Transient Biology", :plain_label => "feettransientbiology", :depth => 21, :type_id => 1)
|
||||||
|
Zone.create(:id => 19, :label => "Shoes", :plain_label => "shoes", :depth => 22, :type_id => 2)
|
||||||
|
Zone.create(:id => 20, :label => "Lower-body Transient Biology", :plain_label => "lowerbodytransientbiology", :depth => 23, :type_id => 1)
|
||||||
|
Zone.create(:id => 21, :label => "Trousers", :plain_label => "trousers", :depth => 24, :type_id => 2)
|
||||||
|
Zone.create(:id => 22, :label => "Upper-body Transient Biology", :plain_label => "upperbodytransientbiology", :depth => 25, :type_id => 1)
|
||||||
|
Zone.create(:id => 23, :label => "Shirt/Dress", :plain_label => "shirtdress", :depth => 26, :type_id => 2)
|
||||||
|
Zone.create(:id => 24, :label => "Necklace", :plain_label => "necklace", :depth => 28, :type_id => 2)
|
||||||
|
Zone.create(:id => 25, :label => "Gloves", :plain_label => "gloves", :depth => 29, :type_id => 2)
|
||||||
|
Zone.create(:id => 26, :label => "Jacket", :plain_label => "jacket", :depth => 30, :type_id => 2)
|
||||||
|
Zone.create(:id => 27, :label => "Collar", :plain_label => "collar", :depth => 31, :type_id => 2)
|
||||||
|
Zone.create(:id => 28, :label => "Body Drippings", :plain_label => "bodydrippings", :depth => 32, :type_id => 1)
|
||||||
|
Zone.create(:id => 29, :label => "Ruff", :plain_label => "ruff", :depth => 33, :type_id => 1)
|
||||||
|
Zone.create(:id => 30, :label => "Head", :plain_label => "head", :depth => 34, :type_id => 1)
|
||||||
|
Zone.create(:id => 31, :label => "Markings", :plain_label => "markings", :depth => 35, :type_id => 2)
|
||||||
|
Zone.create(:id => 32, :label => "Head Disease", :plain_label => "headdisease", :depth => 36, :type_id => 1)
|
||||||
|
Zone.create(:id => 33, :label => "Eyes", :plain_label => "eyes", :depth => 37, :type_id => 1)
|
||||||
|
Zone.create(:id => 34, :label => "Mouth", :plain_label => "mouth", :depth => 38, :type_id => 1)
|
||||||
|
Zone.create(:id => 35, :label => "Glasses", :plain_label => "glasses", :depth => 41, :type_id => 2)
|
||||||
|
Zone.create(:id => 36, :label => "Earrings", :plain_label => "earrings", :depth => 39, :type_id => 2)
|
||||||
|
Zone.create(:id => 37, :label => "Hair Front", :plain_label => "hairfront", :depth => 40, :type_id => 1)
|
||||||
|
Zone.create(:id => 38, :label => "Head Transient Biology", :plain_label => "headtransientbiology", :depth => 42, :type_id => 1)
|
||||||
|
Zone.create(:id => 39, :label => "Head Drippings", :plain_label => "headdrippings", :depth => 43, :type_id => 1)
|
||||||
|
Zone.create(:id => 40, :label => "Hat", :plain_label => "hat", :depth => 44, :type_id => 2)
|
||||||
|
Zone.create(:id => 41, :label => "Earrings", :plain_label => "earrings", :depth => 45, :type_id => 2)
|
||||||
|
Zone.create(:id => 42, :label => "Right-hand Item", :plain_label => "righthand", :depth => 46, :type_id => 2)
|
||||||
|
Zone.create(:id => 43, :label => "Left-hand Item", :plain_label => "lefthand", :depth => 47, :type_id => 2)
|
||||||
|
Zone.create(:id => 44, :label => "Higher Foreground Item", :plain_label => "higherforeground", :depth => 49, :type_id => 3)
|
||||||
|
Zone.create(:id => 45, :label => "Lower Foreground Item", :plain_label => "lowerforeground", :depth => 50, :type_id => 3)
|
||||||
|
Zone.create(:id => 46, :label => "Static", :plain_label => "static", :depth => 48, :type_id => 3)
|
||||||
|
Zone.create(:id => 47, :label => "Thought Bubble", :plain_label => "thoughtbubble", :depth => 51, :type_id => 3)
|
||||||
|
Zone.create(:id => 48, :label => "Background Item", :plain_label => "background", :depth => 4, :type_id => 3)
|
||||||
|
Zone.create(:id => 49, :label => "Right-hand Item", :plain_label => "righthand", :depth => 5, :type_id => 2)
|
||||||
|
Zone.create(:id => 50, :label => "Hat", :plain_label => "hat", :depth => 16, :type_id => 2)
|
||||||
|
Zone.create(:id => 51, :label => "Belt", :plain_label => "belt", :depth => 27, :type_id => 2)
|
||||||
|
Zone.create(:id => 52, :label => "Foreground", :plain_label => "foreground", :depth => 52, :type_id => 3)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
require 'net/http'
|
require 'net/http'
|
||||||
require 'rocketamf'
|
require 'rocketamf'
|
||||||
require File.join(File.dirname(__FILE__), 'remote_gateway', 'service')
|
require File.join(File.dirname(__FILE__), 'remote_gateway', 'service')
|
||||||
require File.join(File.dirname(__FILE__), 'remote_gateway', 'request')
|
|
||||||
|
|
||||||
module RocketAMF
|
module RocketAMF
|
||||||
class RemoteGateway
|
class RemoteGateway
|
||||||
|
|
18
lib/rocketamf/remote_gateway/action.rb
Normal file
18
lib/rocketamf/remote_gateway/action.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
require File.join(File.dirname(__FILE__), 'request')
|
||||||
|
|
||||||
|
module RocketAMF
|
||||||
|
class RemoteGateway
|
||||||
|
class Action
|
||||||
|
attr_reader :service, :name
|
||||||
|
|
||||||
|
def initialize(service, name)
|
||||||
|
@service = service
|
||||||
|
@name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
def request(params)
|
||||||
|
Request.new(self, params)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,18 +5,21 @@ module RocketAMF
|
||||||
class Request
|
class Request
|
||||||
ERROR_CODE = 'AMFPHP_RUNTIME_ERROR'
|
ERROR_CODE = 'AMFPHP_RUNTIME_ERROR'
|
||||||
|
|
||||||
def initialize(service, method, *params)
|
def initialize(action, params)
|
||||||
@service = service
|
@action = action
|
||||||
@method = method
|
|
||||||
@params = params
|
@params = params
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch(options={})
|
def post(options={})
|
||||||
uri = @service.gateway.uri
|
uri = @action.service.gateway.uri
|
||||||
data = envelope.serialize
|
data = envelope.serialize
|
||||||
|
|
||||||
req = Net::HTTP::Post.new(uri.path)
|
req = Net::HTTP::Post.new(uri.path)
|
||||||
req.body = data
|
req.body = data
|
||||||
|
headers = options[:headers] || {}
|
||||||
|
headers.each do |key, value|
|
||||||
|
req[key] = value
|
||||||
|
end
|
||||||
|
|
||||||
res = nil
|
res = nil
|
||||||
|
|
||||||
|
@ -68,8 +71,8 @@ module RocketAMF
|
||||||
|
|
||||||
def remoting_message
|
def remoting_message
|
||||||
message = Values::RemotingMessage.new
|
message = Values::RemotingMessage.new
|
||||||
message.source = @service.name
|
message.source = @action.service.name
|
||||||
message.operation = @method
|
message.operation = @action.name
|
||||||
message.body = @params
|
message.body = @params
|
||||||
message
|
message
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
require File.join(File.dirname(__FILE__), 'action')
|
||||||
|
|
||||||
module RocketAMF
|
module RocketAMF
|
||||||
class RemoteGateway
|
class RemoteGateway
|
||||||
class Service
|
class Service
|
||||||
|
@ -8,8 +10,8 @@ module RocketAMF
|
||||||
@name = name
|
@name = name
|
||||||
end
|
end
|
||||||
|
|
||||||
def request(method, *params)
|
def action(name)
|
||||||
Request.new(self, method, *params)
|
Action.new(self, name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
|
@import url(http://fonts.googleapis.com/css?family=Droid+Sans:400,700);
|
||||||
|
@import url(http://fonts.googleapis.com/css?family=Droid+Serif:400,700,400italic);
|
||||||
|
@import url(http://fonts.googleapis.com/css?family=Calligraffitti);
|
||||||
/* Reset */
|
/* Reset */
|
||||||
/* line 5, ../../../app/stylesheets/_layout.sass */
|
/* line 8, ../../../app/stylesheets/_layout.sass */
|
||||||
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p,
|
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p,
|
||||||
blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em,
|
blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em,
|
||||||
font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b,
|
font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b,
|
||||||
|
@ -16,12 +19,12 @@ caption, tbody, tfoot, thead, tr, th, td {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Typography */
|
/* Typography */
|
||||||
/* line 20, ../../../app/stylesheets/_layout.sass */
|
/* line 23, ../../../app/stylesheets/_layout.sass */
|
||||||
html, body {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 23, ../../../app/stylesheets/_layout.sass */
|
/* line 26, ../../../app/stylesheets/_layout.sass */
|
||||||
body {
|
body {
|
||||||
background: white;
|
background: white;
|
||||||
color: #004400;
|
color: #004400;
|
||||||
|
@ -30,60 +33,60 @@ body {
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 31, ../../../app/stylesheets/_layout.sass */
|
/* line 34, ../../../app/stylesheets/_layout.sass */
|
||||||
a {
|
a {
|
||||||
color: #226622;
|
color: #226622;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 34, ../../../app/stylesheets/_layout.sass */
|
/* line 37, ../../../app/stylesheets/_layout.sass */
|
||||||
p {
|
p {
|
||||||
font-family: "Droid Serif", Georgia, "Times New Roman", Times, serif;
|
font-family: "Droid Serif", Georgia, "Times New Roman", Times, serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 37, ../../../app/stylesheets/_layout.sass */
|
/* line 40, ../../../app/stylesheets/_layout.sass */
|
||||||
input, button, select {
|
input, button, select {
|
||||||
font-family: inherit;
|
font-family: inherit;
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 42, ../../../app/stylesheets/_layout.sass */
|
/* line 45, ../../../app/stylesheets/_layout.sass */
|
||||||
p {
|
p {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 45, ../../../app/stylesheets/_layout.sass */
|
/* line 48, ../../../app/stylesheets/_layout.sass */
|
||||||
h1, h2, h3 {
|
h1, h2, h3 {
|
||||||
font-family: Delicious, Helvetica, Arial, Verdana, sans-serif;
|
font-family: Delicious, Helvetica, Arial, Verdana, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 48, ../../../app/stylesheets/_layout.sass */
|
/* line 51, ../../../app/stylesheets/_layout.sass */
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 3em;
|
font-size: 3em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 53, ../../../app/stylesheets/_layout.sass */
|
/* line 56, ../../../app/stylesheets/_layout.sass */
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
margin-bottom: 0.75em;
|
margin-bottom: 0.75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 57, ../../../app/stylesheets/_layout.sass */
|
/* line 60, ../../../app/stylesheets/_layout.sass */
|
||||||
h3 {
|
h3 {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 62, ../../../app/stylesheets/_layout.sass */
|
/* line 65, ../../../app/stylesheets/_layout.sass */
|
||||||
.inline-image, body.pets-bulk #bulk-pets-form ul img {
|
.inline-image, body.pets-bulk #bulk-pets-form ul img {
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main */
|
/* Main */
|
||||||
/* line 70, ../../../app/stylesheets/_layout.sass */
|
/* line 73, ../../../app/stylesheets/_layout.sass */
|
||||||
#container {
|
#container {
|
||||||
margin: 1em auto;
|
margin: 1em auto;
|
||||||
padding-top: 3em;
|
padding-top: 3em;
|
||||||
|
@ -91,12 +94,12 @@ h3 {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 76, ../../../app/stylesheets/_layout.sass */
|
/* line 79, ../../../app/stylesheets/_layout.sass */
|
||||||
input, button, select, label {
|
input, button, select, label {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 79, ../../../app/stylesheets/_layout.sass */
|
/* line 82, ../../../app/stylesheets/_layout.sass */
|
||||||
input[type=text], body.pets-bulk #bulk-pets-form textarea, input[type=password], input[type=search], input[type=number], select, textarea {
|
input[type=text], body.pets-bulk #bulk-pets-form textarea, input[type=password], input[type=search], input[type=number], select, textarea {
|
||||||
-moz-border-radius: 3px;
|
-moz-border-radius: 3px;
|
||||||
-webkit-border-radius: 3px;
|
-webkit-border-radius: 3px;
|
||||||
|
@ -105,17 +108,17 @@ input[type=text], body.pets-bulk #bulk-pets-form textarea, input[type=password],
|
||||||
color: #448844;
|
color: #448844;
|
||||||
padding: 0.25em;
|
padding: 0.25em;
|
||||||
}
|
}
|
||||||
/* line 85, ../../../app/stylesheets/_layout.sass */
|
/* line 88, ../../../app/stylesheets/_layout.sass */
|
||||||
input[type=text]:focus, body.pets-bulk #bulk-pets-form textarea:focus, input[type=text]:active, body.pets-bulk #bulk-pets-form textarea:active, input[type=password]:focus, input[type=password]:active, input[type=search]:focus, input[type=search]:active, input[type=number]:focus, input[type=number]:active, select:focus, select:active, textarea:focus, textarea:active {
|
input[type=text]:focus, body.pets-bulk #bulk-pets-form textarea:focus, input[type=text]:active, body.pets-bulk #bulk-pets-form textarea:active, input[type=password]:focus, input[type=password]:active, input[type=search]:focus, input[type=search]:active, input[type=number]:focus, input[type=number]:active, select:focus, select:active, textarea:focus, textarea:active {
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 88, ../../../app/stylesheets/_layout.sass */
|
/* line 91, ../../../app/stylesheets/_layout.sass */
|
||||||
textarea {
|
textarea {
|
||||||
font: inherit;
|
font: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 91, ../../../app/stylesheets/_layout.sass */
|
/* line 94, ../../../app/stylesheets/_layout.sass */
|
||||||
a.button, input[type=submit], button {
|
a.button, input[type=submit], button {
|
||||||
/* http://www.zurb.com/blog_uploads/0000/0617/buttons-03.html */
|
/* http://www.zurb.com/blog_uploads/0000/0617/buttons-03.html */
|
||||||
-moz-border-radius: 5px;
|
-moz-border-radius: 5px;
|
||||||
|
@ -146,7 +149,7 @@ a.button:hover, input[type=submit]:hover, button:hover {
|
||||||
a.button:active, input[type=submit]:active, button:active {
|
a.button:active, input[type=submit]:active, button:active {
|
||||||
top: 1px;
|
top: 1px;
|
||||||
}
|
}
|
||||||
/* line 93, ../../../app/stylesheets/_layout.sass */
|
/* line 96, ../../../app/stylesheets/_layout.sass */
|
||||||
a.button.loud, input[type=submit].loud, button.loud {
|
a.button.loud, input[type=submit].loud, button.loud {
|
||||||
background: #ff5c00 url('/images/alert-overlay.png?1344550430') repeat-x;
|
background: #ff5c00 url('/images/alert-overlay.png?1344550430') repeat-x;
|
||||||
font-size: 125%;
|
font-size: 125%;
|
||||||
|
@ -157,21 +160,21 @@ a.button.loud:hover, input[type=submit].loud:hover, button.loud:hover {
|
||||||
background-color: #ee4b00;
|
background-color: #ee4b00;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 96, ../../../app/stylesheets/_layout.sass */
|
/* line 99, ../../../app/stylesheets/_layout.sass */
|
||||||
ul.buttons {
|
ul.buttons {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
/* line 98, ../../../app/stylesheets/_layout.sass */
|
/* line 101, ../../../app/stylesheets/_layout.sass */
|
||||||
ul.buttons li {
|
ul.buttons li {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0 0.5em;
|
margin: 0 0.5em;
|
||||||
}
|
}
|
||||||
/* line 101, ../../../app/stylesheets/_layout.sass */
|
/* line 104, ../../../app/stylesheets/_layout.sass */
|
||||||
ul.buttons li, ul.buttons li form {
|
ul.buttons li, ul.buttons li form {
|
||||||
display: inline;
|
display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 104, ../../../app/stylesheets/_layout.sass */
|
/* line 107, ../../../app/stylesheets/_layout.sass */
|
||||||
#footer {
|
#footer {
|
||||||
clear: both;
|
clear: both;
|
||||||
font-size: 75%;
|
font-size: 75%;
|
||||||
|
@ -179,69 +182,69 @@ ul.buttons li, ul.buttons li form {
|
||||||
padding-top: 2em;
|
padding-top: 2em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
/* line 110, ../../../app/stylesheets/_layout.sass */
|
/* line 113, ../../../app/stylesheets/_layout.sass */
|
||||||
#footer ul, #footer div {
|
#footer ul, #footer div {
|
||||||
display: inline;
|
display: inline;
|
||||||
margin: 0 1em;
|
margin: 0 1em;
|
||||||
}
|
}
|
||||||
/* line 113, ../../../app/stylesheets/_layout.sass */
|
/* line 116, ../../../app/stylesheets/_layout.sass */
|
||||||
#footer li, #footer div ul {
|
#footer li, #footer div ul {
|
||||||
display: inline;
|
display: inline;
|
||||||
margin: 0 0.5em;
|
margin: 0 0.5em;
|
||||||
}
|
}
|
||||||
/* line 116, ../../../app/stylesheets/_layout.sass */
|
/* line 119, ../../../app/stylesheets/_layout.sass */
|
||||||
#footer #locale-form {
|
#footer #locale-form {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 119, ../../../app/stylesheets/_layout.sass */
|
/* line 122, ../../../app/stylesheets/_layout.sass */
|
||||||
.success, .alert, .warning {
|
.success, .alert, .warning {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
padding: 0.25em 0.5em;
|
padding: 0.25em 0.5em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 124, ../../../app/stylesheets/_layout.sass */
|
/* line 127, ../../../app/stylesheets/_layout.sass */
|
||||||
.success {
|
.success {
|
||||||
background: #e6efc2;
|
background: #e6efc2;
|
||||||
border: 1px solid #c6d880;
|
border: 1px solid #c6d880;
|
||||||
color: #264409;
|
color: #264409;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 127, ../../../app/stylesheets/_layout.sass */
|
/* line 130, ../../../app/stylesheets/_layout.sass */
|
||||||
.alert {
|
.alert {
|
||||||
background: #fbe3e4;
|
background: #fbe3e4;
|
||||||
border: 1px solid #fbc2c4;
|
border: 1px solid #fbc2c4;
|
||||||
color: #8a1f11;
|
color: #8a1f11;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 130, ../../../app/stylesheets/_layout.sass */
|
/* line 133, ../../../app/stylesheets/_layout.sass */
|
||||||
.warning {
|
.warning {
|
||||||
background: #fff6bf;
|
background: #fff6bf;
|
||||||
border: 1px solid #ffd324;
|
border: 1px solid #ffd324;
|
||||||
color: #514721;
|
color: #514721;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 133, ../../../app/stylesheets/_layout.sass */
|
/* line 136, ../../../app/stylesheets/_layout.sass */
|
||||||
#userbar {
|
#userbar {
|
||||||
font-family: Delicious, Helvetica, Arial, Verdana, sans-serif;
|
font-family: Delicious, Helvetica, Arial, Verdana, sans-serif;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
/* line 138, ../../../app/stylesheets/_layout.sass */
|
/* line 141, ../../../app/stylesheets/_layout.sass */
|
||||||
#userbar > * {
|
#userbar > * {
|
||||||
display: inline;
|
display: inline;
|
||||||
margin: 0 0.25em;
|
margin: 0 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 142, ../../../app/stylesheets/_layout.sass */
|
/* line 145, ../../../app/stylesheets/_layout.sass */
|
||||||
#userbar-image-mode {
|
#userbar-image-mode {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
/* line 146, ../../../app/stylesheets/_layout.sass */
|
/* line 149, ../../../app/stylesheets/_layout.sass */
|
||||||
#userbar-image-mode img {
|
#userbar-image-mode img {
|
||||||
bottom: -2px;
|
bottom: -2px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
@ -249,25 +252,25 @@ ul.buttons li, ul.buttons li form {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 149, ../../../app/stylesheets/_layout.sass */
|
/* line 152, ../../../app/stylesheets/_layout.sass */
|
||||||
#userbar-log-in {
|
#userbar-log-in {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
/* line 151, ../../../app/stylesheets/_layout.sass */
|
/* line 154, ../../../app/stylesheets/_layout.sass */
|
||||||
#userbar-log-in img {
|
#userbar-log-in img {
|
||||||
margin-bottom: -4px;
|
margin-bottom: -4px;
|
||||||
margin-right: 0.25em;
|
margin-right: 0.25em;
|
||||||
}
|
}
|
||||||
/* line 155, ../../../app/stylesheets/_layout.sass */
|
/* line 158, ../../../app/stylesheets/_layout.sass */
|
||||||
#userbar-log-in span {
|
#userbar-log-in span {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
/* line 157, ../../../app/stylesheets/_layout.sass */
|
/* line 160, ../../../app/stylesheets/_layout.sass */
|
||||||
#userbar-log-in:hover span {
|
#userbar-log-in:hover span {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 160, ../../../app/stylesheets/_layout.sass */
|
/* line 163, ../../../app/stylesheets/_layout.sass */
|
||||||
.object {
|
.object {
|
||||||
display: -moz-inline-box;
|
display: -moz-inline-box;
|
||||||
-moz-box-orient: vertical;
|
-moz-box-orient: vertical;
|
||||||
|
@ -282,32 +285,32 @@ ul.buttons li, ul.buttons li form {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
/* line 168, ../../../app/stylesheets/_layout.sass */
|
/* line 171, ../../../app/stylesheets/_layout.sass */
|
||||||
.object a {
|
.object a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
/* line 170, ../../../app/stylesheets/_layout.sass */
|
/* line 173, ../../../app/stylesheets/_layout.sass */
|
||||||
.object a img {
|
.object a img {
|
||||||
-moz-opacity: 0.75;
|
-moz-opacity: 0.75;
|
||||||
-webkit-opacity: 0.75;
|
-webkit-opacity: 0.75;
|
||||||
-o-opacity: 0.75;
|
-o-opacity: 0.75;
|
||||||
-khtml-opacity: 0.75;
|
-khtml-opacity: 0.75;
|
||||||
}
|
}
|
||||||
/* line 172, ../../../app/stylesheets/_layout.sass */
|
/* line 175, ../../../app/stylesheets/_layout.sass */
|
||||||
.object img {
|
.object img {
|
||||||
display: block;
|
display: block;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
}
|
}
|
||||||
/* line 177, ../../../app/stylesheets/_layout.sass */
|
/* line 180, ../../../app/stylesheets/_layout.sass */
|
||||||
.object:hover img, .object a:hover img {
|
.object:hover img, .object a:hover img {
|
||||||
-moz-opacity: 1;
|
-moz-opacity: 1;
|
||||||
-webkit-opacity: 1;
|
-webkit-opacity: 1;
|
||||||
-o-opacity: 1;
|
-o-opacity: 1;
|
||||||
-khtml-opacity: 1;
|
-khtml-opacity: 1;
|
||||||
}
|
}
|
||||||
/* line 183, ../../../app/stylesheets/_layout.sass */
|
/* line 186, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .nc-icon, .object .closeted-icons {
|
.object .nc-icon, .object .closeted-icons {
|
||||||
-moz-opacity: 1;
|
-moz-opacity: 1;
|
||||||
-webkit-opacity: 1;
|
-webkit-opacity: 1;
|
||||||
|
@ -318,7 +321,7 @@ ul.buttons li, ul.buttons li form {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 64px;
|
top: 64px;
|
||||||
}
|
}
|
||||||
/* line 189, ../../../app/stylesheets/_layout.sass */
|
/* line 192, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .nc-icon:hover, .object .closeted-icons:hover {
|
.object .nc-icon:hover, .object .closeted-icons:hover {
|
||||||
-moz-opacity: 0.5;
|
-moz-opacity: 0.5;
|
||||||
-webkit-opacity: 0.5;
|
-webkit-opacity: 0.5;
|
||||||
|
@ -326,32 +329,32 @@ ul.buttons li, ul.buttons li form {
|
||||||
-khtml-opacity: 0.5;
|
-khtml-opacity: 0.5;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
/* line 193, ../../../app/stylesheets/_layout.sass */
|
/* line 196, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .nc-icon, .object .closeted-icons img {
|
.object .nc-icon, .object .closeted-icons img {
|
||||||
display: inline;
|
display: inline;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
}
|
}
|
||||||
/* line 198, ../../../app/stylesheets/_layout.sass */
|
/* line 201, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .nc-icon {
|
.object .nc-icon {
|
||||||
right: 18px;
|
right: 18px;
|
||||||
}
|
}
|
||||||
/* line 202, ../../../app/stylesheets/_layout.sass */
|
/* line 205, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .closeted-icons {
|
.object .closeted-icons {
|
||||||
left: 18px;
|
left: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 205, ../../../app/stylesheets/_layout.sass */
|
/* line 208, ../../../app/stylesheets/_layout.sass */
|
||||||
dt {
|
dt {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 208, ../../../app/stylesheets/_layout.sass */
|
/* line 211, ../../../app/stylesheets/_layout.sass */
|
||||||
dd {
|
dd {
|
||||||
margin: 0 0 1.5em 1em;
|
margin: 0 0 1.5em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 211, ../../../app/stylesheets/_layout.sass */
|
/* line 214, ../../../app/stylesheets/_layout.sass */
|
||||||
#home-link {
|
#home-link {
|
||||||
font-family: Delicious, Helvetica, Arial, Verdana, sans-serif;
|
font-family: Delicious, Helvetica, Arial, Verdana, sans-serif;
|
||||||
font-size: 175%;
|
font-size: 175%;
|
||||||
|
@ -362,21 +365,21 @@ dd {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
/* line 221, ../../../app/stylesheets/_layout.sass */
|
/* line 224, ../../../app/stylesheets/_layout.sass */
|
||||||
#home-link:hover {
|
#home-link:hover {
|
||||||
background: #eeffee;
|
background: #eeffee;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
/* line 224, ../../../app/stylesheets/_layout.sass */
|
/* line 227, ../../../app/stylesheets/_layout.sass */
|
||||||
#home-link span:before {
|
#home-link span:before {
|
||||||
content: "<< ";
|
content: "<< ";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 228, ../../../app/stylesheets/_layout.sass */
|
/* line 231, ../../../app/stylesheets/_layout.sass */
|
||||||
.pagination a, .pagination span {
|
.pagination a, .pagination span {
|
||||||
margin: 0 0.5em;
|
margin: 0 0.5em;
|
||||||
}
|
}
|
||||||
/* line 230, ../../../app/stylesheets/_layout.sass */
|
/* line 233, ../../../app/stylesheets/_layout.sass */
|
||||||
.pagination .current {
|
.pagination .current {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
@ -400,34 +403,6 @@ dd {
|
||||||
src: local("Delicious"), url('/fonts/Delicious-Italic.otf');
|
src: local("Delicious"), url('/fonts/Delicious-Italic.otf');
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Droid Serif";
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
src: local("Droid Serif"), url("http://themes.googleusercontent.com/font?kit=70P0G8gxVDIV6F9om0DsKg") format("truetype");
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Droid Serif";
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: bold;
|
|
||||||
src: local("Droid Serif"), url("http://themes.googleusercontent.com/font?kit=QQt14e8dY39u-eYBZmppwf5Jgr8ufe5A6KahQF76Xmg") format("truetype");
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Droid Sans";
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
src: local("Droid Sans"), url("http://themes.googleusercontent.com/font?kit=POVDFY-UUf0WFR9DIMCU8g") format("truetype");
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: "Calligraffitti";
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
src: local("Calligraffiti"), url("http://themes.googleusercontent.com/font?kit=vLVN2Y-z65rVu1R7lWdvyKIZAuDcNtpCWuPSaIR0Ie8") format("woff");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* line 2, ../../../app/stylesheets/partials/_jquery.jgrowl.sass */
|
/* line 2, ../../../app/stylesheets/partials/_jquery.jgrowl.sass */
|
||||||
div.jGrowl {
|
div.jGrowl {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
BIN
vendor/cache/addressable-2.2.6.gem
vendored
BIN
vendor/cache/addressable-2.2.6.gem
vendored
Binary file not shown.
BIN
vendor/cache/addressable-2.3.2.gem
vendored
Normal file
BIN
vendor/cache/addressable-2.3.2.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/bullet-4.1.5.gem
vendored
BIN
vendor/cache/bullet-4.1.5.gem
vendored
Binary file not shown.
BIN
vendor/cache/bullet-4.1.6.gem
vendored
Normal file
BIN
vendor/cache/bullet-4.1.6.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/closure-compiler-1.1.4.gem
vendored
BIN
vendor/cache/closure-compiler-1.1.4.gem
vendored
Binary file not shown.
BIN
vendor/cache/closure-compiler-1.1.8.gem
vendored
Normal file
BIN
vendor/cache/closure-compiler-1.1.8.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/dye-0.1.4.gem
vendored
Normal file
BIN
vendor/cache/dye-0.1.4.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/em-socksify-0.1.0.gem
vendored
BIN
vendor/cache/em-socksify-0.1.0.gem
vendored
Binary file not shown.
BIN
vendor/cache/em-socksify-0.2.1.gem
vendored
Normal file
BIN
vendor/cache/em-socksify-0.2.1.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/excon-0.16.10.gem
vendored
Normal file
BIN
vendor/cache/excon-0.16.10.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/excon-0.9.6.gem
vendored
BIN
vendor/cache/excon-0.9.6.gem
vendored
Binary file not shown.
BIN
vendor/cache/factory_girl-2.3.2.gem
vendored
BIN
vendor/cache/factory_girl-2.3.2.gem
vendored
Binary file not shown.
BIN
vendor/cache/factory_girl-2.6.4.gem
vendored
Normal file
BIN
vendor/cache/factory_girl-2.6.4.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/factory_girl_rails-1.4.0.gem
vendored
BIN
vendor/cache/factory_girl_rails-1.4.0.gem
vendored
Binary file not shown.
BIN
vendor/cache/factory_girl_rails-1.7.0.gem
vendored
Normal file
BIN
vendor/cache/factory_girl_rails-1.7.0.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/fog-1.1.2.gem
vendored
BIN
vendor/cache/fog-1.1.2.gem
vendored
Binary file not shown.
BIN
vendor/cache/fog-1.8.0.gem
vendored
Normal file
BIN
vendor/cache/fog-1.8.0.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/formatador-0.2.1.gem
vendored
BIN
vendor/cache/formatador-0.2.1.gem
vendored
Binary file not shown.
BIN
vendor/cache/formatador-0.2.4.gem
vendored
Normal file
BIN
vendor/cache/formatador-0.2.4.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/globalize3-0.3.0.gem
vendored
Normal file
BIN
vendor/cache/globalize3-0.3.0.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/msgpack-0.4.6.gem
vendored
BIN
vendor/cache/msgpack-0.4.6.gem
vendored
Binary file not shown.
BIN
vendor/cache/msgpack-0.4.7.gem
vendored
Normal file
BIN
vendor/cache/msgpack-0.4.7.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/multi_json-1.0.4.gem
vendored
BIN
vendor/cache/multi_json-1.0.4.gem
vendored
Binary file not shown.
BIN
vendor/cache/multi_json-1.3.7.gem
vendored
Normal file
BIN
vendor/cache/multi_json-1.3.7.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/mysql2-0.2.18.gem
vendored
Normal file
BIN
vendor/cache/mysql2-0.2.18.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/mysql2-0.2.6.gem
vendored
BIN
vendor/cache/mysql2-0.2.6.gem
vendored
Binary file not shown.
BIN
vendor/cache/net-ssh-2.3.0.gem
vendored
BIN
vendor/cache/net-ssh-2.3.0.gem
vendored
Binary file not shown.
BIN
vendor/cache/net-ssh-2.6.3.gem
vendored
Normal file
BIN
vendor/cache/net-ssh-2.6.3.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/newrelic_rpm-3.5.3.25.gem
vendored
BIN
vendor/cache/newrelic_rpm-3.5.3.25.gem
vendored
Binary file not shown.
BIN
vendor/cache/newrelic_rpm-3.5.5.38.gem
vendored
Normal file
BIN
vendor/cache/newrelic_rpm-3.5.5.38.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/nokogiri-1.5.3.gem
vendored
BIN
vendor/cache/nokogiri-1.5.3.gem
vendored
Binary file not shown.
BIN
vendor/cache/nokogiri-1.5.6.gem
vendored
Normal file
BIN
vendor/cache/nokogiri-1.5.6.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/paper_trail-2.7.0.gem
vendored
Normal file
BIN
vendor/cache/paper_trail-2.7.0.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/parallel-0.5.17.gem
vendored
BIN
vendor/cache/parallel-0.5.17.gem
vendored
Binary file not shown.
BIN
vendor/cache/parallel-0.5.21.gem
vendored
Normal file
BIN
vendor/cache/parallel-0.5.21.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/patron-0.4.18.gem
vendored
Normal file
BIN
vendor/cache/patron-0.4.18.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/progressbar-0.11.0.gem
vendored
Normal file
BIN
vendor/cache/progressbar-0.11.0.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/prompter-0.1.5.gem
vendored
Normal file
BIN
vendor/cache/prompter-0.1.5.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/rack-1.2.6.gem
vendored
BIN
vendor/cache/rack-1.2.6.gem
vendored
Binary file not shown.
BIN
vendor/cache/rack-1.2.7.gem
vendored
Normal file
BIN
vendor/cache/rack-1.2.7.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/redis-2.2.2.gem
vendored
BIN
vendor/cache/redis-2.2.2.gem
vendored
Binary file not shown.
BIN
vendor/cache/redis-3.0.2.gem
vendored
Normal file
BIN
vendor/cache/redis-3.0.2.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/redis-namespace-1.1.0.gem
vendored
BIN
vendor/cache/redis-namespace-1.1.0.gem
vendored
Binary file not shown.
BIN
vendor/cache/redis-namespace-1.2.1.gem
vendored
Normal file
BIN
vendor/cache/redis-namespace-1.2.1.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/rufus-scheduler-2.0.16.gem
vendored
BIN
vendor/cache/rufus-scheduler-2.0.16.gem
vendored
Binary file not shown.
BIN
vendor/cache/rufus-scheduler-2.0.17.gem
vendored
Normal file
BIN
vendor/cache/rufus-scheduler-2.0.17.gem
vendored
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue