Permalink
Browse files

WIP fog integration

  • Loading branch information...
1 parent 36fc5b2 commit 4047d322969276f6c993ceb7bc6e6a3e7f0a77cd @geemus geemus committed with jyurek Nov 29, 2010
Showing with 225 additions and 2 deletions.
  1. +1 −0 Gemfile
  2. +16 −0 Gemfile.lock
  3. +1 −0 lib/paperclip/storage.rb
  4. +98 −0 lib/paperclip/storage/fog.rb
  5. +2 −2 paperclip.gemspec
  6. +107 −0 test/fog_test.rb
View
@@ -6,3 +6,4 @@ gem "ruby-debug"
gem "aws-s3", :require => "aws/s3"
gem "sqlite3-ruby", "~>1.3.0"
gem "appraisal"
+gem 'fog'
View
@@ -10,16 +10,31 @@ GEM
xml-simple
builder (3.0.0)
columnize (0.3.2)
+ excon (0.5.2)
+ fog (0.5.2)
+ builder
+ excon (>= 0.5.2)
+ formatador (>= 0.0.16)
+ json
+ mime-types
+ net-ssh (>= 2.0.23)
+ nokogiri (>= 1.4.4)
+ ruby-hmac
+ formatador (0.0.16)
+ json (1.5.1)
linecache (0.43)
mime-types (1.16)
mocha (0.9.9)
rake
+ net-ssh (2.1.0)
+ nokogiri (1.4.4)
rake (0.8.7)
ruby-debug (0.10.4)
columnize (>= 0.1)
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
+ ruby-hmac (0.4.0)
shoulda (2.11.3)
sqlite3-ruby (1.3.2)
xml-simple (1.0.12)
@@ -30,6 +45,7 @@ PLATFORMS
DEPENDENCIES
appraisal
aws-s3
+ fog
mocha
rake
ruby-debug
@@ -1,2 +1,3 @@
require "paperclip/storage/filesystem"
+require "paperclip/storage/fog"
require "paperclip/storage/s3"
@@ -0,0 +1,98 @@
+module Paperclip
+ module Storage
+
+ module Fog
+ def self.extended base
+ begin
+ require 'fog'
+ rescue LoadError => e
+ e.message << " (You may need to install the fog gem)"
+ raise e
+ end
+
+ base.instance_eval do
+ @fog_directory = @options[:fog_directory]
+ @fog_credentials = @options[:fog_credentials]
+ @fog_host = @options[:fog_host]
+ @fog_public = @options[:fog_public]
+
+ @url = ':fog_public_url'
+ Paperclip.interpolates(:fog_public_url) do |attachment, style|
+ attachment.public_url(style)
+ end
+ end
+ end
+
+ def exists?(style = default_style)
+ if original_filename
+ !!directory.files.head(path(style))
+ else
+ false
+ end
+ end
+
+ def flush_writes
+ for style, file in @queued_for_write do
+ log("saving #{path(style)}")
+ directory.files.create(
+ :body => file,
+ :key => path(style),
+ :public => @fog_public
+ )
+ end
+ @queued_for_write = {}
+ end
+
+ def flush_deletes
+ for path in @queued_for_delete do
+ log("deleting #{path}")
+ directory.files.new(:key => path).destroy
+ end
+ @queued_for_delete = []
+ end
+
+ # Returns representation of the data of the file assigned to the given
+ # style, in the format most representative of the current storage.
+ def to_file(style = default_style)
+ if @queued_for_write[style]
+ @queued_for_write[style]
+ else
+ body = directory.files.get(path(style)).body
+ filename = path(style)
+ extname = File.extname(filename)
+ basename = File.basename(filename, extname)
+ file = Tempfile.new([basename, extname])
+ file.binmode
+ file.write(body)
+ file.rewind
+ file
+ end
+ end
+
+ def public_url(style = default_style)
+ if @fog_host
+ "#{@fog_host}/#{path(style)}"
+ else
+ directory.files.new(:key => path(style)).public_url
+ end
+ end
+
+ private
+
+ def connection
+ @connection ||= ::Fog::Storage.new(@fog_credentials)
+ end
+
+ def directory
+ @directory ||= begin
+ connection.directories.get(@fog_directory) || connection.directories.create(
+ :key => @fog_directory,
+ :public => @fog_public
+ )
+ end
+ end
+
+ end
+
+ end
+end
View
@@ -25,8 +25,8 @@ spec = Gem::Specification.new do |s|
s.extra_rdoc_files = Dir["README*"]
s.rdoc_options << '--line-numbers' << '--inline-source'
s.requirements << "ImageMagick"
- s.add_dependency 'activerecord'
- s.add_dependency 'activesupport'
+ s.add_dependency 'activerecord', '~>2.3.0'
+ s.add_dependency 'activesupport', '=2.3.2'
s.add_development_dependency 'shoulda'
s.add_development_dependency 'appraisal'
s.add_development_dependency 'mocha'
View
@@ -0,0 +1,107 @@
+require './test/helper'
+require 'fog'
+
+Fog.mock!
+
+class FogTest < Test::Unit::TestCase
+ context "" do
+
+ setup do
+ @fog_directory = 'papercliptests'
+
+ @credentials = {
+ :provider => 'AWS',
+ :aws_access_key_id => 'ID',
+ :aws_secret_access_key => 'SECRET'
+ }
+
+ @connection = Fog::Storage.new(@credentials)
+
+ rebuild_model(
+ :fog_directory => @fog_directory,
+ :fog_credentials => @credentials,
+ :fog_host => nil,
+ :fog_public => true,
+ :path => ":attachment/:basename.:extension",
+ :storage => :fog
+ )
+ end
+
+ should "be extended by the Fog module" do
+ assert Dummy.new.avatar.is_a?(Paperclip::Storage::Fog)
+ end
+
+ context "when assigned" do
+ setup do
+ @file = File.new(File.join(File.dirname(__FILE__), 'fixtures', '5k.png'), 'rb')
+ @dummy = Dummy.new
+ @dummy.avatar = @file
+ end
+
+ teardown do
+ @file.close
+ directory = @connection.directories.new(:key => @fog_directory)
+ directory.files.each {|file| file.destroy}
+ directory.destroy
+ end
+
+ context "without a bucket" do
+ should "succeed" do
+ assert @dummy.save
+ end
+ end
+
+ context "with a bucket" do
+ setup do
+ @connection.directories.create(:key => @fog_directory)
+ end
+
+ should "succeed" do
+ assert @dummy.save
+ end
+ end
+
+ context "without a fog_host" do
+ setup do
+ rebuild_model(
+ :fog_directory => @fog_directory,
+ :fog_credentials => @credentials,
+ :fog_host => nil,
+ :fog_public => true,
+ :path => ":attachment/:basename.:extension",
+ :storage => :fog
+ )
+ @dummy = Dummy.new
+ @dummy.avatar = StringIO.new('.')
+ @dummy.save
+ end
+
+ should "provide a public url" do
+ assert !@dummy.avatar.url.nil?
+ end
+ end
+
+ context "with a fog_host" do
+ setup do
+ rebuild_model(
+ :fog_directory => @fog_directory,
+ :fog_credentials => @credentials,
+ :fog_host => 'http://example.com',
+ :fog_public => true,
+ :path => ":attachment/:basename.:extension",
+ :storage => :fog
+ )
+ @dummy = Dummy.new
+ @dummy.avatar = StringIO.new('.')
+ @dummy.save
+ end
+
+ should "provide a public url" do
+ assert @dummy.avatar.url =~ /^http:\/\/example\.com\/avatars\/stringio\.txt\?\d*$/
+ end
+ end
+
+ end
+
+ end
+end

0 comments on commit 4047d32

Please sign in to comment.