paperclip-cloudfiles 2.3.8.6 → 2.3.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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