Commit 532fa71e

mo khan <mo@mokhan.ca>
2014-06-07 14:26:53
add ability to generate urls for different versions of an image.
1 parent b3d5986
app/models/creation.rb
@@ -26,10 +26,6 @@ class Creation < ActiveRecord::Base
     is_restricted == false
   end
 
-  def add_photo(photo)
-    photos.create(:image => photo)
-  end
-
   def is_liked_by(user)
     favorites.where(user: user).any?
   end
app/models/photo.rb
@@ -1,53 +1,75 @@
 class Photo < ActiveRecord::Base
   belongs_to :creation, counter_cache: true, touch: true
-  #mount_uploader :image, PhotoUploader
 
   def watermark
     return '' if creation.nil?
     creation.watermark
   end
 
+  def url_for(version_key, asset_host = ENV['ASSET_HOST'])
+    versions.find { |version| version.for?(version_key) }.url_for(asset_host)
+  end
+
   def is_processed?
     !self.image_processing
   end
 
   def upload(file, blob_storage)
     image = Image.new(file)
-    self.image = self.original_filename = image.filename
+    self.original_filename = File.basename(file)
+    self.image = image.filename
     self.content_type = image.content_type
     self.latitude, self.longitude = image.geolocation
     self.image_processing = nil
     versions.each do |version|
       version.adjust(image)
-      blob_storage.upload(create_key(version.prefix), image.path)
+      blob_storage.upload(version.create_key, image.path)
     end
   end
 
   private
 
-  def create_key(prefix = '')
-    "uploads/photo/image/#{id}/#{prefix}#{original_filename}"
-  end
-
   def versions
-    @versions ||= [OriginalVersion.new, LargeVersion.new, ThumbnailVersion.new]
+    @versions ||= [OriginalVersion.new(self), LargeVersion.new(self), ThumbnailVersion.new(self)]
   end
 
-  class OriginalVersion
-    attr_reader :prefix
+  class Version
+    attr_reader :key, :prefix, :photo
 
-    def initialize
-      @prefix = ''
+    def initialize(photo, key, prefix)
+      @key = key
+      @prefix = prefix
+      @photo = photo
     end
 
-    def adjust(image); end
+    def adjust(image) 
+      fail "Please override with version specific behaviours"
+    end
+
+    def for?(other_key)
+      key == other_key
+    end
+
+    def url_for(asset_host)
+      "#{asset_host}/#{create_key}"
+    end
+
+    def create_key
+      "uploads/photo/image/#{photo.id}/#{prefix}#{photo.image}"
+    end
   end
 
-  class LargeVersion
-    attr_reader :prefix
+  class OriginalVersion < Version
+    def initialize(photo)
+      super(photo, :original, "")
+    end
+
+    def adjust(image); end
+  end
 
-    def initialize
-      @prefix = 'large_'
+  class LargeVersion < Version
+    def initialize(photo)
+      super(photo, :large, "large_")
     end
 
     def adjust(image)
@@ -55,11 +77,9 @@ class Photo < ActiveRecord::Base
     end
   end
 
-  class ThumbnailVersion
-    attr_reader :prefix
-
-    def initialize
-      @prefix = 'thumb_'
+  class ThumbnailVersion < Version
+    def initialize(photo)
+      super(photo, :thumb, "thumb_")
     end
 
     def adjust(image)
app/services/application/handlers/process_photo.rb
@@ -1,5 +1,5 @@
 class ProcessPhoto
-  def initialize(photos, blob_storage = BlobStorage.new)
+  def initialize(photos, blob_storage)
     @photos = photos
     @blob_storage = blob_storage
   end
app/services/application/photo_to_jq_json_mapper.rb
@@ -2,7 +2,8 @@ class PhotoToJQJsonMapper
   def map_from(photo)
     {
       name: photo.read_attribute(:image),
-      url: photo.image.url,
+      #url: photo.image.url,
+      url: photo.url_for(:large),
       thumbnail_url: photo.is_processed? ? photo.image.thumb.url : photo.image.thumb.default_url,
       delete_url: photo.id,
       delete_type: "DELETE"
config/initializers/container.rb
@@ -8,6 +8,7 @@ container.register(:queue) { |c| Delayed::Job }
 container.register(:message_bus) { |c| c.build(MessageBus) }.as_singleton
 container.register(:exif_parser) { |builder| ExifParser.new }
 container.register(:twitter_publisher) { |c| c.build(TwitterPublisher) }.as_singleton
+container.register(:blob_storage) { |builder| BlobStorage.new }
 
 # repositories
 container.register(:cakes) { |builder| Creation }
spec/controllers/my/photos_controller_spec.rb
@@ -32,13 +32,10 @@ module My
     end
 
     describe :delete do
-      let!(:photo) { create(:photo) }
+      let!(:photo) { create(:photo, creation_id: cake.id, image_processing: nil) }
 
       before :each do
-        cake.photos << photo
-        cake.save!
-        photo.update_attribute(:image_processing, nil)
-        delete :destroy, :cake_id => cake.id, :id => photo.id
+        delete :destroy, cake_id: cake.id, id: photo.id
       end
 
       it "returns http success" do
spec/controllers/creations_controller_spec.rb
@@ -5,9 +5,8 @@ describe CreationsController do
   let(:creation){ create(:creation, :user => user) }
 
   before(:each) do
-    photo = File.new(File.join(Rails.root, 'spec/fixtures/images/example.png'))
-    creation.add_photo(photo)
-    creation.photos.first.update_attribute(:image_processing, nil)
+    photo = 'spec/fixtures/images/example.png'
+    creation.photos.create(image: photo, image_processing: nil)
   end
 
   describe :index do
spec/factories/photo.rb
@@ -1,5 +1,5 @@
 FactoryGirl.define do
   factory :photo, class: Photo do
-    image { File.new(File.join(Rails.root, 'spec/fixtures/images/example.png')) }
+    image { 'example.png' }
   end
 end
spec/models/photo_spec.rb
@@ -36,4 +36,25 @@ describe Photo do
       "uploads/photo/image/#{subject.id}/#{prefix}gps.jpg"
     end
   end
+
+  describe "#url_for" do
+    let(:asset_host) { ENV['ASSET_HOST'] }
+
+    before :each do
+      subject.id = rand(100)
+      subject.image = "blah.png"
+    end
+
+    it "returns the url to the large version" do
+      expect(subject.url_for(:large)).to eql("#{asset_host}/uploads/photo/image/#{subject.id}/large_blah.png")
+    end
+
+    it "returns the url for the thumbnail version" do
+      expect(subject.url_for(:thumb)).to eql("#{asset_host}/uploads/photo/image/#{subject.id}/thumb_blah.png")
+    end
+
+    it "returns the url for the original version" do
+      expect(subject.url_for(:original)).to eql("#{asset_host}/uploads/photo/image/#{subject.id}/blah.png")
+    end
+  end
 end