paperclip 3.1.4 → 3.2.0
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/NEWS +9 -0
- data/README.md +159 -106
- data/lib/paperclip/attachment.rb +1 -1
- data/lib/paperclip/instance_methods.rb +2 -2
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +1 -1
- data/lib/paperclip/storage/fog.rb +12 -5
- data/lib/paperclip/storage/s3.rb +6 -4
- data/lib/paperclip/thumbnail.rb +3 -1
- data/lib/paperclip/version.rb +1 -1
- data/lib/tasks/paperclip.rake +4 -3
- data/test/fixtures/rotated.jpg +0 -0
- data/test/helper.rb +7 -0
- data/test/io_adapters/uploaded_file_adapter_test.rb +1 -1
- data/test/meta_class_test.rb +32 -0
- data/test/storage/fog_test.rb +30 -0
- data/test/storage/s3_test.rb +41 -1
- data/test/thumbnail_test.rb +59 -3
- metadata +8 -75
data/NEWS
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
New in 3.2.0:
|
2
|
+
|
3
|
+
* Bug fix: Use the new correct Amazon S3 encryption header.
|
4
|
+
* Bug fix: The rake task respects the updated_at column.
|
5
|
+
* Bug fix: Strip newline from content type.
|
6
|
+
* Feature: Fog file visibility can be specified per style.
|
7
|
+
* Feature: Autonatically rotate images.
|
8
|
+
* Feature: Reduce class-oriented programming of the attachment definitions.
|
9
|
+
|
1
10
|
New in 3.1.4:
|
2
11
|
|
3
12
|
* Bug fix: Allow user to be able to set path without `:style` attribute and not raising an error.
|
data/README.md
CHANGED
@@ -78,57 +78,71 @@ on GitHub.
|
|
78
78
|
|
79
79
|
For Non-Rails usage:
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
81
|
+
```ruby
|
82
|
+
class ModuleName < ActiveRecord::Base
|
83
|
+
include Paperclip::Glue
|
84
|
+
...
|
85
|
+
end
|
86
|
+
```
|
85
87
|
|
86
88
|
Quick Start
|
87
89
|
-----------
|
88
90
|
|
89
91
|
In your model:
|
90
92
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
93
|
+
```ruby
|
94
|
+
class User < ActiveRecord::Base
|
95
|
+
attr_accessible :avatar
|
96
|
+
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }
|
97
|
+
end
|
98
|
+
```
|
95
99
|
|
96
100
|
In your migrations:
|
97
101
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
+
```ruby
|
103
|
+
class AddAvatarColumnsToUsers < ActiveRecord::Migration
|
104
|
+
def self.up
|
105
|
+
add_attachment :users, :avatar
|
106
|
+
end
|
102
107
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
108
|
+
def self.down
|
109
|
+
remove_attachment :users, :avatar
|
110
|
+
end
|
111
|
+
end
|
112
|
+
```
|
107
113
|
|
108
114
|
(Or you can use migration generator: `rails generate paperclip user avatar`)
|
109
115
|
|
110
116
|
In your edit and new views:
|
111
117
|
|
112
|
-
|
113
|
-
|
114
|
-
|
118
|
+
```erb
|
119
|
+
<%= form_for @user, :url => users_path, :html => { :multipart => true } do |form| %>
|
120
|
+
<%= form.file_field :avatar %>
|
121
|
+
<% end %>
|
122
|
+
```
|
115
123
|
|
116
124
|
In your controller:
|
117
125
|
|
118
|
-
|
119
|
-
|
120
|
-
|
126
|
+
```ruby
|
127
|
+
def create
|
128
|
+
@user = User.create( params[:user] )
|
129
|
+
end
|
130
|
+
```
|
121
131
|
|
122
132
|
In your show view:
|
123
133
|
|
124
|
-
|
125
|
-
|
126
|
-
|
134
|
+
```erb
|
135
|
+
<%= image_tag @user.avatar.url %>
|
136
|
+
<%= image_tag @user.avatar.url(:medium) %>
|
137
|
+
<%= image_tag @user.avatar.url(:thumb) %>
|
138
|
+
```
|
127
139
|
|
128
140
|
To detach a file, simply set the attribute to `nil`:
|
129
141
|
|
130
|
-
|
131
|
-
|
142
|
+
```ruby
|
143
|
+
@user.avatar = nil
|
144
|
+
@user.save
|
145
|
+
```
|
132
146
|
|
133
147
|
Usage
|
134
148
|
-----
|
@@ -160,8 +174,10 @@ For validations, Paperclip introduces several validators to validate your attach
|
|
160
174
|
|
161
175
|
Example Usage:
|
162
176
|
|
163
|
-
|
164
|
-
|
177
|
+
```ruby
|
178
|
+
validates :avatar, :attachment_presence => true
|
179
|
+
validates_with AttachmentPresenceValidator, :attributes => :avatar
|
180
|
+
```
|
165
181
|
|
166
182
|
Validators can also be defined using the old helper style:
|
167
183
|
|
@@ -171,13 +187,17 @@ Validators can also be defined using the old helper style:
|
|
171
187
|
|
172
188
|
Example Usage:
|
173
189
|
|
174
|
-
|
190
|
+
```ruby
|
191
|
+
validates_attachment_presence :avatar
|
192
|
+
```
|
175
193
|
|
176
194
|
Lastly, you can also define multiple validations on a single attachment using `validates_attachment`:
|
177
195
|
|
178
|
-
|
179
|
-
|
180
|
-
|
196
|
+
```ruby
|
197
|
+
validates_attachment :avatar, :presence => true,
|
198
|
+
:content_type => { :content_type => "image/jpg" },
|
199
|
+
:size => { :in => 0..10.kilobytes }
|
200
|
+
```
|
181
201
|
|
182
202
|
Defaults
|
183
203
|
--------
|
@@ -214,43 +234,51 @@ model. There are two types of method:
|
|
214
234
|
|
215
235
|
### Table Definition
|
216
236
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
end
|
237
|
+
```ruby
|
238
|
+
class AddAttachmentToUsers < ActiveRecord::Migration
|
239
|
+
def self.up
|
240
|
+
create_table :users do |t|
|
241
|
+
t.attachment :avatar
|
223
242
|
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
```
|
224
246
|
|
225
247
|
If you're using Rails 3.2 or newer, this method works in `change` method as well:
|
226
248
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
end
|
249
|
+
```ruby
|
250
|
+
class AddAttachmentToUsers < ActiveRecord::Migration
|
251
|
+
def change
|
252
|
+
create_table :users do |t|
|
253
|
+
t.attachment :avatar
|
233
254
|
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
```
|
234
258
|
|
235
259
|
### Schema Definition
|
236
260
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
261
|
+
```ruby
|
262
|
+
class AddAttachmentToUsers < ActiveRecord::Migration
|
263
|
+
def self.up
|
264
|
+
add_attachment :users, :avatar
|
265
|
+
end
|
241
266
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
267
|
+
def self.down
|
268
|
+
remove_attachment :users, :avatar
|
269
|
+
end
|
270
|
+
end
|
271
|
+
```
|
246
272
|
|
247
273
|
If you're using Rails 3.2 or newer, you only need `add_attachment` in your `change` method:
|
248
274
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
275
|
+
```ruby
|
276
|
+
class AddAttachmentToUsers < ActiveRecord::Migration
|
277
|
+
def change
|
278
|
+
add_attachment :users, :avatar
|
279
|
+
end
|
280
|
+
end
|
281
|
+
```
|
254
282
|
|
255
283
|
### Vintage syntax
|
256
284
|
|
@@ -269,7 +297,8 @@ Paperclip ships with 3 storage adapters:
|
|
269
297
|
If you would like to use Paperclip with another storage, you can install these
|
270
298
|
gems along side with Paperclip:
|
271
299
|
|
272
|
-
* [
|
300
|
+
* [paperclip-azure-storage](https://github.com/gmontard/paperclip-azure-storage)
|
301
|
+
* [paperclip-dropbox](https://github.com/janko-m/paperclip-dropbox)
|
273
302
|
|
274
303
|
### Understanding Storage
|
275
304
|
|
@@ -289,7 +318,9 @@ safer choice for the default file store._
|
|
289
318
|
You may also choose to store your files using Amazon's S3 service. To do so, include
|
290
319
|
the `aws-sdk` gem in your Gemfile:
|
291
320
|
|
292
|
-
|
321
|
+
```ruby
|
322
|
+
gem 'aws-sdk', '~> 1.3.4'
|
323
|
+
```
|
293
324
|
|
294
325
|
And then you can specify using S3 from `has_attached_file`.
|
295
326
|
You can find more information about configuring and using S3 storage in
|
@@ -314,8 +345,10 @@ your Rails app's lib/paperclip\_processors directory is automatically loaded by
|
|
314
345
|
paperclip, allowing you to easily define custom processors. You can specify a
|
315
346
|
processor with the :processors option to `has_attached_file`:
|
316
347
|
|
317
|
-
|
318
|
-
|
348
|
+
```ruby
|
349
|
+
has_attached_file :scan, :styles => { :text => { :quality => :better } },
|
350
|
+
:processors => [:ocr]
|
351
|
+
```
|
319
352
|
|
320
353
|
This would load the hypothetical class Paperclip::Ocr, which would have the
|
321
354
|
hash "{ :quality => :better }" passed to it along with the uploaded file. For
|
@@ -325,7 +358,9 @@ The default processor is Paperclip::Thumbnail. For backwards compatibility
|
|
325
358
|
reasons, you can pass a single geometry string or an array containing a
|
326
359
|
geometry and a format, which the file will be converted to, like so:
|
327
360
|
|
328
|
-
|
361
|
+
```ruby
|
362
|
+
has_attached_file :avatar, :styles => { :thumb => ["32x32#", :png] }
|
363
|
+
```
|
329
364
|
|
330
365
|
This will convert the "thumb" style to a 32x32 square in png format, regardless
|
331
366
|
of what was uploaded. If the format is not specified, it is kept the same (i.e.
|
@@ -338,8 +373,10 @@ be given the result of the previous processor's execution. All processors will
|
|
338
373
|
receive the same parameters, which are what you define in the :styles hash.
|
339
374
|
For example, assuming we had this definition:
|
340
375
|
|
341
|
-
|
342
|
-
|
376
|
+
```ruby
|
377
|
+
has_attached_file :scan, :styles => { :text => { :quality => :better } },
|
378
|
+
:processors => [:rotator, :ocr]
|
379
|
+
```
|
343
380
|
|
344
381
|
then both the :rotator processor and the :ocr processor would receive the
|
345
382
|
options "{ :quality => :better }". This parameter may not mean anything to one
|
@@ -372,15 +409,17 @@ _NOTE: Post processing will not even *start* if the attachment is not valid
|
|
372
409
|
according to the validations. Your callbacks and processors will *only* be
|
373
410
|
called with valid attachments._
|
374
411
|
|
375
|
-
|
376
|
-
|
412
|
+
```ruby
|
413
|
+
class Message < ActiveRecord::Base
|
414
|
+
has_attached_file :asset, styles: {thumb: "100x100#"}
|
377
415
|
|
378
|
-
|
416
|
+
before_post_process :skip_for_audio
|
379
417
|
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
418
|
+
def skip_for_audio
|
419
|
+
! %w(audio/ogg application/ogg).include?(asset_content_type)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
```
|
384
423
|
|
385
424
|
URI Obfuscation
|
386
425
|
---------------
|
@@ -390,10 +429,12 @@ publicly-available files.
|
|
390
429
|
|
391
430
|
Example Usage:
|
392
431
|
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
432
|
+
```ruby
|
433
|
+
has_attached_file :avatar, {
|
434
|
+
:url => "/system/:hash.:extension",
|
435
|
+
:hash_secret => "longSecretString"
|
436
|
+
}
|
437
|
+
```
|
397
438
|
|
398
439
|
|
399
440
|
The `:hash` interpolation will be replaced with a unique hash made up of whatever
|
@@ -410,15 +451,17 @@ A MD5 checksum of the original file assigned will be placed in the model if it
|
|
410
451
|
has an attribute named fingerprint. Following the user model migration example
|
411
452
|
above, the migration would look like the following.
|
412
453
|
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
454
|
+
```ruby
|
455
|
+
class AddAvatarFingerprintColumnToUser < ActiveRecord::Migration
|
456
|
+
def self.up
|
457
|
+
add_column :users, :avatar_fingerprint, :string
|
458
|
+
end
|
417
459
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
460
|
+
def self.down
|
461
|
+
remove_column :users, :avatar_fingerprint
|
462
|
+
end
|
463
|
+
end
|
464
|
+
```
|
422
465
|
|
423
466
|
Custom Attachment Processors
|
424
467
|
-------
|
@@ -457,9 +500,11 @@ determine what style parameters are to be used based on the user role might
|
|
457
500
|
look as follows where a boss will receive a `300x300` thumbnail otherwise a
|
458
501
|
`100x100` thumbnail will be created.
|
459
502
|
|
460
|
-
|
461
|
-
|
462
|
-
|
503
|
+
```ruby
|
504
|
+
class User < ActiveRecord::Base
|
505
|
+
has_attached_file :avatar, :styles => lambda { |attachment| { :thumb => (attachment.instance.boss? ? "300x300>" : "100x100>") }
|
506
|
+
end
|
507
|
+
```
|
463
508
|
|
464
509
|
### Dynamic Processors:
|
465
510
|
|
@@ -472,10 +517,12 @@ Presumably some users might return `[:thumbnail, :watermark]` for its
|
|
472
517
|
processors, where a defined `watermark` processor is invoked after the
|
473
518
|
`thumbnail` processor already defined by Paperclip.
|
474
519
|
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
520
|
+
```ruby
|
521
|
+
class User < ActiveRecord::Base
|
522
|
+
has_attached_file :avatar, :processors => lambda { |instance| instance.processors }
|
523
|
+
attr_accessor :watermark
|
524
|
+
end
|
525
|
+
```
|
479
526
|
|
480
527
|
Deployment
|
481
528
|
----------
|
@@ -484,18 +531,22 @@ Paperclip is aware of new attachment styles you have added in previous deploys.
|
|
484
531
|
`rake paperclip:refresh:missing_styles`. It will store current attachment styles in `RAILS_ROOT/public/system/paperclip_attachments.yml`
|
485
532
|
by default. You can change it by:
|
486
533
|
|
487
|
-
|
534
|
+
```ruby
|
535
|
+
Paperclip.registered_attachments_styles_path = '/tmp/config/paperclip_attachments.yml'
|
536
|
+
```
|
488
537
|
|
489
538
|
Here is an example for Capistrano:
|
490
539
|
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
540
|
+
```ruby
|
541
|
+
namespace :deploy do
|
542
|
+
desc "build missing paperclip styles"
|
543
|
+
task :build_missing_paperclip_styles, :roles => :app do
|
544
|
+
run "cd #{release_path}; RAILS_ENV=production bundle exec rake paperclip:refresh:missing_styles"
|
545
|
+
end
|
546
|
+
end
|
497
547
|
|
498
|
-
|
548
|
+
after("deploy:update_code", "deploy:build_missing_paperclip_styles")
|
549
|
+
```
|
499
550
|
|
500
551
|
Now you don't have to remember to refresh thumbnails in production every time you add a new style.
|
501
552
|
Unfortunately it does not work with dynamic styles - it just ignores them.
|
@@ -503,14 +554,16 @@ Unfortunately it does not work with dynamic styles - it just ignores them.
|
|
503
554
|
If you already have a working app and don't want `rake paperclip:refresh:missing_styles` to refresh old pictures, you need to tell
|
504
555
|
Paperclip about existing styles. Simply create a `paperclip_attachments.yml` file by hand. For example:
|
505
556
|
|
506
|
-
|
507
|
-
|
508
|
-
|
557
|
+
```ruby
|
558
|
+
class User < ActiveRecord::Base
|
559
|
+
has_attached_file :avatar, :styles => {:thumb => 'x100', :croppable => '600x600>', :big => '1000x1000>'}
|
560
|
+
end
|
509
561
|
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
562
|
+
class Book < ActiveRecord::Base
|
563
|
+
has_attached_file :cover, :styles => {:small => 'x100', :large => '1000x1000>'}
|
564
|
+
has_attached_file :sample, :styles => {:thumb => 'x100'}
|
565
|
+
end
|
566
|
+
```
|
514
567
|
|
515
568
|
Then in `RAILS_ROOT/public/system/paperclip_attachments.yml`:
|
516
569
|
|
data/lib/paperclip/attachment.rb
CHANGED
@@ -2,11 +2,11 @@ module Paperclip
|
|
2
2
|
module InstanceMethods #:nodoc:
|
3
3
|
def attachment_for name
|
4
4
|
@_paperclip_attachments ||= {}
|
5
|
-
@_paperclip_attachments[name] ||= Attachment.new(name, self,
|
5
|
+
@_paperclip_attachments[name] ||= Attachment.new(name, self, attachment_definitions[name])
|
6
6
|
end
|
7
7
|
|
8
8
|
def each_attachment
|
9
|
-
self.
|
9
|
+
self.attachment_definitions.each do |name, definition|
|
10
10
|
yield(name, attachment_for(name))
|
11
11
|
end
|
12
12
|
end
|
@@ -69,9 +69,16 @@ module Paperclip
|
|
69
69
|
@fog_file ||= @options[:fog_file] || {}
|
70
70
|
end
|
71
71
|
|
72
|
-
def fog_public
|
73
|
-
|
74
|
-
|
72
|
+
def fog_public(style = default_style)
|
73
|
+
if defined?(@options[:fog_public])
|
74
|
+
if defined?(@options[:fog_public][style])
|
75
|
+
return @options[:fog_public][style]
|
76
|
+
else
|
77
|
+
return @options[:fog_public]
|
78
|
+
end
|
79
|
+
else
|
80
|
+
return true
|
81
|
+
end
|
75
82
|
end
|
76
83
|
|
77
84
|
def flush_writes
|
@@ -82,7 +89,7 @@ module Paperclip
|
|
82
89
|
directory.files.create(fog_file.merge(
|
83
90
|
:body => file,
|
84
91
|
:key => path(style),
|
85
|
-
:public => fog_public,
|
92
|
+
:public => fog_public(style),
|
86
93
|
:content_type => file.content_type
|
87
94
|
))
|
88
95
|
rescue Excon::Errors::NotFound
|
@@ -197,4 +204,4 @@ module Paperclip
|
|
197
204
|
end
|
198
205
|
end
|
199
206
|
end
|
200
|
-
end
|
207
|
+
end
|
data/lib/paperclip/storage/s3.rb
CHANGED
@@ -138,7 +138,12 @@ module Paperclip
|
|
138
138
|
|
139
139
|
@s3_headers[:storage_class] = @options[:s3_storage_class] if @options[:s3_storage_class]
|
140
140
|
|
141
|
-
|
141
|
+
if @options[:s3_server_side_encryption].blank?
|
142
|
+
@options[:s3_server_side_encryption] = false
|
143
|
+
end
|
144
|
+
if @options[:s3_server_side_encryption]
|
145
|
+
@s3_headers['x-amz-server-side-encryption'] = @options[:s3_server_side_encryption].to_s.upcase
|
146
|
+
end
|
142
147
|
|
143
148
|
unless @options[:url].to_s.match(/^:s3.*url$/) || @options[:url] == ":asset_host"
|
144
149
|
@options[:path] = @options[:path].gsub(/:url/, @options[:url]).gsub(/^:rails_root\/public\/system/, '')
|
@@ -302,9 +307,6 @@ module Paperclip
|
|
302
307
|
:acl => acl
|
303
308
|
}
|
304
309
|
write_options[:metadata] = @s3_metadata unless @s3_metadata.empty?
|
305
|
-
unless @s3_server_side_encryption.blank?
|
306
|
-
write_options[:server_side_encryption] = @s3_server_side_encryption
|
307
|
-
end
|
308
310
|
write_options.merge!(@s3_headers)
|
309
311
|
s3_object(style).write(file, write_options)
|
310
312
|
rescue AWS::S3::Errors::NoSuchBucket => e
|
data/lib/paperclip/thumbnail.rb
CHANGED
@@ -3,7 +3,7 @@ module Paperclip
|
|
3
3
|
class Thumbnail < Processor
|
4
4
|
|
5
5
|
attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options,
|
6
|
-
:source_file_options, :animated
|
6
|
+
:source_file_options, :animated, :auto_orient
|
7
7
|
|
8
8
|
# List of formats that we need to preserve animation
|
9
9
|
ANIMATED_FORMATS = %w(gif)
|
@@ -38,6 +38,7 @@ module Paperclip
|
|
38
38
|
@whiny = options[:whiny].nil? ? true : options[:whiny]
|
39
39
|
@format = options[:format]
|
40
40
|
@animated = options[:animated].nil? ? true : options[:animated]
|
41
|
+
@auto_orient = options[:auto_orient].nil? ? true : options[:auto_orient]
|
41
42
|
|
42
43
|
@source_file_options = @source_file_options.split(/\s+/) if @source_file_options.respond_to?(:split)
|
43
44
|
@convert_options = @convert_options.split(/\s+/) if @convert_options.respond_to?(:split)
|
@@ -89,6 +90,7 @@ module Paperclip
|
|
89
90
|
scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
|
90
91
|
trans = []
|
91
92
|
trans << "-coalesce" if animated?
|
93
|
+
trans << "-auto-orient" if auto_orient
|
92
94
|
trans << "-resize" << %["#{scale}"] unless scale.nil? || scale.empty?
|
93
95
|
trans << "-crop" << %["#{crop}"] << "+repage" if crop
|
94
96
|
trans
|
data/lib/paperclip/version.rb
CHANGED
data/lib/tasks/paperclip.rake
CHANGED
@@ -26,17 +26,18 @@ namespace :paperclip do
|
|
26
26
|
namespace :refresh do
|
27
27
|
desc "Regenerates thumbnails for a given CLASS (and optional ATTACHMENT and STYLES splitted by comma)."
|
28
28
|
task :thumbnails => :environment do
|
29
|
-
errors = []
|
30
29
|
klass = Paperclip::Task.obtain_class
|
31
30
|
names = Paperclip::Task.obtain_attachments(klass)
|
32
31
|
styles = (ENV['STYLES'] || ENV['styles'] || '').split(',').map(&:to_sym)
|
33
32
|
names.each do |name|
|
34
33
|
Paperclip.each_instance_with_attachment(klass, name) do |instance|
|
35
34
|
instance.send(name).reprocess!(*styles)
|
36
|
-
|
35
|
+
unless instance.errors.blank?
|
36
|
+
puts "errors while processing #{klass} ID #{instance.id}:"
|
37
|
+
puts " " + instance.errors.full_messages.join("\n ") + "\n"
|
38
|
+
end
|
37
39
|
end
|
38
40
|
end
|
39
|
-
errors.each{|e| puts "#{e.first}: #{e.last.full_messages.inspect}" }
|
40
41
|
end
|
41
42
|
|
42
43
|
desc "Regenerates content_type/size metadata for a given CLASS (and optional ATTACHMENT)."
|
Binary file
|
data/test/helper.rb
CHANGED
@@ -103,6 +103,13 @@ def rebuild_class options = {}
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
+
def rebuild_meta_class_of obj, options = {}
|
107
|
+
(class << obj; self; end).tap do |metaklass|
|
108
|
+
metaklass.has_attached_file :avatar, options
|
109
|
+
Paperclip.reset_duplicate_clash_check!
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
106
113
|
class FakeModel
|
107
114
|
attr_accessor :avatar_file_name,
|
108
115
|
:avatar_file_size,
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require './test/helper'
|
2
|
+
|
3
|
+
class MetaClassTest < Test::Unit::TestCase
|
4
|
+
context "A meta-class of dummy" do
|
5
|
+
setup do
|
6
|
+
rebuild_model
|
7
|
+
@file = File.new(fixture_file("5k.png"), 'rb')
|
8
|
+
end
|
9
|
+
|
10
|
+
teardown { @file.close }
|
11
|
+
|
12
|
+
should "be able to use Paperclip like a normal class" do
|
13
|
+
reset_class("Dummy")
|
14
|
+
@dummy = Dummy.new
|
15
|
+
|
16
|
+
assert_nothing_raised do
|
17
|
+
rebuild_meta_class_of(@dummy)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
should "work like any other instance" do
|
22
|
+
reset_class("Dummy")
|
23
|
+
@dummy = Dummy.new
|
24
|
+
rebuild_meta_class_of(@dummy)
|
25
|
+
|
26
|
+
assert_nothing_raised do
|
27
|
+
@dummy.avatar = @file
|
28
|
+
end
|
29
|
+
assert @dummy.save
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/test/storage/fog_test.rb
CHANGED
@@ -232,6 +232,36 @@ class FogTest < Test::Unit::TestCase
|
|
232
232
|
end
|
233
233
|
end
|
234
234
|
|
235
|
+
context "with styles set and fog_public set to false" do
|
236
|
+
setup do
|
237
|
+
rebuild_model(@options.merge(:fog_public => false, :styles => { :medium => "300x300>", :thumb => "100x100>" }))
|
238
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
239
|
+
@dummy = Dummy.new
|
240
|
+
@dummy.avatar = @file
|
241
|
+
@dummy.save
|
242
|
+
end
|
243
|
+
|
244
|
+
should 'set the @fog_public for a perticular style to false' do
|
245
|
+
assert_equal false, @dummy.avatar.instance_variable_get('@options')[:fog_public]
|
246
|
+
assert_equal false, @dummy.avatar.fog_public(:thumb)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
context "with styles set and fog_public set per-style" do
|
251
|
+
setup do
|
252
|
+
rebuild_model(@options.merge(:fog_public => { :medium => false, :thumb => true}, :styles => { :medium => "300x300>", :thumb => "100x100>" }))
|
253
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
254
|
+
@dummy = Dummy.new
|
255
|
+
@dummy.avatar = @file
|
256
|
+
@dummy.save
|
257
|
+
end
|
258
|
+
|
259
|
+
should 'set the fog_public for a perticular style to correct value' do
|
260
|
+
assert_equal false, @dummy.avatar.fog_public(:medium)
|
261
|
+
assert_equal true, @dummy.avatar.fog_public(:thumb)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
235
265
|
context "with a valid bucket name for a subdomain" do
|
236
266
|
should "provide an url in subdomain style" do
|
237
267
|
assert_match @dummy.avatar.url, /^https:\/\/papercliptests.s3.amazonaws.com\/avatars\/5k.png/
|
data/test/storage/s3_test.rb
CHANGED
@@ -856,6 +856,46 @@ class S3Test < Test::Unit::TestCase
|
|
856
856
|
end
|
857
857
|
end
|
858
858
|
|
859
|
+
context "Can disable AES256 encryption multiple ways" do
|
860
|
+
[nil, false, ''].each do |tech|
|
861
|
+
setup do
|
862
|
+
rebuild_model(
|
863
|
+
:storage => :s3,
|
864
|
+
:bucket => "testing",
|
865
|
+
:path => ":attachment/:style/:basename.:extension",
|
866
|
+
:s3_credentials => {
|
867
|
+
'access_key_id' => "12345",
|
868
|
+
'secret_access_key' => "54321"},
|
869
|
+
:s3_server_side_encryption => tech)
|
870
|
+
end
|
871
|
+
|
872
|
+
context "when assigned" do
|
873
|
+
setup do
|
874
|
+
@file = File.new(fixture_file('5k.png'), 'rb')
|
875
|
+
@dummy = Dummy.new
|
876
|
+
@dummy.avatar = @file
|
877
|
+
end
|
878
|
+
|
879
|
+
teardown { @file.close }
|
880
|
+
|
881
|
+
context "and saved" do
|
882
|
+
setup do
|
883
|
+
object = stub
|
884
|
+
@dummy.avatar.stubs(:s3_object).returns(object)
|
885
|
+
object.expects(:write).with(anything,
|
886
|
+
:content_type => "image/png",
|
887
|
+
:acl => :public_read)
|
888
|
+
@dummy.save
|
889
|
+
end
|
890
|
+
|
891
|
+
should "succeed" do
|
892
|
+
assert true
|
893
|
+
end
|
894
|
+
end
|
895
|
+
end
|
896
|
+
end
|
897
|
+
end
|
898
|
+
|
859
899
|
context "An attachment with S3 storage and using AES256 encryption" do
|
860
900
|
setup do
|
861
901
|
rebuild_model :storage => :s3,
|
@@ -884,7 +924,7 @@ class S3Test < Test::Unit::TestCase
|
|
884
924
|
object.expects(:write).with(anything,
|
885
925
|
:content_type => "image/png",
|
886
926
|
:acl => :public_read,
|
887
|
-
|
927
|
+
'x-amz-server-side-encryption' => 'AES256')
|
888
928
|
@dummy.save
|
889
929
|
end
|
890
930
|
|
data/test/thumbnail_test.rb
CHANGED
@@ -114,7 +114,7 @@ class ThumbnailTest < Test::Unit::TestCase
|
|
114
114
|
|
115
115
|
should "send the right command to convert when sent #make" do
|
116
116
|
@thumb.expects(:convert).with do |*arg|
|
117
|
-
arg[0] == ':source -resize "x50" -crop "100x50+114+0" +repage :dest' &&
|
117
|
+
arg[0] == ':source -auto-orient -resize "x50" -crop "100x50+114+0" +repage :dest' &&
|
118
118
|
arg[1][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
|
119
119
|
end
|
120
120
|
@thumb.make
|
@@ -139,7 +139,7 @@ class ThumbnailTest < Test::Unit::TestCase
|
|
139
139
|
|
140
140
|
should "send the right command to convert when sent #make" do
|
141
141
|
@thumb.expects(:convert).with do |*arg|
|
142
|
-
arg[0] == '-strip :source -resize "x50" -crop "100x50+114+0" +repage :dest' &&
|
142
|
+
arg[0] == '-strip :source -auto-orient -resize "x50" -crop "100x50+114+0" +repage :dest' &&
|
143
143
|
arg[1][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
|
144
144
|
end
|
145
145
|
@thumb.make
|
@@ -180,7 +180,7 @@ class ThumbnailTest < Test::Unit::TestCase
|
|
180
180
|
|
181
181
|
should "send the right command to convert when sent #make" do
|
182
182
|
@thumb.expects(:convert).with do |*arg|
|
183
|
-
arg[0] == ':source -resize "x50" -crop "100x50+114+0" +repage -strip -depth 8 :dest' &&
|
183
|
+
arg[0] == ':source -auto-orient -resize "x50" -crop "100x50+114+0" +repage -strip -depth 8 :dest' &&
|
184
184
|
arg[1][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
|
185
185
|
end
|
186
186
|
@thumb.make
|
@@ -302,6 +302,62 @@ class ThumbnailTest < Test::Unit::TestCase
|
|
302
302
|
end
|
303
303
|
end
|
304
304
|
|
305
|
+
context "An image with exif orientation" do
|
306
|
+
setup do
|
307
|
+
@file = File.new(fixture_file("rotated.jpg"), 'rb')
|
308
|
+
end
|
309
|
+
|
310
|
+
teardown { @file.close }
|
311
|
+
|
312
|
+
context "With :auto_orient => false" do
|
313
|
+
setup do
|
314
|
+
@thumb = Paperclip::Thumbnail.new(@file, :geometry => "100x50", :auto_orient => false)
|
315
|
+
end
|
316
|
+
|
317
|
+
should "send the right command to convert when sent #make" do
|
318
|
+
@thumb.expects(:convert).with do |*arg|
|
319
|
+
arg[0] == ':source -resize "100x50" :dest' &&
|
320
|
+
arg[1][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
|
321
|
+
end
|
322
|
+
@thumb.make
|
323
|
+
end
|
324
|
+
|
325
|
+
should "create the thumbnail when sent #make" do
|
326
|
+
dst = @thumb.make
|
327
|
+
assert_match /75x50/, `identify "#{dst.path}"`
|
328
|
+
end
|
329
|
+
|
330
|
+
should "not touch the orientation information" do
|
331
|
+
dst = @thumb.make
|
332
|
+
assert_match /exif:Orientation=6/, `identify -format "%[EXIF:*]" "#{dst.path}"`
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
context "Without :auto_orient => false" do
|
337
|
+
setup do
|
338
|
+
@thumb = Paperclip::Thumbnail.new(@file, :geometry => "100x50")
|
339
|
+
end
|
340
|
+
|
341
|
+
should "send the right command to convert when sent #make" do
|
342
|
+
@thumb.expects(:convert).with do |*arg|
|
343
|
+
arg[0] == ':source -auto-orient -resize "100x50" :dest' &&
|
344
|
+
arg[1][:source] == "#{File.expand_path(@thumb.file.path)}[0]"
|
345
|
+
end
|
346
|
+
@thumb.make
|
347
|
+
end
|
348
|
+
|
349
|
+
should "create the thumbnail when sent #make" do
|
350
|
+
dst = @thumb.make
|
351
|
+
assert_match /33x50/, `identify "#{dst.path}"`
|
352
|
+
end
|
353
|
+
|
354
|
+
should "remove the orientation information" do
|
355
|
+
dst = @thumb.make
|
356
|
+
assert_match /exif:Orientation=1/, `identify -format "%[EXIF:*]" "#{dst.path}"`
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
305
361
|
context "A multipage PDF" do
|
306
362
|
setup do
|
307
363
|
@file = File.new(fixture_file("twopage.pdf"), 'rb')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paperclip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07
|
12
|
+
date: 2012-09-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -498,6 +498,7 @@ files:
|
|
498
498
|
- test/fixtures/animated.unknown
|
499
499
|
- test/fixtures/bad.png
|
500
500
|
- test/fixtures/fog.yml
|
501
|
+
- test/fixtures/rotated.jpg
|
501
502
|
- test/fixtures/s3.yml
|
502
503
|
- test/fixtures/spaced file.png
|
503
504
|
- test/fixtures/text.txt
|
@@ -521,6 +522,7 @@ files:
|
|
521
522
|
- test/matchers/validate_attachment_content_type_matcher_test.rb
|
522
523
|
- test/matchers/validate_attachment_presence_matcher_test.rb
|
523
524
|
- test/matchers/validate_attachment_size_matcher_test.rb
|
525
|
+
- test/meta_class_test.rb
|
524
526
|
- test/paperclip_missing_attachment_styles_test.rb
|
525
527
|
- test/paperclip_test.rb
|
526
528
|
- test/processor_test.rb
|
@@ -566,6 +568,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
566
568
|
- - ! '>='
|
567
569
|
- !ruby/object:Gem::Version
|
568
570
|
version: '0'
|
571
|
+
segments:
|
572
|
+
- 0
|
573
|
+
hash: 2351053992072953924
|
569
574
|
requirements:
|
570
575
|
- ImageMagick
|
571
576
|
rubyforge_project: paperclip
|
@@ -573,76 +578,4 @@ rubygems_version: 1.8.24
|
|
573
578
|
signing_key:
|
574
579
|
specification_version: 3
|
575
580
|
summary: File attachments as attributes for ActiveRecord
|
576
|
-
test_files:
|
577
|
-
- features/basic_integration.feature
|
578
|
-
- features/migration.feature
|
579
|
-
- features/rake_tasks.feature
|
580
|
-
- features/step_definitions/attachment_steps.rb
|
581
|
-
- features/step_definitions/html_steps.rb
|
582
|
-
- features/step_definitions/rails_steps.rb
|
583
|
-
- features/step_definitions/s3_steps.rb
|
584
|
-
- features/step_definitions/web_steps.rb
|
585
|
-
- features/support/env.rb
|
586
|
-
- features/support/fakeweb.rb
|
587
|
-
- features/support/file_helpers.rb
|
588
|
-
- features/support/fixtures/boot_config.txt
|
589
|
-
- features/support/fixtures/gemfile.txt
|
590
|
-
- features/support/fixtures/preinitializer.txt
|
591
|
-
- features/support/paths.rb
|
592
|
-
- features/support/rails.rb
|
593
|
-
- features/support/selectors.rb
|
594
|
-
- test/attachment_options_test.rb
|
595
|
-
- test/attachment_test.rb
|
596
|
-
- test/content_type_detector_test.rb
|
597
|
-
- test/database.yml
|
598
|
-
- test/fixtures/12k.png
|
599
|
-
- test/fixtures/50x50.png
|
600
|
-
- test/fixtures/5k.png
|
601
|
-
- test/fixtures/animated
|
602
|
-
- test/fixtures/animated.gif
|
603
|
-
- test/fixtures/animated.unknown
|
604
|
-
- test/fixtures/bad.png
|
605
|
-
- test/fixtures/fog.yml
|
606
|
-
- test/fixtures/s3.yml
|
607
|
-
- test/fixtures/spaced file.png
|
608
|
-
- test/fixtures/text.txt
|
609
|
-
- test/fixtures/twopage.pdf
|
610
|
-
- test/fixtures/uppercase.PNG
|
611
|
-
- test/generator_test.rb
|
612
|
-
- test/geometry_test.rb
|
613
|
-
- test/helper.rb
|
614
|
-
- test/integration_test.rb
|
615
|
-
- test/interpolations_test.rb
|
616
|
-
- test/io_adapters/abstract_adapter_test.rb
|
617
|
-
- test/io_adapters/attachment_adapter_test.rb
|
618
|
-
- test/io_adapters/file_adapter_test.rb
|
619
|
-
- test/io_adapters/identity_adapter_test.rb
|
620
|
-
- test/io_adapters/nil_adapter_test.rb
|
621
|
-
- test/io_adapters/registry_test.rb
|
622
|
-
- test/io_adapters/stringio_adapter_test.rb
|
623
|
-
- test/io_adapters/uploaded_file_adapter_test.rb
|
624
|
-
- test/io_adapters/uri_adapter_test.rb
|
625
|
-
- test/matchers/have_attached_file_matcher_test.rb
|
626
|
-
- test/matchers/validate_attachment_content_type_matcher_test.rb
|
627
|
-
- test/matchers/validate_attachment_presence_matcher_test.rb
|
628
|
-
- test/matchers/validate_attachment_size_matcher_test.rb
|
629
|
-
- test/paperclip_missing_attachment_styles_test.rb
|
630
|
-
- test/paperclip_test.rb
|
631
|
-
- test/processor_test.rb
|
632
|
-
- test/schema_test.rb
|
633
|
-
- test/storage/filesystem_test.rb
|
634
|
-
- test/storage/fog_test.rb
|
635
|
-
- test/storage/s3_live_test.rb
|
636
|
-
- test/storage/s3_test.rb
|
637
|
-
- test/style_test.rb
|
638
|
-
- test/support/mock_attachment.rb
|
639
|
-
- test/support/mock_interpolator.rb
|
640
|
-
- test/support/mock_model.rb
|
641
|
-
- test/support/mock_url_generator_builder.rb
|
642
|
-
- test/tempfile_factory_test.rb
|
643
|
-
- test/thumbnail_test.rb
|
644
|
-
- test/url_generator_test.rb
|
645
|
-
- test/validators/attachment_content_type_validator_test.rb
|
646
|
-
- test/validators/attachment_presence_validator_test.rb
|
647
|
-
- test/validators/attachment_size_validator_test.rb
|
648
|
-
- test/validators_test.rb
|
581
|
+
test_files: []
|