paperclip 4.3.1 → 4.3.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of paperclip might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ab079cc4a5b7fb2885b1976726ae33c0db4f675c
4
- data.tar.gz: 9702e32a54d7bb860cf80378d9a2272414d4a6bb
3
+ metadata.gz: 0e139df6e8e24d624d436566d794642b848aba04
4
+ data.tar.gz: 4ebe1f32b8ce077f35d56ab232d07f71a3e39267
5
5
  SHA512:
6
- metadata.gz: 907a4cb680acec3e2900bc2bc2b3ec800850f6d1819feaff1f7fcc4104e665571ec330fe78606152ea35fcbcd653163f00dd22585d230ab7d2da228984abc9f1
7
- data.tar.gz: 197e5d325aa36649e725672ff64dcf127944c97cb91d69faed664cd05dc32d643dea1a65eadb917493d9883009fb79e06f5ae27a001b130cb5525827026de370
6
+ metadata.gz: 445e6c03d40f5c72e2cc45eb818685917d450607a37c37ecb413be50534036a4606572a2f1990c851705fe5c767e3861700732de81894633bcb54b26ec50b36a
7
+ data.tar.gz: 2ab2c5ba3f14288f3e906d7f6410b2a1cc2727ec7adeada4c6fd6ce34b81c2270df75a4391447b047de8ab5797bc3c898ab3181fd03bded34b1329277fa2c30d
data/NEWS CHANGED
@@ -1,3 +1,7 @@
1
+ 4.3.2 (11/18/2015):
2
+
3
+ * Performance: Reduce memory allocations (#2056)
4
+
1
5
  4.3.1 (9/9/2015):
2
6
 
3
7
  * Backport of bugfix to `remove_column`, so it works in Rails 3 and 4
@@ -68,7 +68,8 @@ module Paperclip
68
68
  # +url_generator+ - the object used to generate URLs, using the interpolator. Defaults to Paperclip::UrlGenerator
69
69
  # +escape_url+ - Perform URI escaping to URLs. Defaults to true
70
70
  def initialize(name, instance, options = {})
71
- @name = name
71
+ @name = name.to_sym
72
+ @name_string = name.to_s
72
73
  @instance = instance
73
74
 
74
75
  options = self.class.default_options.deep_merge(options)
@@ -365,7 +366,7 @@ module Paperclip
365
366
  # instance_write(:file_name, "me.jpg") will write "me.jpg" to the instance's
366
367
  # "avatar_file_name" field (assuming the attachment is called avatar).
367
368
  def instance_write(attr, value)
368
- setter = :"#{name}_#{attr}="
369
+ setter = :"#{@name_string}_#{attr}="
369
370
  if instance.respond_to?(setter)
370
371
  instance.send(setter, value)
371
372
  end
@@ -374,7 +375,7 @@ module Paperclip
374
375
  # Reads the attachment-specific attribute on the instance. See instance_write
375
376
  # for more details.
376
377
  def instance_read(attr)
377
- getter = :"#{name}_#{attr}"
378
+ getter = :"#{@name_string}_#{attr}"
378
379
  if instance.respond_to?(getter)
379
380
  instance.send(getter)
380
381
  end
@@ -402,8 +403,8 @@ module Paperclip
402
403
 
403
404
  def ensure_required_accessors! #:nodoc:
404
405
  %w(file_name).each do |field|
405
- unless @instance.respond_to?("#{name}_#{field}") && @instance.respond_to?("#{name}_#{field}=")
406
- raise Paperclip::Error.new("#{@instance.class} model missing required attr_accessor for '#{name}_#{field}'")
406
+ unless @instance.respond_to?("#{@name_string}_#{field}") && @instance.respond_to?("#{@name_string}_#{field}=")
407
+ raise Paperclip::Error.new("#{@instance.class} model missing required attr_accessor for '#{@name_string}_#{field}'")
407
408
  end
408
409
  end
409
410
  end
@@ -10,6 +10,7 @@ module Paperclip
10
10
  # and is not intended for normal use.
11
11
  def self.[]= name, block
12
12
  define_method(name, &block)
13
+ @interpolators_cache = nil
13
14
  end
14
15
 
15
16
  # Hash access of interpolations. Included only for compatibility,
@@ -20,7 +21,7 @@ module Paperclip
20
21
 
21
22
  # Returns a sorted list of all interpolations.
22
23
  def self.all
23
- self.instance_methods(false).sort
24
+ self.instance_methods(false).sort!
24
25
  end
25
26
 
26
27
  # Perform the actual interpolation. Takes the pattern to interpolate
@@ -29,11 +30,15 @@ module Paperclip
29
30
  # an interpolation pattern for Paperclip to use.
30
31
  def self.interpolate pattern, *args
31
32
  pattern = args.first.instance.send(pattern) if pattern.kind_of? Symbol
32
- all.reverse.inject(pattern) do |result, tag|
33
- result.gsub(/:#{tag}/) do |match|
34
- send( tag, *args )
35
- end
33
+ result = pattern.dup
34
+ interpolators_cache.each do |method, token|
35
+ result.gsub!(token) { send(method, *args) } if result.include?(token)
36
36
  end
37
+ result
38
+ end
39
+
40
+ def self.interpolators_cache
41
+ @interpolators_cache ||= all.reverse!.map! { |method| [method, ":#{method}"] }
37
42
  end
38
43
 
39
44
  def self.plural_cache
@@ -42,7 +47,7 @@ module Paperclip
42
47
 
43
48
  # Returns the filename, the same way as ":basename.:extension" would.
44
49
  def filename attachment, style_name
45
- [ basename(attachment, style_name), extension(attachment, style_name) ].reject(&:blank?).join(".")
50
+ [ basename(attachment, style_name), extension(attachment, style_name) ].delete_if(&:empty?).join(".".freeze)
46
51
  end
47
52
 
48
53
  # Returns the interpolated URL. Will raise an error if the url itself
@@ -85,12 +90,12 @@ module Paperclip
85
90
  # all class names. Calling #class will return the expected class.
86
91
  def class attachment = nil, style_name = nil
87
92
  return super() if attachment.nil? && style_name.nil?
88
- plural_cache.underscore_and_pluralize(attachment.instance.class.to_s)
93
+ plural_cache.underscore_and_pluralize_class(attachment.instance.class)
89
94
  end
90
95
 
91
96
  # Returns the basename of the file. e.g. "file" for "file.jpg"
92
97
  def basename attachment, style_name
93
- attachment.original_filename.gsub(/#{Regexp.escape(File.extname(attachment.original_filename))}\Z/, "")
98
+ File.basename(attachment.original_filename, ".*".freeze)
94
99
  end
95
100
 
96
101
  # Returns the extension of the file. e.g. "jpg" for "file.jpg"
@@ -98,7 +103,7 @@ module Paperclip
98
103
  # of the actual extension.
99
104
  def extension attachment, style_name
100
105
  ((style = attachment.styles[style_name.to_s.to_sym]) && style[:format]) ||
101
- File.extname(attachment.original_filename).gsub(/\A\.+/, "")
106
+ File.extname(attachment.original_filename).sub(/\A\.+/, "".freeze)
102
107
  end
103
108
 
104
109
  # Returns the dot+extension of the file. e.g. ".jpg" for "file.jpg"
@@ -106,7 +111,7 @@ module Paperclip
106
111
  # of the actual extension. If the extension is empty, no dot is added.
107
112
  def dotextension attachment, style_name
108
113
  ext = extension(attachment, style_name)
109
- ext.empty? ? "" : ".#{ext}"
114
+ ext.empty? ? ext : ".#{ext}"
110
115
  end
111
116
 
112
117
  # Returns an extension based on the content type. e.g. "jpeg" for
@@ -170,9 +175,9 @@ module Paperclip
170
175
  def id_partition attachment, style_name
171
176
  case id = attachment.instance.id
172
177
  when Integer
173
- ("%09d" % id).scan(/\d{3}/).join("/")
178
+ ("%09d".freeze % id).scan(/\d{3}/).join("/".freeze)
174
179
  when String
175
- id.scan(/.{3}/).first(3).join("/")
180
+ id.scan(/.{3}/).first(3).join("/".freeze)
176
181
  else
177
182
  nil
178
183
  end
@@ -181,7 +186,7 @@ module Paperclip
181
186
  # Returns the pluralized form of the attachment name. e.g.
182
187
  # "avatars" for an attachment of :avatar
183
188
  def attachment attachment, style_name
184
- plural_cache.pluralize(attachment.name.to_s.downcase)
189
+ plural_cache.pluralize_symbol(attachment.name)
185
190
  end
186
191
 
187
192
  # Returns the style, or the default style if nil is supplied.
@@ -2,15 +2,16 @@ module Paperclip
2
2
  module Interpolations
3
3
  class PluralCache
4
4
  def initialize
5
- @cache = {}
5
+ @symbol_cache = {}.compare_by_identity
6
+ @klass_cache = {}.compare_by_identity
6
7
  end
7
8
 
8
- def pluralize(word)
9
- @cache[word] ||= word.pluralize
9
+ def pluralize_symbol(symbol)
10
+ @symbol_cache[symbol] ||= symbol.to_s.downcase.pluralize
10
11
  end
11
12
 
12
- def underscore_and_pluralize(word)
13
- @cache[word] ||= word.underscore.pluralize
13
+ def underscore_and_pluralize_class(klass)
14
+ @klass_cache[klass] ||= klass.name.underscore.pluralize
14
15
  end
15
16
  end
16
17
  end
@@ -15,7 +15,7 @@ module Paperclip
15
15
  private
16
16
 
17
17
  def rails_exists?
18
- Object.const_defined?("Rails")
18
+ Object.const_defined?(:Rails)
19
19
  end
20
20
 
21
21
  def rails_environment_exists?
@@ -141,7 +141,7 @@ module Paperclip
141
141
  Proc.new do |style, attachment|
142
142
  permission = (@s3_permissions[style.to_s.to_sym] || @s3_permissions[:default])
143
143
  permission = permission.call(attachment, style) if permission.respond_to?(:call)
144
- (permission == :public_read) ? 'http' : 'https'
144
+ (permission == :public_read) ? 'http'.freeze : 'https'.freeze
145
145
  end
146
146
  @s3_metadata = @options[:s3_metadata] || {}
147
147
  @s3_headers = {}
@@ -157,9 +157,9 @@ module Paperclip
157
157
  @s3_server_side_encryption = @options[:s3_server_side_encryption]
158
158
  end
159
159
 
160
- unless @options[:url].to_s.match(/\A:s3.*url\Z/) || @options[:url] == ":asset_host"
161
- @options[:path] = path_option.gsub(/:url/, @options[:url]).gsub(/\A:rails_root\/public\/system/, '')
162
- @options[:url] = ":s3_path_url"
160
+ unless @options[:url].to_s.match(/\A:s3.*url\Z/) || @options[:url] == ":asset_host".freeze
161
+ @options[:path] = path_option.gsub(/:url/, @options[:url]).sub(/\A:rails_root\/public\/system/, "".freeze)
162
+ @options[:url] = ":s3_path_url".freeze
163
163
  end
164
164
  @options[:url] = @options[:url].inspect if @options[:url].is_a?(Symbol)
165
165
 
@@ -167,16 +167,16 @@ module Paperclip
167
167
  end
168
168
 
169
169
  Paperclip.interpolates(:s3_alias_url) do |attachment, style|
170
- "#{attachment.s3_protocol(style, true)}//#{attachment.s3_host_alias}/#{attachment.path(style).gsub(%r{\A/}, "")}"
170
+ "#{attachment.s3_protocol(style, true)}//#{attachment.s3_host_alias}/#{attachment.path(style).sub(%r{\A/}, "".freeze)}"
171
171
  end unless Paperclip::Interpolations.respond_to? :s3_alias_url
172
172
  Paperclip.interpolates(:s3_path_url) do |attachment, style|
173
- "#{attachment.s3_protocol(style, true)}//#{attachment.s3_host_name}/#{attachment.bucket_name}/#{attachment.path(style).gsub(%r{\A/}, "")}"
173
+ "#{attachment.s3_protocol(style, true)}//#{attachment.s3_host_name}/#{attachment.bucket_name}/#{attachment.path(style).sub(%r{\A/}, "".freeze)}"
174
174
  end unless Paperclip::Interpolations.respond_to? :s3_path_url
175
175
  Paperclip.interpolates(:s3_domain_url) do |attachment, style|
176
- "#{attachment.s3_protocol(style, true)}//#{attachment.bucket_name}.#{attachment.s3_host_name}/#{attachment.path(style).gsub(%r{\A/}, "")}"
176
+ "#{attachment.s3_protocol(style, true)}//#{attachment.bucket_name}.#{attachment.s3_host_name}/#{attachment.path(style).sub(%r{\A/}, "".freeze)}"
177
177
  end unless Paperclip::Interpolations.respond_to? :s3_domain_url
178
178
  Paperclip.interpolates(:asset_host) do |attachment, style|
179
- "#{attachment.path(style).gsub(%r{\A/}, "")}"
179
+ "#{attachment.path(style).sub(%r{\A/}, "".freeze)}"
180
180
  end unless Paperclip::Interpolations.respond_to? :asset_host
181
181
  end
182
182
 
@@ -197,7 +197,7 @@ module Paperclip
197
197
  host_name = @options[:s3_host_name]
198
198
  host_name = host_name.call(self) if host_name.is_a?(Proc)
199
199
 
200
- host_name || s3_credentials[:s3_host_name] || "s3.amazonaws.com"
200
+ host_name || s3_credentials[:s3_host_name] || "s3.amazonaws.com".freeze
201
201
  end
202
202
 
203
203
  def s3_host_alias
@@ -286,7 +286,7 @@ module Paperclip
286
286
  end
287
287
 
288
288
  def parse_credentials creds
289
- creds = creds.respond_to?('call') ? creds.call(self) : creds
289
+ creds = creds.respond_to?(:call) ? creds.call(self) : creds
290
290
  creds = find_credentials(creds).stringify_keys
291
291
  (creds[RailsEnvironment.get] || creds).symbolize_keys
292
292
  end
@@ -1,3 +1,3 @@
1
1
  module Paperclip
2
- VERSION = "4.3.1" unless defined? Paperclip::VERSION
2
+ VERSION = "4.3.2" unless defined? Paperclip::VERSION
3
3
  end
@@ -34,12 +34,13 @@ Gem::Specification.new do |s|
34
34
  s.add_development_dependency('aws-sdk', '>= 1.5.7', "<= 2.0")
35
35
  s.add_development_dependency('bourne')
36
36
  s.add_development_dependency('cucumber', '~> 1.3.18')
37
- s.add_development_dependency('aruba')
37
+ s.add_development_dependency('aruba', '~> 0.9.0')
38
38
  s.add_development_dependency('nokogiri')
39
39
  # Ruby version < 1.9.3 can't install capybara > 2.0.3.
40
40
  s.add_development_dependency('capybara')
41
41
  s.add_development_dependency('bundler')
42
- s.add_development_dependency('fog', '~> 1.0')
42
+ s.add_development_dependency('fog-aws')
43
+ s.add_development_dependency('fog-local')
43
44
  s.add_development_dependency('launchy')
44
45
  s.add_development_dependency('rake')
45
46
  s.add_development_dependency('fakeweb')
@@ -24,15 +24,16 @@ describe Paperclip::Interpolations do
24
24
  end
25
25
 
26
26
  it "returns the class of the instance" do
27
+ class Thing ; end
27
28
  attachment = mock
28
29
  attachment.expects(:instance).returns(attachment)
29
- attachment.expects(:class).returns("Thing")
30
+ attachment.expects(:class).returns(Thing)
30
31
  assert_equal "things", Paperclip::Interpolations.class(attachment, :style)
31
32
  end
32
33
 
33
34
  it "returns the basename of the file" do
34
35
  attachment = mock
35
- attachment.expects(:original_filename).returns("one.jpg").times(2)
36
+ attachment.expects(:original_filename).returns("one.jpg").times(1)
36
37
  assert_equal "one", Paperclip::Interpolations.basename(attachment, :style)
37
38
  end
38
39
 
@@ -187,14 +188,14 @@ describe Paperclip::Interpolations do
187
188
  it "returns the filename as basename.extension" do
188
189
  attachment = mock
189
190
  attachment.expects(:styles).returns({})
190
- attachment.expects(:original_filename).returns("one.jpg").times(3)
191
+ attachment.expects(:original_filename).returns("one.jpg").times(2)
191
192
  assert_equal "one.jpg", Paperclip::Interpolations.filename(attachment, :style)
192
193
  end
193
194
 
194
195
  it "returns the filename as basename.extension when format supplied" do
195
196
  attachment = mock
196
197
  attachment.expects(:styles).returns({style: {format: :png}})
197
- attachment.expects(:original_filename).returns("one.jpg").times(2)
198
+ attachment.expects(:original_filename).returns("one.jpg").times(1)
198
199
  assert_equal "one.png", Paperclip::Interpolations.filename(attachment, :style)
199
200
  end
200
201
 
@@ -249,4 +250,13 @@ describe Paperclip::Interpolations do
249
250
  value = Paperclip::Interpolations.interpolate(":notreal/:id/:attachment", :attachment, :style)
250
251
  assert_equal ":notreal/1234/attachments", value
251
252
  end
253
+
254
+ it "handles question marks" do
255
+ Paperclip.interpolates :foo? do
256
+ "bar"
257
+ end
258
+ Paperclip::Interpolations.expects(:fool).never
259
+ value = Paperclip::Interpolations.interpolate(":fo/:foo?")
260
+ assert_equal ":fo/bar", value
261
+ end
252
262
  end
@@ -3,34 +3,35 @@ require 'spec_helper'
3
3
  describe 'Plural cache' do
4
4
  it 'caches pluralizations' do
5
5
  cache = Paperclip::Interpolations::PluralCache.new
6
- word = "box"
6
+ symbol = :box
7
7
 
8
- word.expects(:pluralize).returns("boxes").once
9
-
10
- cache.pluralize(word)
11
- cache.pluralize(word)
8
+ first = cache.pluralize_symbol(symbol)
9
+ second = cache.pluralize_symbol(symbol)
10
+ expect(first).to equal(second)
12
11
  end
13
12
 
14
13
  it 'caches pluralizations and underscores' do
14
+ class BigBox ; end
15
15
  cache = Paperclip::Interpolations::PluralCache.new
16
- word = "BigBox"
17
-
18
- word.expects(:pluralize).returns(word).once
19
- word.expects(:underscore).returns(word).once
16
+ klass = BigBox
20
17
 
21
- cache.underscore_and_pluralize(word)
22
- cache.underscore_and_pluralize(word)
18
+ first = cache.underscore_and_pluralize_class(klass)
19
+ second = cache.underscore_and_pluralize_class(klass)
20
+ expect(first).to equal(second)
23
21
  end
24
22
 
25
23
  it 'pluralizes words' do
26
24
  cache = Paperclip::Interpolations::PluralCache.new
27
- word = "box"
28
- assert_equal "boxes", cache.pluralize(word)
25
+ symbol = :box
26
+
27
+ expect(cache.pluralize_symbol(symbol)).to eq("boxes")
29
28
  end
30
29
 
31
- it 'pluralizes and underscore words' do
30
+ it 'pluralizes and underscore class names' do
31
+ class BigBox ; end
32
32
  cache = Paperclip::Interpolations::PluralCache.new
33
- word = "BigBox"
34
- assert_equal "big_boxes", cache.underscore_and_pluralize(word)
33
+ klass = BigBox
34
+
35
+ expect(cache.underscore_and_pluralize_class(klass)).to eq("big_boxes")
35
36
  end
36
37
  end
@@ -1,5 +1,6 @@
1
1
  require 'spec_helper'
2
- require 'fog'
2
+ require 'fog/aws'
3
+ require 'fog/local'
3
4
  require 'timecop'
4
5
 
5
6
  describe Paperclip::Storage::Fog do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paperclip
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.1
4
+ version: 4.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Yurek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-10 00:00:00.000000000 Z
11
+ date: 2015-11-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -200,6 +200,20 @@ dependencies:
200
200
  version: 1.3.18
201
201
  - !ruby/object:Gem::Dependency
202
202
  name: aruba
203
+ requirement: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - "~>"
206
+ - !ruby/object:Gem::Version
207
+ version: 0.9.0
208
+ type: :development
209
+ prerelease: false
210
+ version_requirements: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - "~>"
213
+ - !ruby/object:Gem::Version
214
+ version: 0.9.0
215
+ - !ruby/object:Gem::Dependency
216
+ name: nokogiri
203
217
  requirement: !ruby/object:Gem::Requirement
204
218
  requirements:
205
219
  - - ">="
@@ -213,7 +227,7 @@ dependencies:
213
227
  - !ruby/object:Gem::Version
214
228
  version: '0'
215
229
  - !ruby/object:Gem::Dependency
216
- name: nokogiri
230
+ name: capybara
217
231
  requirement: !ruby/object:Gem::Requirement
218
232
  requirements:
219
233
  - - ">="
@@ -227,7 +241,7 @@ dependencies:
227
241
  - !ruby/object:Gem::Version
228
242
  version: '0'
229
243
  - !ruby/object:Gem::Dependency
230
- name: capybara
244
+ name: bundler
231
245
  requirement: !ruby/object:Gem::Requirement
232
246
  requirements:
233
247
  - - ">="
@@ -241,7 +255,7 @@ dependencies:
241
255
  - !ruby/object:Gem::Version
242
256
  version: '0'
243
257
  - !ruby/object:Gem::Dependency
244
- name: bundler
258
+ name: fog-aws
245
259
  requirement: !ruby/object:Gem::Requirement
246
260
  requirements:
247
261
  - - ">="
@@ -255,19 +269,19 @@ dependencies:
255
269
  - !ruby/object:Gem::Version
256
270
  version: '0'
257
271
  - !ruby/object:Gem::Dependency
258
- name: fog
272
+ name: fog-local
259
273
  requirement: !ruby/object:Gem::Requirement
260
274
  requirements:
261
- - - "~>"
275
+ - - ">="
262
276
  - !ruby/object:Gem::Version
263
- version: '1.0'
277
+ version: '0'
264
278
  type: :development
265
279
  prerelease: false
266
280
  version_requirements: !ruby/object:Gem::Requirement
267
281
  requirements:
268
- - - "~>"
282
+ - - ">="
269
283
  - !ruby/object:Gem::Version
270
- version: '1.0'
284
+ version: '0'
271
285
  - !ruby/object:Gem::Dependency
272
286
  name: launchy
273
287
  requirement: !ruby/object:Gem::Requirement