paperclip-cloudfiles 2.3.8.6 → 2.3.10.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -25,6 +25,13 @@ on Gemcutter's gem server.
25
25
 
26
26
  The complete [RDoc](http://rdoc.info/github/minter/paperclip) is online.
27
27
 
28
+ Changes in this repo
29
+ ------------
30
+
31
+ Allowed to refresh images of classes with namespaces. For example:
32
+
33
+ rake paperclip:refresh CLASS='User::Asset'
34
+
28
35
  Requirements
29
36
  ------------
30
37
 
@@ -43,6 +50,10 @@ In development mode, you might add this line to `config/environments/development
43
50
  Installation
44
51
  ------------
45
52
 
53
+ Paperclip is distributed as a gem, which is how it should be used in your app. It's
54
+ technically still installable as a plugin, but that's discouraged, as Rails plays
55
+ well with gems.
56
+
46
57
  Include the gem in your Gemfile:
47
58
 
48
59
  gem "paperclip-cloudfiles", "~> 2.3"
@@ -208,7 +219,8 @@ Testing
208
219
  -------
209
220
 
210
221
  Paperclip provides rspec-compatible matchers for testing attachments. See the
211
- documentation on Paperclip::Shoulda::Matchers for more information.
222
+ documentation on [Paperclip::Shoulda::Matchers](http://rubydoc.info/gems/paperclip/Paperclip/Shoulda/Matchers)
223
+ for more information.
212
224
 
213
225
  Contributing
214
226
  ------------
@@ -39,8 +39,8 @@ require 'paperclip/style'
39
39
  require 'paperclip/attachment'
40
40
  require 'paperclip/storage'
41
41
  require 'paperclip/callback_compatability'
42
- require 'paperclip/command_line'
43
42
  require 'paperclip/railtie'
43
+ require 'cocaine'
44
44
  if defined?(Rails.root) && Rails.root
45
45
  Dir.glob(File.join(File.expand_path(Rails.root), "lib", "paperclip_processors", "*.rb")).each do |processor|
46
46
  require processor
@@ -87,7 +87,7 @@ module Paperclip
87
87
  # symlink them so they are all in the same directory.
88
88
  #
89
89
  # If the command returns with a result code that is not one of the
90
- # expected_outcodes, a PaperclipCommandLineError will be raised. Generally
90
+ # expected_outcodes, a Cocaine::CommandLineError will be raised. Generally
91
91
  # a code of 0 is expected, but a list of codes may be passed if necessary.
92
92
  # These codes should be passed as a hash as the last argument, like so:
93
93
  #
@@ -100,8 +100,8 @@ module Paperclip
100
100
  if options[:image_magick_path]
101
101
  Paperclip.log("[DEPRECATION] :image_magick_path is deprecated and will be removed. Use :command_path instead")
102
102
  end
103
- CommandLine.path = options[:command_path] || options[:image_magick_path]
104
- CommandLine.new(cmd, *params).run
103
+ Cocaine::CommandLine.path = options[:command_path] || options[:image_magick_path]
104
+ Cocaine::CommandLine.new(cmd, *params).run
105
105
  end
106
106
 
107
107
  def processor name #:nodoc:
@@ -114,7 +114,7 @@ module Paperclip
114
114
  end
115
115
 
116
116
  def each_instance_with_attachment(klass, name)
117
- Object.const_get(klass).all.each do |instance|
117
+ class_for(klass).all.each do |instance|
118
118
  yield(instance) if instance.send(:"#{name}?")
119
119
  end
120
120
  end
@@ -132,17 +132,15 @@ module Paperclip
132
132
  def logging? #:nodoc:
133
133
  options[:log]
134
134
  end
135
- end
136
135
 
137
- class PaperclipError < StandardError #:nodoc:
136
+ def class_for(class_name)
137
+ class_name.split('::').inject(Object) do |klass, partial_class_name|
138
+ klass.const_get(partial_class_name)
139
+ end
140
+ end
138
141
  end
139
142
 
140
- class PaperclipCommandLineError < PaperclipError #:nodoc:
141
- attr_accessor :output
142
- def initialize(msg = nil, output = nil)
143
- super(msg)
144
- @output = output
145
- end
143
+ class PaperclipError < StandardError #:nodoc:
146
144
  end
147
145
 
148
146
  class StorageMethodNotFound < PaperclipError
@@ -160,6 +158,7 @@ module Paperclip
160
158
  module Glue
161
159
  def self.included base #:nodoc:
162
160
  base.extend ClassMethods
161
+ base.class_attribute :attachment_definitions
163
162
  if base.respond_to?("set_callback")
164
163
  base.send :include, Paperclip::CallbackCompatability::Rails3
165
164
  else
@@ -235,7 +234,14 @@ module Paperclip
235
234
  def has_attached_file name, options = {}
236
235
  include InstanceMethods
237
236
 
238
- write_inheritable_attribute(:attachment_definitions, {}) if attachment_definitions.nil?
237
+ if attachment_definitions.nil?
238
+ if respond_to?(:class_attribute)
239
+ self.attachment_definitions = {}
240
+ else
241
+ write_inheritable_attribute(:attachment_definitions, {})
242
+ end
243
+ end
244
+
239
245
  attachment_definitions[name] = {:validations => []}.merge(options)
240
246
 
241
247
  after_save :save_attached_files
@@ -343,7 +349,11 @@ module Paperclip
343
349
  # Returns the attachment definitions defined by each call to
344
350
  # has_attached_file.
345
351
  def attachment_definitions
346
- read_inheritable_attribute(:attachment_definitions)
352
+ if respond_to?(:class_attribute)
353
+ self.attachment_definitions
354
+ else
355
+ read_inheritable_attribute(:attachment_definitions)
356
+ end
347
357
  end
348
358
  end
349
359
 
@@ -64,7 +64,7 @@ module Paperclip
64
64
  end
65
65
 
66
66
  def styles
67
- unless @normalized_styles
67
+ if @styles.respond_to?(:call) || !@normalized_styles
68
68
  @normalized_styles = {}
69
69
  (@styles.respond_to?(:call) ? @styles.call(self) : @styles).each do |name, args|
70
70
  @normalized_styles[name] = Paperclip::Style.new(name, args.dup, self)
@@ -270,6 +270,8 @@ module Paperclip
270
270
  def file?
271
271
  !original_filename.blank?
272
272
  end
273
+
274
+ alias :present? :file?
273
275
 
274
276
  # Writes the attachment-specific attribute on the instance. For example,
275
277
  # instance_write(:file_name, "me.jpg") will write "me.jpg" to the instance's
@@ -17,8 +17,10 @@ module Paperclip
17
17
  file = file.path if file.respond_to? "path"
18
18
  geometry = begin
19
19
  Paperclip.run("identify", "-format %wx%h :file", :file => "#{file}[0]")
20
- rescue PaperclipCommandLineError
20
+ rescue Cocaine::ExitStatusError
21
21
  ""
22
+ rescue Cocaine::CommandNotFoundError => e
23
+ raise Paperclip::CommandNotFoundError.new("Could not run the `identify` command. Please install ImageMagick.")
22
24
  end
23
25
  parse(geometry) ||
24
26
  raise(NotIdentifiedByImageMagickError.new("#{file} is not recognized by the 'identify' command."))
@@ -1,3 +1,4 @@
1
1
  require "paperclip/storage/filesystem"
2
+ require "paperclip/storage/fog"
2
3
  require "paperclip/storage/s3"
3
4
  require "paperclip/storage/cloud_files"
@@ -0,0 +1,98 @@
1
+ module Paperclip
2
+ module Storage
3
+
4
+ module Fog
5
+ def self.extended base
6
+ begin
7
+ require 'fog'
8
+ rescue LoadError => e
9
+ e.message << " (You may need to install the fog gem)"
10
+ raise e
11
+ end unless defined?(Fog)
12
+
13
+ base.instance_eval do
14
+ @fog_directory = @options[:fog_directory]
15
+ @fog_credentials = @options[:fog_credentials]
16
+ @fog_host = @options[:fog_host]
17
+ @fog_public = @options[:fog_public]
18
+
19
+ @url = ':fog_public_url'
20
+ Paperclip.interpolates(:fog_public_url) do |attachment, style|
21
+ attachment.public_url(style)
22
+ end unless Paperclip::Interpolations.respond_to? :fog_public_url
23
+ end
24
+ end
25
+
26
+ def exists?(style = default_style)
27
+ if original_filename
28
+ !!directory.files.head(path(style))
29
+ else
30
+ false
31
+ end
32
+ end
33
+
34
+ def flush_writes
35
+ for style, file in @queued_for_write do
36
+ log("saving #{path(style)}")
37
+ directory.files.create(
38
+ :body => file,
39
+ :key => path(style),
40
+ :public => @fog_public
41
+ )
42
+ end
43
+ @queued_for_write = {}
44
+ end
45
+
46
+ def flush_deletes
47
+ for path in @queued_for_delete do
48
+ log("deleting #{path}")
49
+ directory.files.new(:key => path).destroy
50
+ end
51
+ @queued_for_delete = []
52
+ end
53
+
54
+ # Returns representation of the data of the file assigned to the given
55
+ # style, in the format most representative of the current storage.
56
+ def to_file(style = default_style)
57
+ if @queued_for_write[style]
58
+ @queued_for_write[style]
59
+ else
60
+ body = directory.files.get(path(style)).body
61
+ filename = path(style)
62
+ extname = File.extname(filename)
63
+ basename = File.basename(filename, extname)
64
+ file = Tempfile.new([basename, extname])
65
+ file.binmode
66
+ file.write(body)
67
+ file.rewind
68
+ file
69
+ end
70
+ end
71
+
72
+ def public_url(style = default_style)
73
+ if @fog_host
74
+ "#{@fog_host}/#{path(style)}"
75
+ else
76
+ directory.files.new(:key => path(style)).public_url
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def connection
83
+ @connection ||= ::Fog::Storage.new(@fog_credentials)
84
+ end
85
+
86
+ def directory
87
+ @directory ||= begin
88
+ connection.directories.get(@fog_directory) || connection.directories.create(
89
+ :key => @fog_directory,
90
+ :public => @fog_public
91
+ )
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+ end
@@ -25,7 +25,7 @@ module Paperclip
25
25
  # development versus production.
26
26
  # * +s3_permissions+: This is a String that should be one of the "canned" access
27
27
  # policies that S3 provides (more information can be found here:
28
- # http://docs.amazonwebservices.com/AmazonS3/2006-03-01/RESTAccessPolicy.html#RESTCannedAccessPolicies)
28
+ # http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?RESTAccessPolicy.html)
29
29
  # The default for Paperclip is :public_read.
30
30
  # * +s3_protocol+: The protocol for the URLs generated to your S3 assets. Can be either
31
31
  # 'http' or 'https'. Defaults to 'http' when your :s3_permissions are :public_read (the
@@ -94,8 +94,8 @@ module Paperclip
94
94
  end unless Paperclip::Interpolations.respond_to? :s3_domain_url
95
95
  end
96
96
 
97
- def expiring_url(time = 3600)
98
- AWS::S3::S3Object.url_for(path, bucket_name, :expires_in => time )
97
+ def expiring_url(time = 3600, style_name = default_style)
98
+ AWS::S3::S3Object.url_for(path(style_name), bucket_name, :expires_in => time, :use_ssl => (s3_protocol == 'https'))
99
99
  end
100
100
 
101
101
  def bucket_name
@@ -30,8 +30,9 @@ module Paperclip
30
30
  # (which method (in the attachment) will call any supplied procs)
31
31
  # There is an important change of interface here: a style rule can set its own processors
32
32
  # by default we behave as before, though.
33
+ # if a proc has been supplied, we call it here
33
34
  def processors
34
- @processors || attachment.processors
35
+ @processors.respond_to?(:call) ? @processors.call(attachment.instance) : (@processors || attachment.processors)
35
36
  end
36
37
 
37
38
  # retrieves from the attachment the whiny setting
@@ -59,8 +59,10 @@ module Paperclip
59
59
  parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")
60
60
 
61
61
  success = Paperclip.run("convert", parameters, :source => "#{File.expand_path(src.path)}[0]", :dest => File.expand_path(dst.path))
62
- rescue PaperclipCommandLineError => e
62
+ rescue Cocaine::ExitStatusError => e
63
63
  raise PaperclipError, "There was an error processing the thumbnail for #{@basename}" if @whiny
64
+ rescue Cocaine::CommandNotFoundError => e
65
+ raise Paperclip::CommandNotFoundError.new("Could not run the `convert` command. Please install ImageMagick.")
64
66
  end
65
67
 
66
68
  dst
@@ -1,3 +1,3 @@
1
1
  module Paperclip
2
- VERSION = "2.3.8.6" unless defined? Paperclip::VERSION
2
+ VERSION = "2.3.10.1" unless defined? Paperclip::VERSION
3
3
  end
@@ -5,7 +5,7 @@ def obtain_class
5
5
  end
6
6
 
7
7
  def obtain_attachments(klass)
8
- klass = Object.const_get(klass.to_s)
8
+ klass = Paperclip.class_for(klass.to_s)
9
9
  name = ENV['ATTACHMENT'] || ENV['attachment']
10
10
  raise "Class #{klass.name} has no attachments specified" unless klass.respond_to?(:attachment_definitions)
11
11
  if !name.blank? && klass.attachment_definitions.keys.include?(name)
@@ -287,6 +287,24 @@ class AttachmentTest < Test::Unit::TestCase
287
287
  assert_equal "50x50#", @attachment.styles[:thumb][:geometry]
288
288
  end
289
289
  end
290
+
291
+ context "An attachment with conditional :styles that is a proc" do
292
+ setup do
293
+ rebuild_model :styles => lambda{ |attachment| attachment.instance.other == 'a' ? {:thumb => "50x50#"} : {:large => "400x400"} }
294
+
295
+ @dummy = Dummy.new(:other => 'a')
296
+ end
297
+
298
+ should "have the correct styles for the assigned instance values" do
299
+ assert_equal "50x50#", @dummy.avatar.styles[:thumb][:geometry]
300
+ assert_nil @dummy.avatar.styles[:large]
301
+
302
+ @dummy.other = 'b'
303
+
304
+ assert_equal "400x400", @dummy.avatar.styles[:large][:geometry]
305
+ assert_nil @dummy.avatar.styles[:thumb]
306
+ end
307
+ end
290
308
 
291
309
  context "An attachment with :url that is a proc" do
292
310
  setup do
@@ -0,0 +1,107 @@
1
+ require './test/helper'
2
+ require 'fog'
3
+
4
+ Fog.mock!
5
+
6
+ class FogTest < Test::Unit::TestCase
7
+ context "" do
8
+
9
+ setup do
10
+ @fog_directory = 'papercliptests'
11
+
12
+ @credentials = {
13
+ :provider => 'AWS',
14
+ :aws_access_key_id => 'ID',
15
+ :aws_secret_access_key => 'SECRET'
16
+ }
17
+
18
+ @connection = Fog::Storage.new(@credentials)
19
+
20
+ rebuild_model(
21
+ :fog_directory => @fog_directory,
22
+ :fog_credentials => @credentials,
23
+ :fog_host => nil,
24
+ :fog_public => true,
25
+ :path => ":attachment/:basename.:extension",
26
+ :storage => :fog
27
+ )
28
+ end
29
+
30
+ should "be extended by the Fog module" do
31
+ assert Dummy.new.avatar.is_a?(Paperclip::Storage::Fog)
32
+ end
33
+
34
+ context "when assigned" do
35
+ setup do
36
+ @file = File.new(File.join(File.dirname(__FILE__), 'fixtures', '5k.png'), 'rb')
37
+ @dummy = Dummy.new
38
+ @dummy.avatar = @file
39
+ end
40
+
41
+ teardown do
42
+ @file.close
43
+ directory = @connection.directories.new(:key => @fog_directory)
44
+ directory.files.each {|file| file.destroy}
45
+ directory.destroy
46
+ end
47
+
48
+ context "without a bucket" do
49
+ should "succeed" do
50
+ assert @dummy.save
51
+ end
52
+ end
53
+
54
+ context "with a bucket" do
55
+ setup do
56
+ @connection.directories.create(:key => @fog_directory)
57
+ end
58
+
59
+ should "succeed" do
60
+ assert @dummy.save
61
+ end
62
+ end
63
+
64
+ context "without a fog_host" do
65
+ setup do
66
+ rebuild_model(
67
+ :fog_directory => @fog_directory,
68
+ :fog_credentials => @credentials,
69
+ :fog_host => nil,
70
+ :fog_public => true,
71
+ :path => ":attachment/:basename.:extension",
72
+ :storage => :fog
73
+ )
74
+ @dummy = Dummy.new
75
+ @dummy.avatar = StringIO.new('.')
76
+ @dummy.save
77
+ end
78
+
79
+ should "provide a public url" do
80
+ assert !@dummy.avatar.url.nil?
81
+ end
82
+ end
83
+
84
+ context "with a fog_host" do
85
+ setup do
86
+ rebuild_model(
87
+ :fog_directory => @fog_directory,
88
+ :fog_credentials => @credentials,
89
+ :fog_host => 'http://example.com',
90
+ :fog_public => true,
91
+ :path => ":attachment/:basename.:extension",
92
+ :storage => :fog
93
+ )
94
+ @dummy = Dummy.new
95
+ @dummy.avatar = StringIO.new('.')
96
+ @dummy.save
97
+ end
98
+
99
+ should "provide a public url" do
100
+ assert @dummy.avatar.url =~ /^http:\/\/example\.com\/avatars\/stringio\.txt\?\d*$/
101
+ end
102
+ end
103
+
104
+ end
105
+
106
+ end
107
+ end
@@ -120,6 +120,19 @@ class GeometryTest < Test::Unit::TestCase
120
120
  assert_raise(Paperclip::NotIdentifiedByImageMagickError){ @geo = Paperclip::Geometry.from_file(file) }
121
121
  end
122
122
 
123
+ should "let us know when a command isn't found versus a processing error" do
124
+ old_path = ENV['PATH']
125
+ begin
126
+ ENV['PATH'] = ''
127
+ assert_raises(Paperclip::CommandNotFoundError) do
128
+ file = File.join(File.dirname(__FILE__), "fixtures", "5k.png")
129
+ @geo = Paperclip::Geometry.from_file(file)
130
+ end
131
+ ensure
132
+ ENV['PATH'] = old_path
133
+ end
134
+ end
135
+
123
136
  [['vertical', 900, 1440, true, false, false, 1440, 900, 0.625],
124
137
  ['horizontal', 1024, 768, false, true, false, 1024, 768, 1.3333],
125
138
  ['square', 100, 100, false, false, true, 100, 100, 1]].each do |args|
@@ -70,6 +70,7 @@ end
70
70
 
71
71
  def rebuild_model options = {}
72
72
  ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
73
+ table.column :title, :string
73
74
  table.column :other, :string
74
75
  table.column :avatar_file_name, :string
75
76
  table.column :avatar_content_type, :string
@@ -88,6 +89,7 @@ def rebuild_class options = {}
88
89
  include Paperclip::Glue
89
90
  has_attached_file :avatar, options
90
91
  end
92
+ Dummy.reset_column_information
91
93
  end
92
94
 
93
95
  class FakeModel
@@ -34,13 +34,13 @@ class ValidateAttachmentContentTypeMatcherTest < Test::Unit::TestCase
34
34
 
35
35
  should_accept_dummy_class
36
36
  end
37
-
37
+
38
38
  context "given a class with other validations but matching types" do
39
39
  setup do
40
40
  @dummy_class.validates_presence_of :title
41
41
  @dummy_class.validates_attachment_content_type :avatar, :content_type => %r{image/.*}
42
42
  end
43
-
43
+
44
44
  should_accept_dummy_class
45
45
  end
46
46
  end
@@ -2,44 +2,9 @@ require './test/helper'
2
2
 
3
3
  class PaperclipTest < Test::Unit::TestCase
4
4
  context "Calling Paperclip.run" do
5
- setup do
6
- Paperclip.options[:image_magick_path] = nil
7
- Paperclip.options[:command_path] = nil
8
- Paperclip::CommandLine.stubs(:'`')
9
- end
10
-
11
- should "execute the right command with :image_magick_path" do
12
- Paperclip.options[:image_magick_path] = "/usr/bin"
13
- Paperclip.expects(:log).with(includes('[DEPRECATION]'))
14
- Paperclip.expects(:log).with(regexp_matches(%r{/usr/bin/convert ['"]one.jpg['"] ['"]two.jpg['"]}))
15
- Paperclip::CommandLine.expects(:"`").with(regexp_matches(%r{/usr/bin/convert ['"]one.jpg['"] ['"]two.jpg['"]}))
16
- Paperclip.run("convert", ":one :two", :one => "one.jpg", :two => "two.jpg")
17
- end
18
-
19
- should "execute the right command with :command_path" do
20
- Paperclip.options[:command_path] = "/usr/bin"
21
- Paperclip::CommandLine.expects(:"`").with(regexp_matches(%r{/usr/bin/convert ['"]one.jpg['"] ['"]two.jpg['"]}))
22
- Paperclip.run("convert", ":one :two", :one => "one.jpg", :two => "two.jpg")
23
- end
24
-
25
- should "execute the right command with no path" do
26
- Paperclip::CommandLine.expects(:"`").with(regexp_matches(%r{convert ['"]one.jpg['"] ['"]two.jpg['"]}))
27
- Paperclip.run("convert", ":one :two", :one => "one.jpg", :two => "two.jpg")
28
- end
29
-
30
- should "tell you the command isn't there if the shell returns 127" do
31
- with_exitstatus_returning(127) do
32
- assert_raises(Paperclip::CommandNotFoundError) do
33
- Paperclip.run("command")
34
- end
35
- end
36
- end
37
-
38
- should "tell you the command isn't there if an ENOENT is raised" do
39
- assert_raises(Paperclip::CommandNotFoundError) do
40
- Paperclip::CommandLine.stubs(:"`").raises(Errno::ENOENT)
41
- Paperclip.run("command")
42
- end
5
+ should "run the command with Cocaine" do
6
+ Cocaine::CommandLine.expects(:new).with("convert", "stuff").returns(stub(:run))
7
+ Paperclip.run("convert", "stuff")
43
8
  end
44
9
  end
45
10
 
@@ -72,6 +37,11 @@ class PaperclipTest < Test::Unit::TestCase
72
37
  assert_equal ::Paperclip::Thumbnail, Paperclip.processor(:thumbnail)
73
38
  end
74
39
 
40
+ should "get a class from a namespaced class name" do
41
+ class ::One; class Two; end; end
42
+ assert_equal ::One::Two, Paperclip.class_for("One::Two")
43
+ end
44
+
75
45
  context "An ActiveRecord model with an 'avatar' attachment" do
76
46
  setup do
77
47
  rebuild_model :path => "tmp/:class/omg/:style.:extension"
@@ -223,7 +193,7 @@ class PaperclipTest < Test::Unit::TestCase
223
193
  @dummy.valid?
224
194
  end
225
195
  should "not have an error when assigned a valid file" do
226
- assert_equal 0, @dummy.errors.length, @dummy.errors.full_messages.join(", ")
196
+ assert_equal 0, @dummy.errors.size, @dummy.errors.full_messages.join(", ")
227
197
  end
228
198
  end
229
199
  context "and assigned an invalid file" do
@@ -232,7 +202,7 @@ class PaperclipTest < Test::Unit::TestCase
232
202
  @dummy.valid?
233
203
  end
234
204
  should "have an error when assigned a valid file" do
235
- assert @dummy.errors.length > 0
205
+ assert @dummy.errors.size > 0
236
206
  end
237
207
  end
238
208
  end
@@ -180,7 +180,7 @@ class StorageTest < Test::Unit::TestCase
180
180
  end
181
181
  end
182
182
 
183
- context "Generating a url with an expiration" do
183
+ context "Generating a secure url with an expiration" do
184
184
  setup do
185
185
  AWS::S3::Base.stubs(:establish_connection!)
186
186
  rebuild_model :storage => :s3,
@@ -189,6 +189,7 @@ class StorageTest < Test::Unit::TestCase
189
189
  :development => { :bucket => "dev_bucket" }
190
190
  },
191
191
  :s3_host_alias => "something.something.com",
192
+ :s3_permissions => "private",
192
193
  :path => ":attachment/:basename.:extension",
193
194
  :url => ":s3_alias_url"
194
195
 
@@ -197,7 +198,7 @@ class StorageTest < Test::Unit::TestCase
197
198
  @dummy = Dummy.new
198
199
  @dummy.avatar = StringIO.new(".")
199
200
 
200
- AWS::S3::S3Object.expects(:url_for).with("avatars/stringio.txt", "prod_bucket", { :expires_in => 3600 })
201
+ AWS::S3::S3Object.expects(:url_for).with("avatars/stringio.txt", "prod_bucket", { :expires_in => 3600, :use_ssl => true })
201
202
 
202
203
  @dummy.avatar.expiring_url
203
204
  end
@@ -207,6 +208,35 @@ class StorageTest < Test::Unit::TestCase
207
208
  end
208
209
  end
209
210
 
211
+ context "Generating a url with an expiration" do
212
+ setup do
213
+ AWS::S3::Base.stubs(:establish_connection!)
214
+ rebuild_model :storage => :s3,
215
+ :s3_credentials => {
216
+ :production => { :bucket => "prod_bucket" },
217
+ :development => { :bucket => "dev_bucket" }
218
+ },
219
+ :s3_host_alias => "something.something.com",
220
+ :path => ":attachment/:style/:basename.:extension",
221
+ :url => ":s3_alias_url"
222
+
223
+ rails_env("production")
224
+
225
+ @dummy = Dummy.new
226
+ @dummy.avatar = StringIO.new(".")
227
+
228
+ AWS::S3::S3Object.expects(:url_for).with("avatars/original/stringio.txt", "prod_bucket", { :expires_in => 3600, :use_ssl => false })
229
+ @dummy.avatar.expiring_url
230
+
231
+ AWS::S3::S3Object.expects(:url_for).with("avatars/thumb/stringio.txt", "prod_bucket", { :expires_in => 1800, :use_ssl => false })
232
+ @dummy.avatar.expiring_url(1800, :thumb)
233
+ end
234
+
235
+ should "should succeed" do
236
+ assert true
237
+ end
238
+ end
239
+
210
240
  context "Parsing S3 credentials with a bucket in them" do
211
241
  setup do
212
242
  AWS::S3::Base.stubs(:establish_connection!)
@@ -138,4 +138,26 @@ class StyleTest < Test::Unit::TestCase
138
138
  end
139
139
 
140
140
  end
141
+
142
+ context "A style rule with :processors supplied as procs" do
143
+ setup do
144
+ @attachment = attachment :path => ":basename.:extension",
145
+ :styles => {
146
+ :foo => {
147
+ :geometry => "100x100#",
148
+ :format => :png,
149
+ :processors => lambda{|a| [:test]}
150
+ }
151
+ },
152
+ :processors => [:thumbnail]
153
+ end
154
+
155
+ should "defer processing of procs until they are needed" do
156
+ assert_kind_of Proc, @attachment.styles[:foo].instance_variable_get("@processors")
157
+ end
158
+
159
+ should "call procs when they are needed" do
160
+ assert_equal [:test], @attachment.styles[:foo].processors
161
+ end
162
+ end
141
163
  end
@@ -73,6 +73,18 @@ class ThumbnailTest < Test::Unit::TestCase
73
73
  @thumb = Paperclip::Thumbnail.new(@file, :geometry => "100x50#")
74
74
  end
75
75
 
76
+ should "let us know when a command isn't found versus a processing error" do
77
+ old_path = ENV['PATH']
78
+ begin
79
+ ENV['PATH'] = ''
80
+ assert_raises(Paperclip::CommandNotFoundError) do
81
+ @thumb.make
82
+ end
83
+ ensure
84
+ ENV['PATH'] = old_path
85
+ end
86
+ end
87
+
76
88
  should "report its correct current and target geometries" do
77
89
  assert_equal "100x50#", @thumb.target_geometry.to_s
78
90
  assert_equal "434x66", @thumb.current_geometry.to_s
@@ -91,8 +103,10 @@ class ThumbnailTest < Test::Unit::TestCase
91
103
  end
92
104
 
93
105
  should "send the right command to convert when sent #make" do
94
- Paperclip::CommandLine.expects(:"`").with do |arg|
95
- arg.match %r{convert ["']#{File.expand_path(@thumb.file.path)}\[0\]["'] -resize ["']x50["'] -crop ["']100x50\+114\+0["'] \+repage ["'].*?["']}
106
+ Paperclip.expects(:run).with do |*arg|
107
+ arg[0] == 'convert' &&
108
+ arg[1] == ':source -resize "x50" -crop "100x50+114+0" +repage :dest' &&
109
+ arg[2][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
96
110
  end
97
111
  @thumb.make
98
112
  end
@@ -115,8 +129,10 @@ class ThumbnailTest < Test::Unit::TestCase
115
129
  end
116
130
 
117
131
  should "send the right command to convert when sent #make" do
118
- Paperclip::CommandLine.expects(:"`").with do |arg|
119
- arg.match %r{convert -strip ["']#{File.expand_path(@thumb.file.path)}\[0\]["'] -resize ["']x50["'] -crop ["']100x50\+114\+0["'] \+repage ["'].*?["']}
132
+ Paperclip.expects(:run).with do |*arg|
133
+ arg[0] == 'convert' &&
134
+ arg[1] == '-strip :source -resize "x50" -crop "100x50+114+0" +repage :dest' &&
135
+ arg[2][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
120
136
  end
121
137
  @thumb.make
122
138
  end
@@ -153,8 +169,10 @@ class ThumbnailTest < Test::Unit::TestCase
153
169
  end
154
170
 
155
171
  should "send the right command to convert when sent #make" do
156
- Paperclip::CommandLine.expects(:"`").with do |arg|
157
- arg.match %r{convert ["']#{File.expand_path(@thumb.file.path)}\[0\]["'] -resize ["']x50["'] -crop ["']100x50\+114\+0["'] \+repage -strip -depth 8 ["'].*?["']}
172
+ Paperclip.expects(:run).with do |*arg|
173
+ arg[0] == 'convert' &&
174
+ arg[1] == ':source -resize "x50" -crop "100x50+114+0" +repage -strip -depth 8 :dest' &&
175
+ arg[2][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
158
176
  end
159
177
  @thumb.make
160
178
  end
@@ -176,6 +194,18 @@ class ThumbnailTest < Test::Unit::TestCase
176
194
  @thumb.make
177
195
  end
178
196
  end
197
+
198
+ should "let us know when a command isn't found versus a processing error" do
199
+ old_path = ENV['PATH']
200
+ begin
201
+ ENV['PATH'] = ''
202
+ assert_raises(Paperclip::CommandNotFoundError) do
203
+ @thumb.make
204
+ end
205
+ ensure
206
+ ENV['PATH'] = old_path
207
+ end
208
+ end
179
209
  end
180
210
  end
181
211
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paperclip-cloudfiles
3
3
  version: !ruby/object:Gem::Version
4
- hash: 91
4
+ hash: 93
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 3
9
- - 8
10
- - 6
11
- version: 2.3.8.6
9
+ - 10
10
+ - 1
11
+ version: 2.3.10.1
12
12
  platform: ruby
13
13
  authors:
14
14
  - Jon Yurek
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2011-05-26 00:00:00 Z
20
+ date: 2011-05-27 00:00:00 Z
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
23
  prerelease: false
@@ -153,7 +153,6 @@ files:
153
153
  - lib/generators/paperclip/USAGE
154
154
  - lib/paperclip/attachment.rb
155
155
  - lib/paperclip/callback_compatability.rb
156
- - lib/paperclip/command_line.rb
157
156
  - lib/paperclip/geometry.rb
158
157
  - lib/paperclip/interpolations.rb
159
158
  - lib/paperclip/iostream.rb
@@ -166,6 +165,7 @@ files:
166
165
  - lib/paperclip/railtie.rb
167
166
  - lib/paperclip/storage/cloud_files.rb
168
167
  - lib/paperclip/storage/filesystem.rb
168
+ - lib/paperclip/storage/fog.rb
169
169
  - lib/paperclip/storage/s3.rb
170
170
  - lib/paperclip/storage.rb
171
171
  - lib/paperclip/style.rb
@@ -176,7 +176,6 @@ files:
176
176
  - lib/tasks/paperclip.rake
177
177
  - test/attachment_test.rb
178
178
  - test/cloudfiles.yml
179
- - test/command_line_test.rb
180
179
  - test/database.yml
181
180
  - test/fixtures/12k.png
182
181
  - test/fixtures/50x50.png
@@ -186,6 +185,7 @@ files:
186
185
  - test/fixtures/text.txt
187
186
  - test/fixtures/twopage.pdf
188
187
  - test/fixtures/uppercase.PNG
188
+ - test/fog_test.rb
189
189
  - test/geometry_test.rb
190
190
  - test/helper.rb
191
191
  - test/integration_test.rb
@@ -1,86 +0,0 @@
1
- module Paperclip
2
- class CommandLine
3
- class << self
4
- attr_accessor :path
5
- end
6
-
7
- def initialize(binary, params = "", options = {})
8
- @binary = binary.dup
9
- @params = params.dup
10
- @options = options.dup
11
- @swallow_stderr = @options.has_key?(:swallow_stderr) ? @options.delete(:swallow_stderr) : Paperclip.options[:swallow_stderr]
12
- @expected_outcodes = @options.delete(:expected_outcodes)
13
- @expected_outcodes ||= [0]
14
- end
15
-
16
- def command
17
- cmd = []
18
- cmd << full_path(@binary)
19
- cmd << interpolate(@params, @options)
20
- cmd << bit_bucket if @swallow_stderr
21
- cmd.join(" ")
22
- end
23
-
24
- def run
25
- Paperclip.log(command)
26
- begin
27
- output = self.class.send(:'`', command)
28
- rescue Errno::ENOENT
29
- raise Paperclip::CommandNotFoundError
30
- end
31
- if $?.exitstatus == 127
32
- raise Paperclip::CommandNotFoundError
33
- end
34
- unless @expected_outcodes.include?($?.exitstatus)
35
- raise Paperclip::PaperclipCommandLineError, "Command '#{command}' returned #{$?.exitstatus}. Expected #{@expected_outcodes.join(", ")}"
36
- end
37
- output
38
- end
39
-
40
- private
41
-
42
- def full_path(binary)
43
- [self.class.path, binary].compact.join("/")
44
- end
45
-
46
- def interpolate(pattern, vars)
47
- # interpolates :variables and :{variables}
48
- pattern.gsub(%r#:(?:\w+|\{\w+\})#) do |match|
49
- key = match[1..-1]
50
- key = key[1..-2] if key[0,1] == '{'
51
- if invalid_variables.include?(key)
52
- raise PaperclipCommandLineError,
53
- "Interpolation of #{key} isn't allowed."
54
- end
55
- interpolation(vars, key) || match
56
- end
57
- end
58
-
59
- def invalid_variables
60
- %w(expected_outcodes swallow_stderr)
61
- end
62
-
63
- def interpolation(vars, key)
64
- if vars.key?(key.to_sym)
65
- shell_quote(vars[key.to_sym])
66
- end
67
- end
68
-
69
- def shell_quote(string)
70
- return "" if string.nil? or string.blank?
71
- if self.class.unix?
72
- string.split("'").map{|m| "'#{m}'" }.join("\\'")
73
- else
74
- %{"#{string}"}
75
- end
76
- end
77
-
78
- def bit_bucket
79
- self.class.unix? ? "2>/dev/null" : "2>NUL"
80
- end
81
-
82
- def self.unix?
83
- File.exist?("/dev/null")
84
- end
85
- end
86
- end
@@ -1,138 +0,0 @@
1
- require './test/helper'
2
-
3
- class CommandLineTest < Test::Unit::TestCase
4
- def setup
5
- Paperclip::CommandLine.path = nil
6
- File.stubs(:exist?).with("/dev/null").returns(true)
7
- end
8
-
9
- should "allow colons in parameters" do
10
- cmd = Paperclip::CommandLine.new("convert", "'a.jpg' -resize 175x220> -size 175x220 xc:black +swap -gravity center -composite 'b.jpg'", :swallow_stderr => false)
11
- assert_equal "convert 'a.jpg' -resize 175x220> -size 175x220 xc:black +swap -gravity center -composite 'b.jpg'", cmd.command
12
- end
13
-
14
- should "take a command and parameters and produce a shell command for bash" do
15
- cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
16
- assert_equal "convert a.jpg b.png", cmd.command
17
- end
18
-
19
- should "be able to set a path and produce commands with that path" do
20
- Paperclip::CommandLine.path = "/opt/bin"
21
- cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
22
- assert_equal "/opt/bin/convert a.jpg b.png", cmd.command
23
- end
24
-
25
- should "be able to interpolate quoted variables into the parameters" do
26
- cmd = Paperclip::CommandLine.new("convert",
27
- ":one :{two}",
28
- :one => "a.jpg",
29
- :two => "b.png",
30
- :swallow_stderr => false)
31
- assert_equal "convert 'a.jpg' 'b.png'", cmd.command
32
- end
33
-
34
- should "quote command line options differently if we're on windows" do
35
- File.stubs(:exist?).with("/dev/null").returns(false)
36
- cmd = Paperclip::CommandLine.new("convert",
37
- ":one :{two}",
38
- :one => "a.jpg",
39
- :two => "b.png",
40
- :swallow_stderr => false)
41
- assert_equal 'convert "a.jpg" "b.png"', cmd.command
42
- end
43
-
44
- should "be able to quote and interpolate dangerous variables" do
45
- cmd = Paperclip::CommandLine.new("convert",
46
- ":one :two",
47
- :one => "`rm -rf`.jpg",
48
- :two => "ha'ha.png",
49
- :swallow_stderr => false)
50
- assert_equal "convert '`rm -rf`.jpg' 'ha'\\''ha.png'", cmd.command
51
- end
52
-
53
- should "be able to quote and interpolate dangerous variables even on windows" do
54
- File.stubs(:exist?).with("/dev/null").returns(false)
55
- cmd = Paperclip::CommandLine.new("convert",
56
- ":one :two",
57
- :one => "`rm -rf`.jpg",
58
- :two => "ha'ha.png",
59
- :swallow_stderr => false)
60
- assert_equal %{convert "`rm -rf`.jpg" "ha'ha.png"}, cmd.command
61
- end
62
-
63
- should "add redirection to get rid of stderr in bash" do
64
- File.stubs(:exist?).with("/dev/null").returns(true)
65
- cmd = Paperclip::CommandLine.new("convert",
66
- "a.jpg b.png",
67
- :swallow_stderr => true)
68
-
69
- assert_equal "convert a.jpg b.png 2>/dev/null", cmd.command
70
- end
71
-
72
- should "add redirection to get rid of stderr in cmd.exe" do
73
- File.stubs(:exist?).with("/dev/null").returns(false)
74
- cmd = Paperclip::CommandLine.new("convert",
75
- "a.jpg b.png",
76
- :swallow_stderr => true)
77
-
78
- assert_equal "convert a.jpg b.png 2>NUL", cmd.command
79
- end
80
-
81
- should "raise if trying to interpolate :swallow_stderr or :expected_outcodes" do
82
- cmd = Paperclip::CommandLine.new("convert",
83
- ":swallow_stderr :expected_outcodes",
84
- :swallow_stderr => false,
85
- :expected_outcodes => [0, 1])
86
- assert_raise(Paperclip::PaperclipCommandLineError) do
87
- cmd.command
88
- end
89
- end
90
-
91
- should "run the #command it's given and return the output" do
92
- cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
93
- cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
94
- with_exitstatus_returning(0) do
95
- assert_equal :correct_value, cmd.run
96
- end
97
- end
98
-
99
- should "raise a PaperclipCommandLineError if the result code isn't expected" do
100
- cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
101
- cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
102
- with_exitstatus_returning(1) do
103
- assert_raises(Paperclip::PaperclipCommandLineError) do
104
- cmd.run
105
- end
106
- end
107
- end
108
-
109
- should "not raise a PaperclipCommandLineError if the result code is expected" do
110
- cmd = Paperclip::CommandLine.new("convert",
111
- "a.jpg b.png",
112
- :expected_outcodes => [0, 1],
113
- :swallow_stderr => false)
114
- cmd.class.stubs(:"`").with("convert a.jpg b.png").returns(:correct_value)
115
- with_exitstatus_returning(1) do
116
- assert_nothing_raised do
117
- cmd.run
118
- end
119
- end
120
- end
121
-
122
- should "log the command" do
123
- cmd = Paperclip::CommandLine.new("convert", "a.jpg b.png", :swallow_stderr => false)
124
- cmd.class.stubs(:'`')
125
- Paperclip.expects(:log).with("convert a.jpg b.png")
126
- cmd.run
127
- end
128
-
129
- should "detect that the system is unix or windows based on presence of /dev/null" do
130
- File.stubs(:exist?).returns(true)
131
- assert Paperclip::CommandLine.unix?
132
- end
133
-
134
- should "detect that the system is not unix or windows based on absence of /dev/null" do
135
- File.stubs(:exist?).returns(false)
136
- assert ! Paperclip::CommandLine.unix?
137
- end
138
- end