paperclip 2.4.4 → 2.4.5
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.
- data/lib/paperclip.rb +8 -4
- data/lib/paperclip/attachment.rb +51 -5
- data/lib/paperclip/interpolations.rb +2 -6
- data/lib/paperclip/storage/fog.rb +2 -1
- data/lib/paperclip/storage/s3.rb +12 -4
- data/lib/paperclip/version.rb +1 -1
- data/test/attachment_test.rb +34 -0
- data/test/fog_test.rb +1 -0
- data/test/helper.rb +2 -0
- data/test/interpolations_test.rb +1 -1
- data/test/paperclip_test.rb +3 -2
- data/test/storage/s3_test.rb +59 -6
- metadata +106 -163
- data/lib/paperclip/interpolated_string.rb +0 -33
- data/test/interpolated_string_test.rb +0 -62
data/lib/paperclip.rb
CHANGED
@@ -387,10 +387,14 @@ module Paperclip
|
|
387
387
|
# * +unless+: Same as +if+ but validates if lambda or method returns false.
|
388
388
|
def validates_attachment_presence name, options = {}
|
389
389
|
message = options[:message] || :empty
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
390
|
+
validates_each :"#{name}_file_name" do |record, attr, value|
|
391
|
+
if_clause_passed = options[:if].nil? || (options[:if].call(record) != false)
|
392
|
+
unless_clause_passed = options[:unless].nil? || (!!options[:unless].call(record) == false)
|
393
|
+
if if_clause_passed && unless_clause_passed && value.blank?
|
394
|
+
record.errors.add(name, message)
|
395
|
+
record.errors.add("#{name}_file_name", message)
|
396
|
+
end
|
397
|
+
end
|
394
398
|
end
|
395
399
|
|
396
400
|
# Places ActiveRecord-style validations on the content type of the file
|
data/lib/paperclip/attachment.rb
CHANGED
@@ -94,6 +94,8 @@ module Paperclip
|
|
94
94
|
uploaded_filename = uploaded_file.original_filename
|
95
95
|
uploaded_file = uploaded_file.to_file(:original)
|
96
96
|
close_uploaded_file = uploaded_file.respond_to?(:close)
|
97
|
+
else
|
98
|
+
instance_write(:uploaded_file, uploaded_file) if uploaded_file
|
97
99
|
end
|
98
100
|
|
99
101
|
return nil unless valid_assignment?(uploaded_file)
|
@@ -128,12 +130,13 @@ module Paperclip
|
|
128
130
|
# grained security. This is not recommended if you don't need the
|
129
131
|
# security, however, for performance reasons. Set use_timestamp to false
|
130
132
|
# if you want to stop the attachment update time appended to the url
|
131
|
-
def url(style_name = default_style,
|
132
|
-
|
133
|
-
url =
|
133
|
+
def url(style_name = default_style, options = {})
|
134
|
+
options = handle_url_options(options)
|
135
|
+
url = interpolate(most_appropriate_url, style_name)
|
134
136
|
|
135
|
-
url
|
136
|
-
url
|
137
|
+
url = url_timestamp(url) if options[:timestamp]
|
138
|
+
url = escape_url(url) if options[:escape]
|
139
|
+
url
|
137
140
|
end
|
138
141
|
|
139
142
|
# Returns the path of the attachment as defined by the :path option. If the
|
@@ -196,6 +199,11 @@ module Paperclip
|
|
196
199
|
end
|
197
200
|
end
|
198
201
|
|
202
|
+
# Returns the uploaded file if present.
|
203
|
+
def uploaded_file
|
204
|
+
instance_read(:uploaded_file)
|
205
|
+
end
|
206
|
+
|
199
207
|
# Returns the name of the file as originally assigned, and lives in the
|
200
208
|
# <attachment>_file_name attribute of the model.
|
201
209
|
def original_filename
|
@@ -320,6 +328,44 @@ module Paperclip
|
|
320
328
|
|
321
329
|
private
|
322
330
|
|
331
|
+
def handle_url_options(options)
|
332
|
+
timestamp = extract_timestamp(options)
|
333
|
+
options = {} if options == true || options == false
|
334
|
+
options[:timestamp] = timestamp
|
335
|
+
options[:escape] = true if options[:escape].nil?
|
336
|
+
options
|
337
|
+
end
|
338
|
+
|
339
|
+
def extract_timestamp(options)
|
340
|
+
possibilities = [((options == true || options == false) ? options : nil),
|
341
|
+
(options.respond_to?(:[]) ? options[:timestamp] : nil),
|
342
|
+
@options.use_timestamp]
|
343
|
+
possibilities.find{|n| !n.nil? }
|
344
|
+
end
|
345
|
+
|
346
|
+
def default_url
|
347
|
+
return @options.default_url.call(self) if @options.default_url.is_a?(Proc)
|
348
|
+
@options.default_url
|
349
|
+
end
|
350
|
+
|
351
|
+
def most_appropriate_url
|
352
|
+
if original_filename.nil?
|
353
|
+
default_url
|
354
|
+
else
|
355
|
+
@options.url
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
def url_timestamp(url)
|
360
|
+
return url unless updated_at
|
361
|
+
delimiter_char = url.include?("?") ? "&" : "?"
|
362
|
+
"#{url}#{delimiter_char}#{updated_at.to_s}"
|
363
|
+
end
|
364
|
+
|
365
|
+
def escape_url(url)
|
366
|
+
url.respond_to?(:escape) ? url.escape : URI.escape(url)
|
367
|
+
end
|
368
|
+
|
323
369
|
def ensure_required_accessors! #:nodoc:
|
324
370
|
%w(file_name).each do |field|
|
325
371
|
unless @instance.respond_to?("#{name}_#{field}") && @instance.respond_to?("#{name}_#{field}=")
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'paperclip/interpolated_string'
|
2
|
-
|
3
1
|
module Paperclip
|
4
2
|
# This module contains all the methods that are available for interpolation
|
5
3
|
# in paths and urls. To add your own (or override an existing one), you
|
@@ -31,13 +29,11 @@ module Paperclip
|
|
31
29
|
# an interpolation pattern for Paperclip to use.
|
32
30
|
def self.interpolate pattern, *args
|
33
31
|
pattern = args.first.instance.send(pattern) if pattern.kind_of? Symbol
|
34
|
-
|
32
|
+
all.reverse.inject(pattern) do |result, tag|
|
35
33
|
result.gsub(/:#{tag}/) do |match|
|
36
34
|
send( tag, *args )
|
37
35
|
end
|
38
36
|
end
|
39
|
-
interpolated_string.force_escape if pattern =~ /:url/
|
40
|
-
interpolated_string
|
41
37
|
end
|
42
38
|
|
43
39
|
# Returns the filename, the same way as ":basename.:extension" would.
|
@@ -51,7 +47,7 @@ module Paperclip
|
|
51
47
|
RIGHT_HERE = "#{__FILE__.gsub(%r{^\./}, "")}:#{__LINE__ + 3}"
|
52
48
|
def url attachment, style_name
|
53
49
|
raise InfiniteInterpolationError if caller.any?{|b| b.index(RIGHT_HERE) }
|
54
|
-
attachment.url(style_name, false)
|
50
|
+
attachment.url(style_name, :timestamp => false, :escape => false)
|
55
51
|
end
|
56
52
|
|
57
53
|
# Returns the timestamp as defined by the <attachment>_updated_at field
|
data/lib/paperclip/storage/s3.rb
CHANGED
@@ -80,8 +80,10 @@ module Paperclip
|
|
80
80
|
@s3_options = @options.s3_options || {}
|
81
81
|
@s3_permissions = set_permissions(@options.s3_permissions)
|
82
82
|
@s3_protocol = @options.s3_protocol ||
|
83
|
-
Proc.new do |style|
|
84
|
-
(@s3_permissions[style.to_sym] || @s3_permissions[:default])
|
83
|
+
Proc.new do |style, attachment|
|
84
|
+
permission = (@s3_permissions[style.to_sym] || @s3_permissions[:default])
|
85
|
+
permission = permission.call(attachment, style) if permission.is_a?(Proc)
|
86
|
+
(permission == :public_read) ? 'http' : 'https'
|
85
87
|
end
|
86
88
|
@s3_headers = @options.s3_headers || {}
|
87
89
|
|
@@ -182,9 +184,15 @@ module Paperclip
|
|
182
184
|
end
|
183
185
|
end
|
184
186
|
|
187
|
+
def s3_permissions(style = default_style)
|
188
|
+
s3_permissions = @s3_permissions[style] || @s3_permissions[:default]
|
189
|
+
s3_permissions = s3_permissions.call(self, style) if s3_permissions.is_a?(Proc)
|
190
|
+
s3_permissions
|
191
|
+
end
|
192
|
+
|
185
193
|
def s3_protocol(style = default_style)
|
186
194
|
if @s3_protocol.is_a?(Proc)
|
187
|
-
@s3_protocol.call(style)
|
195
|
+
@s3_protocol.call(style, self)
|
188
196
|
else
|
189
197
|
@s3_protocol
|
190
198
|
end
|
@@ -216,7 +224,7 @@ module Paperclip
|
|
216
224
|
file,
|
217
225
|
bucket_name,
|
218
226
|
{:content_type => file.content_type.to_s.strip,
|
219
|
-
:access => (
|
227
|
+
:access => s3_permissions(style),
|
220
228
|
}.merge(@s3_headers))
|
221
229
|
rescue AWS::S3::NoSuchBucket => e
|
222
230
|
create_bucket
|
data/lib/paperclip/version.rb
CHANGED
data/test/attachment_test.rb
CHANGED
@@ -160,6 +160,36 @@ class AttachmentTest < Test::Unit::TestCase
|
|
160
160
|
end
|
161
161
|
end
|
162
162
|
|
163
|
+
context "An attachment" do
|
164
|
+
setup do
|
165
|
+
@file = StringIO.new("...")
|
166
|
+
end
|
167
|
+
|
168
|
+
context "using default time zone" do
|
169
|
+
setup do
|
170
|
+
rebuild_model :url => "X"
|
171
|
+
@dummy = Dummy.new
|
172
|
+
@dummy.avatar = @file
|
173
|
+
end
|
174
|
+
|
175
|
+
should "generate a url with a timestamp when passing true" do
|
176
|
+
assert_equal "X?#{@dummy.avatar_updated_at.to_i.to_s}", @dummy.avatar.url(:style, true)
|
177
|
+
end
|
178
|
+
|
179
|
+
should "not generate a url with a timestamp when passing false" do
|
180
|
+
assert_equal "X", @dummy.avatar.url(:style, false)
|
181
|
+
end
|
182
|
+
|
183
|
+
should "generate a url with a timestamp when setting a timestamp option" do
|
184
|
+
assert_equal "X?#{@dummy.avatar_updated_at.to_i.to_s}", @dummy.avatar.url(:style, :timestamp => true)
|
185
|
+
end
|
186
|
+
|
187
|
+
should "not generate a url with a timestamp when setting a timestamp option to false" do
|
188
|
+
assert_equal "X", @dummy.avatar.url(:style, :timestamp => false)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
163
193
|
context "An attachment with :hash interpolations" do
|
164
194
|
setup do
|
165
195
|
@file = StringIO.new("...")
|
@@ -825,6 +855,10 @@ class AttachmentTest < Test::Unit::TestCase
|
|
825
855
|
assert @attachment.dirty?
|
826
856
|
end
|
827
857
|
|
858
|
+
should "set uploaded_file for access beyond the paperclip lifecycle" do
|
859
|
+
assert_equal @file, @attachment.uploaded_file
|
860
|
+
end
|
861
|
+
|
828
862
|
context "and saved" do
|
829
863
|
setup do
|
830
864
|
@attachment.save
|
data/test/fog_test.rb
CHANGED
data/test/helper.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'tempfile'
|
3
|
+
require 'pathname'
|
3
4
|
require 'test/unit'
|
4
5
|
|
5
6
|
require 'shoulda'
|
@@ -10,6 +11,7 @@ require 'active_record/version'
|
|
10
11
|
require 'active_support'
|
11
12
|
require 'mime/types'
|
12
13
|
require 'pry'
|
14
|
+
require 'pathname'
|
13
15
|
|
14
16
|
puts "Testing against version #{ActiveRecord::VERSION::STRING}"
|
15
17
|
|
data/test/interpolations_test.rb
CHANGED
@@ -120,7 +120,7 @@ class InterpolationsTest < Test::Unit::TestCase
|
|
120
120
|
|
121
121
|
should "reinterpolate :url" do
|
122
122
|
attachment = mock
|
123
|
-
attachment.expects(:url).with(:style, false).returns("1234")
|
123
|
+
attachment.expects(:url).with(:style, :timestamp => false, :escape => false).returns("1234")
|
124
124
|
assert_equal "1234", Paperclip::Interpolations.url(attachment, :style)
|
125
125
|
end
|
126
126
|
|
data/test/paperclip_test.rb
CHANGED
@@ -225,6 +225,7 @@ class PaperclipTest < Test::Unit::TestCase
|
|
225
225
|
end
|
226
226
|
if validation == :presence
|
227
227
|
should "have an error on the attachment" do
|
228
|
+
assert @dummy.errors[:avatar]
|
228
229
|
assert @dummy.errors[:avatar_file_name]
|
229
230
|
end
|
230
231
|
else
|
@@ -238,7 +239,7 @@ class PaperclipTest < Test::Unit::TestCase
|
|
238
239
|
@dummy.avatar = valid_file
|
239
240
|
@dummy.valid?
|
240
241
|
end
|
241
|
-
should "not have an error
|
242
|
+
should "not have an error" do
|
242
243
|
assert_equal 0, @dummy.errors.size, @dummy.errors.full_messages.join(", ")
|
243
244
|
end
|
244
245
|
end
|
@@ -247,7 +248,7 @@ class PaperclipTest < Test::Unit::TestCase
|
|
247
248
|
@dummy.avatar = invalid_file
|
248
249
|
@dummy.valid?
|
249
250
|
end
|
250
|
-
should "have an error
|
251
|
+
should "have an error" do
|
251
252
|
assert @dummy.errors.size > 0
|
252
253
|
end
|
253
254
|
end
|
data/test/storage/s3_test.rb
CHANGED
@@ -509,7 +509,7 @@ class S3Test < Test::Unit::TestCase
|
|
509
509
|
end
|
510
510
|
|
511
511
|
context "S3 Permissions" do
|
512
|
-
context "defaults to
|
512
|
+
context "defaults to :public_read" do
|
513
513
|
setup do
|
514
514
|
rebuild_model :storage => :s3,
|
515
515
|
:bucket => "testing",
|
@@ -556,7 +556,7 @@ class S3Test < Test::Unit::TestCase
|
|
556
556
|
'access_key_id' => "12345",
|
557
557
|
'secret_access_key' => "54321"
|
558
558
|
},
|
559
|
-
:s3_permissions =>
|
559
|
+
:s3_permissions => :private
|
560
560
|
end
|
561
561
|
|
562
562
|
context "when assigned" do
|
@@ -575,7 +575,7 @@ class S3Test < Test::Unit::TestCase
|
|
575
575
|
anything,
|
576
576
|
'testing',
|
577
577
|
:content_type => 'image/png',
|
578
|
-
:access =>
|
578
|
+
:access => :private)
|
579
579
|
@dummy.save
|
580
580
|
end
|
581
581
|
|
@@ -599,8 +599,8 @@ class S3Test < Test::Unit::TestCase
|
|
599
599
|
'secret_access_key' => "54321"
|
600
600
|
},
|
601
601
|
:s3_permissions => {
|
602
|
-
:original =>
|
603
|
-
:thumb =>
|
602
|
+
:original => :private,
|
603
|
+
:thumb => :public_read
|
604
604
|
}
|
605
605
|
end
|
606
606
|
|
@@ -621,7 +621,7 @@ class S3Test < Test::Unit::TestCase
|
|
621
621
|
anything,
|
622
622
|
'testing',
|
623
623
|
:content_type => 'image/png',
|
624
|
-
:access => style == :thumb ?
|
624
|
+
:access => style == :thumb ? :public_read : :private)
|
625
625
|
end
|
626
626
|
@dummy.save
|
627
627
|
end
|
@@ -632,5 +632,58 @@ class S3Test < Test::Unit::TestCase
|
|
632
632
|
end
|
633
633
|
end
|
634
634
|
end
|
635
|
+
|
636
|
+
context "proc permission set" do
|
637
|
+
setup do
|
638
|
+
rebuild_model(
|
639
|
+
:storage => :s3,
|
640
|
+
:bucket => "testing",
|
641
|
+
:path => ":attachment/:style/:basename.:extension",
|
642
|
+
:styles => {
|
643
|
+
:thumb => "80x80>"
|
644
|
+
},
|
645
|
+
:s3_credentials => {
|
646
|
+
'access_key_id' => "12345",
|
647
|
+
'secret_access_key' => "54321"
|
648
|
+
},
|
649
|
+
:s3_permissions => lambda {|attachment, style|
|
650
|
+
attachment.instance.private_attachment? && style.to_sym != :thumb ? :private : :public_read
|
651
|
+
}
|
652
|
+
)
|
653
|
+
end
|
654
|
+
|
655
|
+
context "when assigned" do
|
656
|
+
setup do
|
657
|
+
@file = File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', '5k.png'), 'rb')
|
658
|
+
@dummy = Dummy.new
|
659
|
+
@dummy.stubs(:private_attachment? => true)
|
660
|
+
@dummy.avatar = @file
|
661
|
+
end
|
662
|
+
|
663
|
+
teardown { @file.close }
|
664
|
+
|
665
|
+
context "and saved" do
|
666
|
+
setup do
|
667
|
+
AWS::S3::Base.stubs(:establish_connection!)
|
668
|
+
[:thumb, :original].each do |style|
|
669
|
+
AWS::S3::S3Object.expects(:store).with(
|
670
|
+
"avatars/#{style}/5k.png",
|
671
|
+
anything,
|
672
|
+
'testing',
|
673
|
+
:content_type => 'image/png',
|
674
|
+
:access => style == :thumb ? :public_read : :private
|
675
|
+
)
|
676
|
+
end
|
677
|
+
@dummy.save
|
678
|
+
end
|
679
|
+
|
680
|
+
should "succeed" do
|
681
|
+
assert @dummy.avatar.url().include? "https://"
|
682
|
+
assert @dummy.avatar.url(:thumb).include? "http://"
|
683
|
+
end
|
684
|
+
end
|
685
|
+
end
|
686
|
+
|
687
|
+
end
|
635
688
|
end
|
636
689
|
end
|
metadata
CHANGED
@@ -1,191 +1,144 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: paperclip
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.4.5
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 2
|
8
|
-
- 4
|
9
|
-
- 4
|
10
|
-
version: 2.4.4
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Jon Yurek
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-10-21 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: activerecord
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70180663783480 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
hash: 3
|
29
|
-
segments:
|
30
|
-
- 2
|
31
|
-
- 3
|
32
|
-
- 0
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
33
21
|
version: 2.3.0
|
34
22
|
type: :runtime
|
35
|
-
version_requirements: *id001
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: activesupport
|
38
23
|
prerelease: false
|
39
|
-
|
24
|
+
version_requirements: *70180663783480
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activesupport
|
27
|
+
requirement: &70180663782680 !ruby/object:Gem::Requirement
|
40
28
|
none: false
|
41
|
-
requirements:
|
42
|
-
- -
|
43
|
-
- !ruby/object:Gem::Version
|
44
|
-
hash: 7
|
45
|
-
segments:
|
46
|
-
- 2
|
47
|
-
- 3
|
48
|
-
- 2
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
49
32
|
version: 2.3.2
|
50
33
|
type: :runtime
|
51
|
-
version_requirements: *id002
|
52
|
-
- !ruby/object:Gem::Dependency
|
53
|
-
name: cocaine
|
54
34
|
prerelease: false
|
55
|
-
|
35
|
+
version_requirements: *70180663782680
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: cocaine
|
38
|
+
requirement: &70180663782140 !ruby/object:Gem::Requirement
|
56
39
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
hash: 27
|
61
|
-
segments:
|
62
|
-
- 0
|
63
|
-
- 0
|
64
|
-
- 2
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
65
43
|
version: 0.0.2
|
66
44
|
type: :runtime
|
67
|
-
version_requirements: *id003
|
68
|
-
- !ruby/object:Gem::Dependency
|
69
|
-
name: mime-types
|
70
45
|
prerelease: false
|
71
|
-
|
46
|
+
version_requirements: *70180663782140
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: mime-types
|
49
|
+
requirement: &70180663781760 !ruby/object:Gem::Requirement
|
72
50
|
none: false
|
73
|
-
requirements:
|
74
|
-
- -
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
|
77
|
-
segments:
|
78
|
-
- 0
|
79
|
-
version: "0"
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
80
55
|
type: :runtime
|
81
|
-
version_requirements: *id004
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: shoulda
|
84
56
|
prerelease: false
|
85
|
-
|
57
|
+
version_requirements: *70180663781760
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: shoulda
|
60
|
+
requirement: &70180663781280 !ruby/object:Gem::Requirement
|
86
61
|
none: false
|
87
|
-
requirements:
|
88
|
-
- -
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
|
91
|
-
segments:
|
92
|
-
- 0
|
93
|
-
version: "0"
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
94
66
|
type: :development
|
95
|
-
version_requirements: *id005
|
96
|
-
- !ruby/object:Gem::Dependency
|
97
|
-
name: appraisal
|
98
67
|
prerelease: false
|
99
|
-
|
68
|
+
version_requirements: *70180663781280
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: appraisal
|
71
|
+
requirement: &70180663780840 !ruby/object:Gem::Requirement
|
100
72
|
none: false
|
101
|
-
requirements:
|
102
|
-
- -
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
|
105
|
-
segments:
|
106
|
-
- 0
|
107
|
-
version: "0"
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
108
77
|
type: :development
|
109
|
-
version_requirements: *id006
|
110
|
-
- !ruby/object:Gem::Dependency
|
111
|
-
name: mocha
|
112
78
|
prerelease: false
|
113
|
-
|
79
|
+
version_requirements: *70180663780840
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: mocha
|
82
|
+
requirement: &70180663780420 !ruby/object:Gem::Requirement
|
114
83
|
none: false
|
115
|
-
requirements:
|
116
|
-
- -
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
|
119
|
-
segments:
|
120
|
-
- 0
|
121
|
-
version: "0"
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
122
88
|
type: :development
|
123
|
-
version_requirements: *id007
|
124
|
-
- !ruby/object:Gem::Dependency
|
125
|
-
name: aws-s3
|
126
89
|
prerelease: false
|
127
|
-
|
90
|
+
version_requirements: *70180663780420
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: aws-s3
|
93
|
+
requirement: &70180663779980 !ruby/object:Gem::Requirement
|
128
94
|
none: false
|
129
|
-
requirements:
|
130
|
-
- -
|
131
|
-
- !ruby/object:Gem::Version
|
132
|
-
|
133
|
-
segments:
|
134
|
-
- 0
|
135
|
-
version: "0"
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
136
99
|
type: :development
|
137
|
-
version_requirements: *id008
|
138
|
-
- !ruby/object:Gem::Dependency
|
139
|
-
name: sqlite3
|
140
100
|
prerelease: false
|
141
|
-
|
101
|
+
version_requirements: *70180663779980
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: sqlite3
|
104
|
+
requirement: &70180663779560 !ruby/object:Gem::Requirement
|
142
105
|
none: false
|
143
|
-
requirements:
|
144
|
-
- -
|
145
|
-
- !ruby/object:Gem::Version
|
146
|
-
|
147
|
-
segments:
|
148
|
-
- 0
|
149
|
-
version: "0"
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
150
110
|
type: :development
|
151
|
-
version_requirements: *id009
|
152
|
-
- !ruby/object:Gem::Dependency
|
153
|
-
name: cucumber
|
154
111
|
prerelease: false
|
155
|
-
|
112
|
+
version_requirements: *70180663779560
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: cucumber
|
115
|
+
requirement: &70180663779140 !ruby/object:Gem::Requirement
|
156
116
|
none: false
|
157
|
-
requirements:
|
158
|
-
- -
|
159
|
-
- !ruby/object:Gem::Version
|
160
|
-
|
161
|
-
segments:
|
162
|
-
- 0
|
163
|
-
version: "0"
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
164
121
|
type: :development
|
165
|
-
version_requirements: *id010
|
166
|
-
- !ruby/object:Gem::Dependency
|
167
|
-
name: capybara
|
168
122
|
prerelease: false
|
169
|
-
|
123
|
+
version_requirements: *70180663779140
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: capybara
|
126
|
+
requirement: &70180663778720 !ruby/object:Gem::Requirement
|
170
127
|
none: false
|
171
|
-
requirements:
|
172
|
-
- -
|
173
|
-
- !ruby/object:Gem::Version
|
174
|
-
|
175
|
-
segments:
|
176
|
-
- 0
|
177
|
-
version: "0"
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
178
132
|
type: :development
|
179
|
-
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: *70180663778720
|
180
135
|
description: Easy upload management for ActiveRecord
|
181
136
|
email: jyurek@thoughtbot.com
|
182
137
|
executables: []
|
183
|
-
|
184
138
|
extensions: []
|
185
|
-
|
186
|
-
extra_rdoc_files:
|
139
|
+
extra_rdoc_files:
|
187
140
|
- README.md
|
188
|
-
files:
|
141
|
+
files:
|
189
142
|
- README.md
|
190
143
|
- LICENSE
|
191
144
|
- Rakefile
|
@@ -196,7 +149,6 @@ files:
|
|
196
149
|
- lib/paperclip/attachment.rb
|
197
150
|
- lib/paperclip/callback_compatibility.rb
|
198
151
|
- lib/paperclip/geometry.rb
|
199
|
-
- lib/paperclip/interpolated_string.rb
|
200
152
|
- lib/paperclip/interpolations.rb
|
201
153
|
- lib/paperclip/iostream.rb
|
202
154
|
- lib/paperclip/matchers/have_attached_file_matcher.rb
|
@@ -235,7 +187,6 @@ files:
|
|
235
187
|
- test/geometry_test.rb
|
236
188
|
- test/helper.rb
|
237
189
|
- test/integration_test.rb
|
238
|
-
- test/interpolated_string_test.rb
|
239
190
|
- test/interpolations_test.rb
|
240
191
|
- test/iostream_test.rb
|
241
192
|
- test/matchers/have_attached_file_matcher_test.rb
|
@@ -259,32 +210,25 @@ files:
|
|
259
210
|
- shoulda_macros/paperclip.rb
|
260
211
|
homepage: https://github.com/thoughtbot/paperclip
|
261
212
|
licenses: []
|
262
|
-
|
263
213
|
post_install_message:
|
264
|
-
rdoc_options:
|
214
|
+
rdoc_options:
|
265
215
|
- --line-numbers
|
266
216
|
- --inline-source
|
267
|
-
require_paths:
|
217
|
+
require_paths:
|
268
218
|
- lib
|
269
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
219
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
270
220
|
none: false
|
271
|
-
requirements:
|
272
|
-
- -
|
273
|
-
- !ruby/object:Gem::Version
|
274
|
-
|
275
|
-
|
276
|
-
- 0
|
277
|
-
version: "0"
|
278
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
221
|
+
requirements:
|
222
|
+
- - ! '>='
|
223
|
+
- !ruby/object:Gem::Version
|
224
|
+
version: '0'
|
225
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
279
226
|
none: false
|
280
|
-
requirements:
|
281
|
-
- -
|
282
|
-
- !ruby/object:Gem::Version
|
283
|
-
|
284
|
-
|
285
|
-
- 0
|
286
|
-
version: "0"
|
287
|
-
requirements:
|
227
|
+
requirements:
|
228
|
+
- - ! '>='
|
229
|
+
- !ruby/object:Gem::Version
|
230
|
+
version: '0'
|
231
|
+
requirements:
|
288
232
|
- ImageMagick
|
289
233
|
rubyforge_project: paperclip
|
290
234
|
rubygems_version: 1.8.10
|
@@ -292,4 +236,3 @@ signing_key:
|
|
292
236
|
specification_version: 3
|
293
237
|
summary: File attachments as attributes for ActiveRecord
|
294
238
|
test_files: []
|
295
|
-
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'uri'
|
2
|
-
|
3
|
-
module Paperclip
|
4
|
-
class InterpolatedString < String
|
5
|
-
def escaped?
|
6
|
-
!!@escaped
|
7
|
-
end
|
8
|
-
|
9
|
-
def escape
|
10
|
-
if !escaped?
|
11
|
-
escaped_string = self.class.new(URI.escape(self))
|
12
|
-
escaped_string.instance_variable_set(:@escaped, true)
|
13
|
-
escaped_string
|
14
|
-
else
|
15
|
-
self
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def unescape
|
20
|
-
if escaped?
|
21
|
-
escaped_string = self.class.new(URI.unescape(self))
|
22
|
-
escaped_string.instance_variable_set(:@escaped, false)
|
23
|
-
escaped_string
|
24
|
-
else
|
25
|
-
self
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def force_escape
|
30
|
-
@escaped = true
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require './test/helper'
|
2
|
-
|
3
|
-
class InterpolatedStringTest < Test::Unit::TestCase
|
4
|
-
context "inheritance" do
|
5
|
-
should "inherited from String" do
|
6
|
-
assert Paperclip::InterpolatedString.new("paperclip").is_a? String
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
context "#escape" do
|
11
|
-
subject { Paperclip::InterpolatedString.new("paperclip foo").escape }
|
12
|
-
|
13
|
-
should "returns an InterpolatedString object" do
|
14
|
-
assert subject.is_a? Paperclip::InterpolatedString
|
15
|
-
end
|
16
|
-
|
17
|
-
should "escape the output string" do
|
18
|
-
assert_equal "paperclip%20foo", subject
|
19
|
-
end
|
20
|
-
|
21
|
-
should "not double escape output string" do
|
22
|
-
assert_equal "paperclip%20foo", subject.escape
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context "#unescape" do
|
27
|
-
subject { Paperclip::InterpolatedString.new("paperclip%20foo").escape.unescape }
|
28
|
-
|
29
|
-
should "returns an InterpolatedString object" do
|
30
|
-
assert subject.is_a? Paperclip::InterpolatedString
|
31
|
-
end
|
32
|
-
|
33
|
-
should "unescape the output string" do
|
34
|
-
assert_equal "paperclip%20foo", subject
|
35
|
-
end
|
36
|
-
|
37
|
-
should "not double unescape output string" do
|
38
|
-
assert_equal "paperclip%20foo", subject.unescape
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
context "#escaped?" do
|
43
|
-
subject { Paperclip::InterpolatedString.new("paperclip") }
|
44
|
-
|
45
|
-
should "returns true if string was escaped" do
|
46
|
-
assert subject.escape.escaped?
|
47
|
-
end
|
48
|
-
|
49
|
-
should "returns false if string wasn't escaped" do
|
50
|
-
assert !subject.escaped?
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
context "#force_escape" do
|
55
|
-
subject { Paperclip::InterpolatedString.new("paperclip") }
|
56
|
-
setup { subject.force_escape }
|
57
|
-
|
58
|
-
should "sets escaped flag to true" do
|
59
|
-
assert subject.escaped?
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|