forked from OpenNeo/impress
outfit thumbnails initial commit
This commit is contained in:
parent
22cfff66e9
commit
220aca9311
18 changed files with 139 additions and 0 deletions
5
Gemfile
5
Gemfile
|
@ -41,6 +41,11 @@ gem 'newrelic_rpm'
|
||||||
|
|
||||||
gem 'neopets', :git => 'git://github.com/matchu/neopets.git'
|
gem 'neopets', :git => 'git://github.com/matchu/neopets.git'
|
||||||
|
|
||||||
|
gem "mini_magick", "~> 3.4"
|
||||||
|
|
||||||
|
gem "fog", "~> 1.1.2"
|
||||||
|
gem "carrierwave", "~> 0.5.8"
|
||||||
|
|
||||||
group :development_async do
|
group :development_async do
|
||||||
# async wrappers
|
# async wrappers
|
||||||
gem 'eventmachine', :git => 'git://github.com/eventmachine/eventmachine.git'
|
gem 'eventmachine', :git => 'git://github.com/eventmachine/eventmachine.git'
|
||||||
|
|
24
Gemfile.lock
24
Gemfile.lock
|
@ -87,6 +87,8 @@ GEM
|
||||||
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)
|
||||||
|
carrierwave (0.5.8)
|
||||||
|
activesupport (~> 3.0)
|
||||||
character-encodings (0.4.1)
|
character-encodings (0.4.1)
|
||||||
closure-compiler (1.1.4)
|
closure-compiler (1.1.4)
|
||||||
compass (0.10.6)
|
compass (0.10.6)
|
||||||
|
@ -100,11 +102,23 @@ GEM
|
||||||
eventmachine
|
eventmachine
|
||||||
erubis (2.6.6)
|
erubis (2.6.6)
|
||||||
abstract (>= 1.0.0)
|
abstract (>= 1.0.0)
|
||||||
|
excon (0.9.6)
|
||||||
factory_girl (2.3.2)
|
factory_girl (2.3.2)
|
||||||
activesupport
|
activesupport
|
||||||
factory_girl_rails (1.4.0)
|
factory_girl_rails (1.4.0)
|
||||||
factory_girl (~> 2.3.0)
|
factory_girl (~> 2.3.0)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
|
fog (1.1.2)
|
||||||
|
builder
|
||||||
|
excon (~> 0.9.0)
|
||||||
|
formatador (~> 0.2.0)
|
||||||
|
mime-types
|
||||||
|
multi_json (~> 1.0.3)
|
||||||
|
net-scp (~> 1.0.4)
|
||||||
|
net-ssh (>= 2.1.3)
|
||||||
|
nokogiri (~> 1.5.0)
|
||||||
|
ruby-hmac
|
||||||
|
formatador (0.2.1)
|
||||||
haml (3.0.25)
|
haml (3.0.25)
|
||||||
hoptoad_notifier (2.4.11)
|
hoptoad_notifier (2.4.11)
|
||||||
activesupport
|
activesupport
|
||||||
|
@ -122,8 +136,14 @@ GEM
|
||||||
treetop (~> 1.4.8)
|
treetop (~> 1.4.8)
|
||||||
memcache-client (1.8.5)
|
memcache-client (1.8.5)
|
||||||
mime-types (1.17.2)
|
mime-types (1.17.2)
|
||||||
|
mini_magick (3.4)
|
||||||
|
subexec (~> 0.2.1)
|
||||||
msgpack (0.4.6)
|
msgpack (0.4.6)
|
||||||
|
multi_json (1.0.4)
|
||||||
mysql2 (0.2.6)
|
mysql2 (0.2.6)
|
||||||
|
net-scp (1.0.4)
|
||||||
|
net-ssh (>= 1.99.1)
|
||||||
|
net-ssh (2.3.0)
|
||||||
newrelic_rpm (3.3.3)
|
newrelic_rpm (3.3.3)
|
||||||
nokogiri (1.5.3)
|
nokogiri (1.5.3)
|
||||||
open4 (1.3.0)
|
open4 (1.3.0)
|
||||||
|
@ -189,6 +209,7 @@ GEM
|
||||||
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)
|
||||||
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)
|
||||||
|
@ -213,6 +234,7 @@ PLATFORMS
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
RocketAMF!
|
RocketAMF!
|
||||||
addressable
|
addressable
|
||||||
|
carrierwave (~> 0.5.8)
|
||||||
character-encodings (~> 0.4.1)
|
character-encodings (~> 0.4.1)
|
||||||
compass (~> 0.10.1)
|
compass (~> 0.10.1)
|
||||||
devise (~> 1.1.5)
|
devise (~> 1.1.5)
|
||||||
|
@ -221,10 +243,12 @@ DEPENDENCIES
|
||||||
em-synchrony!
|
em-synchrony!
|
||||||
eventmachine!
|
eventmachine!
|
||||||
factory_girl_rails (~> 1.0)
|
factory_girl_rails (~> 1.0)
|
||||||
|
fog (~> 1.1.2)
|
||||||
haml (~> 3.0.18)
|
haml (~> 3.0.18)
|
||||||
hoptoad_notifier
|
hoptoad_notifier
|
||||||
jammit (~> 0.5.3)
|
jammit (~> 0.5.3)
|
||||||
memcache-client (~> 1.8.5)
|
memcache-client (~> 1.8.5)
|
||||||
|
mini_magick (~> 3.4)
|
||||||
msgpack (~> 0.4.3)
|
msgpack (~> 0.4.3)
|
||||||
mysql2 (< 0.3)
|
mysql2 (< 0.3)
|
||||||
mysqlplus!
|
mysqlplus!
|
||||||
|
|
|
@ -13,6 +13,8 @@ class Outfit < ActiveRecord::Base
|
||||||
|
|
||||||
scope :wardrobe_order, order('starred DESC', :name)
|
scope :wardrobe_order, order('starred DESC', :name)
|
||||||
|
|
||||||
|
mount_uploader :image, OutfitImageUploader
|
||||||
|
|
||||||
def as_json(more_options={})
|
def as_json(more_options={})
|
||||||
serializable_hash :only => [:id, :name, :pet_state_id, :starred],
|
serializable_hash :only => [:id, :name, :pet_state_id, :starred],
|
||||||
:methods => [:color_id, :species_id, :worn_and_unworn_item_ids]
|
:methods => [:color_id, :species_id, :worn_and_unworn_item_ids]
|
||||||
|
@ -71,6 +73,22 @@ class Outfit < ActiveRecord::Base
|
||||||
visible_assets.sort { |a, b| a.zone.depth <=> b.zone.depth }
|
visible_assets.sort { |a, b| a.zone.depth <=> b.zone.depth }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Creates and writes the thumbnail images for this outfit. (Writes to file in
|
||||||
|
# development, S3 in production.) Runs #save! on the record, so any other
|
||||||
|
# changes will also be saved.
|
||||||
|
def write_image!
|
||||||
|
Tempfile.open(['outfit_image', '.png']) do |image|
|
||||||
|
create_image! image
|
||||||
|
self.image = image
|
||||||
|
save!
|
||||||
|
end
|
||||||
|
self.image
|
||||||
|
end
|
||||||
|
|
||||||
|
def s3_key(size)
|
||||||
|
URI.encode("#{id}/#{size.join 'x'}.png")
|
||||||
|
end
|
||||||
|
|
||||||
def self.build_for_user(user, params)
|
def self.build_for_user(user, params)
|
||||||
Outfit.new.tap do |outfit|
|
Outfit.new.tap do |outfit|
|
||||||
name = params.delete(:name)
|
name = params.delete(:name)
|
||||||
|
@ -87,6 +105,28 @@ class Outfit < ActiveRecord::Base
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
# Creates a 600x600 PNG image of this outfit, writing to the given output
|
||||||
|
# file.
|
||||||
|
def create_image!(output)
|
||||||
|
layers = self.layered_assets
|
||||||
|
base_layer = layers.shift
|
||||||
|
write_temp_swf_asset_image! base_layer, output
|
||||||
|
output.close
|
||||||
|
|
||||||
|
Tempfile.open(['outfit_overlay', '.png']) do |overlay|
|
||||||
|
layers.each do |layer|
|
||||||
|
overlay.open
|
||||||
|
write_temp_swf_asset_image! layer, overlay
|
||||||
|
overlay.close
|
||||||
|
|
||||||
|
previous_image = MiniMagick::Image.open(output.path)
|
||||||
|
overlay_image = MiniMagick::Image.open(overlay.path)
|
||||||
|
output_image = previous_image.composite(overlay_image)
|
||||||
|
output_image.write output.path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def visible_assets
|
def visible_assets
|
||||||
biology_assets = pet_state.swf_assets
|
biology_assets = pet_state.swf_assets
|
||||||
object_assets = SwfAsset.object_assets.
|
object_assets = SwfAsset.object_assets.
|
||||||
|
@ -110,5 +150,15 @@ class Outfit < ActiveRecord::Base
|
||||||
all_assets = biology_assets + object_assets
|
all_assets = biology_assets + object_assets
|
||||||
all_assets.select { |a| (1 << (a.zone_id - 1)) & restricted_zones_mask == 0 }
|
all_assets.select { |a| (1 << (a.zone_id - 1)) & restricted_zones_mask == 0 }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
IMAGE_BASE_SIZE = [600, 600]
|
||||||
|
def write_temp_swf_asset_image!(swf_asset, file)
|
||||||
|
key = swf_asset.s3_key(IMAGE_BASE_SIZE)
|
||||||
|
bucket = SwfAsset::IMAGE_BUCKET
|
||||||
|
data = bucket.get(key)
|
||||||
|
file.binmode # write in binary mode
|
||||||
|
file.truncate(0) # clear the file
|
||||||
|
file.write data # write the new data
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
31
app/models/outfit_image_uploader.rb
Normal file
31
app/models/outfit_image_uploader.rb
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
require 'carrierwave/processing/mime_types'
|
||||||
|
|
||||||
|
class OutfitImageUploader < CarrierWave::Uploader::Base
|
||||||
|
include CarrierWave::MimeTypes
|
||||||
|
include CarrierWave::MiniMagick
|
||||||
|
|
||||||
|
# Settings for S3 storage. Will only be used on production.
|
||||||
|
fog_directory 'impress-outfit-images'
|
||||||
|
fog_attributes 'Cache-Control' => "max-age=#{15.minutes}",
|
||||||
|
'Content-Type' => 'image/png'
|
||||||
|
|
||||||
|
process :set_content_type
|
||||||
|
|
||||||
|
version :medium do
|
||||||
|
process :resize_to_fill => [300, 300]
|
||||||
|
end
|
||||||
|
|
||||||
|
version :small do
|
||||||
|
process :resize_to_fill => [150, 150]
|
||||||
|
end
|
||||||
|
|
||||||
|
def filename
|
||||||
|
"thumb.png"
|
||||||
|
end
|
||||||
|
|
||||||
|
def store_dir
|
||||||
|
partition_id = model.id / 1000
|
||||||
|
partition_dir = "%03d" % partition_id
|
||||||
|
"outfits/#{partition_dir}/#{model.id}"
|
||||||
|
end
|
||||||
|
end
|
20
config/initializers/carrierwave.rb
Normal file
20
config/initializers/carrierwave.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# By default, we'll have CarrierWave use S3 only on production. (Since each
|
||||||
|
# asset image has only One True Image no matter the environment, we'll override
|
||||||
|
# this to use S3 on all environments for those images only.)
|
||||||
|
|
||||||
|
CarrierWave.configure do |config|
|
||||||
|
if Rails.env.production? || true # REMOVE
|
||||||
|
s3_config = YAML.load_file Rails.root.join('config', 'aws_s3.yml')
|
||||||
|
access_key_id = s3_config['access_key_id']
|
||||||
|
secret_access_key = s3_config['secret_access_key']
|
||||||
|
|
||||||
|
config.storage = :fog
|
||||||
|
config.fog_credentials = {
|
||||||
|
:provider => 'AWS',
|
||||||
|
:aws_access_key_id => access_key_id,
|
||||||
|
:aws_secret_access_key => secret_access_key
|
||||||
|
}
|
||||||
|
else
|
||||||
|
config.storage = :file
|
||||||
|
end
|
||||||
|
end
|
9
db/migrate/20120308205324_add_image_to_outfits.rb
Normal file
9
db/migrate/20120308205324_add_image_to_outfits.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
class AddImageToOutfits < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
add_column :outfits, :image, :string
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
remove_column :outfits, :image
|
||||||
|
end
|
||||||
|
end
|
BIN
public/outfits/000/19/medium_thumb.png
Normal file
BIN
public/outfits/000/19/medium_thumb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
BIN
public/outfits/000/19/small_thumb.png
Normal file
BIN
public/outfits/000/19/small_thumb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
public/outfits/000/19/thumb.png
Normal file
BIN
public/outfits/000/19/thumb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
BIN
vendor/cache/carrierwave-0.5.8.gem
vendored
Normal file
BIN
vendor/cache/carrierwave-0.5.8.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/excon-0.9.6.gem
vendored
Normal file
BIN
vendor/cache/excon-0.9.6.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/fog-1.1.2.gem
vendored
Normal file
BIN
vendor/cache/fog-1.1.2.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/formatador-0.2.1.gem
vendored
Normal file
BIN
vendor/cache/formatador-0.2.1.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/mini_magick-3.4.gem
vendored
Normal file
BIN
vendor/cache/mini_magick-3.4.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/multi_json-1.0.4.gem
vendored
Normal file
BIN
vendor/cache/multi_json-1.0.4.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/net-scp-1.0.4.gem
vendored
Normal file
BIN
vendor/cache/net-scp-1.0.4.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/net-ssh-2.3.0.gem
vendored
Normal file
BIN
vendor/cache/net-ssh-2.3.0.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/subexec-0.2.1.gem
vendored
Normal file
BIN
vendor/cache/subexec-0.2.1.gem
vendored
Normal file
Binary file not shown.
Loading…
Reference in a new issue