Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
paperclip
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ikcrm_common
paperclip
Commits
ce9d7eab
Commit
ce9d7eab
authored
Aug 26, 2011
by
Marcin Urbanski
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote branch 'upstream/master'
Conflicts: README.md
parents
bb5fde8c
d00c04e3
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
186 additions
and
11 deletions
+186
-11
README.md
+76
-3
lib/paperclip.rb
+10
-2
lib/paperclip/attachment.rb
+1
-1
lib/paperclip/storage/fog.rb
+20
-3
test/attachment_test.rb
+28
-0
test/fixtures/fog.yml
+8
-0
test/fog_test.rb
+35
-2
test/upfile_test.rb
+8
-0
No files found.
README.md
View file @
ce9d7eab
...
@@ -25,7 +25,7 @@ that it does, on your command line, run `which convert` (one of the ImageMagick
...
@@ -25,7 +25,7 @@ that it does, on your command line, run `which convert` (one of the ImageMagick
utilities). This will give you the path where that utility is installed. For
utilities). This will give you the path where that utility is installed. For
example, it might return
`/usr/local/bin/convert`
.
example, it might return
`/usr/local/bin/convert`
.
Then, in your environment config file, let Paperclip know to look there by adding that
Then, in your environment config file, let Paperclip know to look there by adding that
directory to its path.
directory to its path.
In development mode, you might add this line to
`config/environments/development.rb)`
:
In development mode, you might add this line to
`config/environments/development.rb)`
:
...
@@ -231,6 +231,80 @@ Paperclip has an interpolation called `:hash` for obfuscating filenames of publi
...
@@ -231,6 +231,80 @@ Paperclip has an interpolation called `:hash` for obfuscating filenames of publi
[
https://github.com/thoughtbot/paperclip/pull/416
](
https://github.com/thoughtbot/paperclip/pull/416
)
[
https://github.com/thoughtbot/paperclip/pull/416
](
https://github.com/thoughtbot/paperclip/pull/416
)
MD5 Checksum / Fingerprint
-------
A MD5 checksum of the original file assigned will be placed in the model if it
has an attribute named fingerprint. Following the user model migration example
above, the migration would look like the following.
class AddAvatarFingerprintColumnToUser < ActiveRecord::Migration
def self.up
add_column :users, :avatar_fingerprint, :string
end
def self.down
remove_column :users, :avatar_fingerprint
end
end
Custom Attachment Processors
-------
Custom attachment processors can be implemented and their only requirement is
to inherit from
`Paperclip::Processor`
(see
`lib/paperclip/processor.rb`
).
For example, when
`:styles`
are specified for an image attachment, the
thumbnail processor (see
`lib/paperclip/thumbnail.rb`
) is loaded without having
to specify it as a
`:processor`
parameter to
`has_attached_file`
. When any
other processor is defined it must be called out in the
`:processors`
parameter if it is to be applied to the attachment. The thumbnail processor
uses the imagemagick
`convert`
command to do the work of resizing image
thumbnails. It would be easy to create a custom processor that watermarks
an image using imagemagick's
`composite`
command. Following the
implementation pattern of the thumbnail processor would be a way to implement a
watermark processor. All kinds of attachment processors can be created;
a few utility examples would be compression and encryption processors.
Dynamic Configuration
---------------------
Callable objects (labdas, Procs) can be used in a number of places for dynamic
configuration throughout Paperclip. This strategy exists in a number of
components of the library but is most significant in the possibilities for
allowing custom styles and processors to be applied for specific model
instances, rather than applying defined styles and processors across all
instances.
Dynamic Styles:
Imagine a user model that had different styles based on the role of the user.
Perhaps some users are bosses (e.g. a User model instance responds to #boss?)
and merit a bigger avatar thumbnail than regular users. The configuration to
determine what style parameters are to be used based on the user role might
look as follows where a boss will receive a
`300x300`
thumbnail otherwise a
`100x100`
thumbnail will be created.
class User < ActiveRecord::Base
has_attached_file :avatar, :styles => lambda { |attachment| { :thumb => (attachment.instance.boss? ? "300x300>" : "100x100>") }
end
Dynamic Processors:
Another contrived example is a user model that is aware of which file processors
should be applied to it (beyond the implied
`thumbnail`
processor invoked when
`:styles`
are defined). Perhaps we have a watermark processor available and it is
only used on the avatars of certain models. The configuration for this might be
where the instance is queried for which processors should be applied to it.
Presumably some users might return
`[:thumbnail, :watermark]`
for its
processors, where a defined
`watermark`
processor is invoked after the
`thumbnail`
processor already defined by Paperclip.
class User < ActiveRecord::Base
has_attached_file :avatar, :processors => lambda { |instance| instance.processors }
attr_accessor :watermark
end
Deploy
Deploy
------
------
...
@@ -288,7 +362,6 @@ Then in `RAILS_ROOT/public/system/paperclip_attachments.yml`:
...
@@ -288,7 +362,6 @@ Then in `RAILS_ROOT/public/system/paperclip_attachments.yml`:
:sample:
:sample:
- :thumb
- :thumb
Testing
Testing
-------
-------
...
@@ -303,7 +376,7 @@ If you'd like to contribute a feature or bugfix: Thanks! To make sure your
...
@@ -303,7 +376,7 @@ If you'd like to contribute a feature or bugfix: Thanks! To make sure your
fix/feature has a high chance of being included, please read the following
fix/feature has a high chance of being included, please read the following
guidelines:
guidelines:
1.
Ask on the mailing list
[
http://groups.google.com/group/paperclip-plugin
]
, or
1.
Ask on the mailing list
[
http://groups.google.com/group/paperclip-plugin
]
, or
post a new GitHub Issue
[
http://github.com/thoughtbot/paperclip/issues
]
.
post a new GitHub Issue
[
http://github.com/thoughtbot/paperclip/issues
]
.
2.
Make sure there are tests! We will not accept any patch that is not tested.
2.
Make sure there are tests! We will not accept any patch that is not tested.
It's a rare time when explicit tests aren't needed. If you have questions
It's a rare time when explicit tests aren't needed. If you have questions
...
...
lib/paperclip.rb
View file @
ce9d7eab
...
@@ -273,7 +273,8 @@ module Paperclip
...
@@ -273,7 +273,8 @@ module Paperclip
Paperclip
.
classes_with_attachments
<<
self
Paperclip
.
classes_with_attachments
<<
self
after_save
:save_attached_files
after_save
:save_attached_files
before_destroy
:destroy_attached_files
before_destroy
:prepare_for_destroy
after_destroy
:destroy_attached_files
define_paperclip_callbacks
:post_process
,
:"
#{
name
}
_post_process"
define_paperclip_callbacks
:post_process
,
:"
#{
name
}
_post_process"
...
@@ -409,10 +410,17 @@ module Paperclip
...
@@ -409,10 +410,17 @@ module Paperclip
def
destroy_attached_files
def
destroy_attached_files
Paperclip
.
log
(
"Deleting attachments."
)
Paperclip
.
log
(
"Deleting attachments."
)
each_attachment
do
|
name
,
attachment
|
each_attachment
do
|
name
,
attachment
|
attachment
.
send
(
:queue_existing_for_delete
)
attachment
.
send
(
:flush_deletes
)
attachment
.
send
(
:flush_deletes
)
end
end
end
end
def
prepare_for_destroy
Paperclip
.
log
(
"Scheduling attachments for deletion."
)
each_attachment
do
|
name
,
attachment
|
attachment
.
send
(
:queue_existing_for_delete
)
end
end
end
end
end
end
lib/paperclip/attachment.rb
View file @
ce9d7eab
...
@@ -135,7 +135,7 @@ module Paperclip
...
@@ -135,7 +135,7 @@ module Paperclip
@dirty
=
true
@dirty
=
true
post_process
(
*
@only_process
)
if
@
post_processing
post_process
(
*
@only_process
)
if
post_processing
# Reset the file size if the original file was reprocessed.
# Reset the file size if the original file was reprocessed.
instance_write
(
:file_size
,
@queued_for_write
[
:original
].
size
.
to_i
)
instance_write
(
:file_size
,
@queued_for_write
[
:original
].
size
.
to_i
)
...
...
lib/paperclip/storage/fog.rb
View file @
ce9d7eab
...
@@ -42,7 +42,7 @@ module Paperclip
...
@@ -42,7 +42,7 @@ module Paperclip
base
.
instance_eval
do
base
.
instance_eval
do
@fog_directory
=
@options
[
:fog_directory
]
@fog_directory
=
@options
[
:fog_directory
]
@fog_credentials
=
@options
[
:fog_credentials
]
@fog_credentials
=
parse_credentials
(
@options
[
:fog_credentials
])
@fog_host
=
@options
[
:fog_host
]
@fog_host
=
@options
[
:fog_host
]
@fog_public
=
@options
.
key?
(
:fog_public
)
?
@options
[:
fog_public
]
:
true
@fog_public
=
@options
.
key?
(
:fog_public
)
?
@options
[:
fog_public
]
:
true
@fog_file
=
@options
[
:fog_file
]
||
{}
@fog_file
=
@options
[
:fog_file
]
||
{}
...
@@ -120,8 +120,27 @@ module Paperclip
...
@@ -120,8 +120,27 @@ module Paperclip
end
end
end
end
def
parse_credentials
(
creds
)
creds
=
find_credentials
(
creds
).
stringify_keys
env
=
Object
.
const_defined?
(
:Rails
)
?
Rails
.
env
:
nil
(
creds
[
env
]
||
creds
).
symbolize_keys
end
private
private
def
find_credentials
(
creds
)
case
creds
when
File
YAML
::
load
(
ERB
.
new
(
File
.
read
(
creds
.
path
)).
result
)
when
String
,
Pathname
YAML
::
load
(
ERB
.
new
(
File
.
read
(
creds
)).
result
)
when
Hash
creds
else
raise
ArgumentError
,
"Credentials are not a path, file, or hash."
end
end
def
connection
def
connection
@connection
||=
::
Fog
::
Storage
.
new
(
@fog_credentials
)
@connection
||=
::
Fog
::
Storage
.
new
(
@fog_credentials
)
end
end
...
@@ -129,8 +148,6 @@ module Paperclip
...
@@ -129,8 +148,6 @@ module Paperclip
def
directory
def
directory
@directory
||=
connection
.
directories
.
new
(
:key
=>
@fog_directory
)
@directory
||=
connection
.
directories
.
new
(
:key
=>
@fog_directory
)
end
end
end
end
end
end
end
end
test/attachment_test.rb
View file @
ce9d7eab
...
@@ -1076,4 +1076,32 @@ class AttachmentTest < Test::Unit::TestCase
...
@@ -1076,4 +1076,32 @@ class AttachmentTest < Test::Unit::TestCase
assert_equal
"hello"
,
attachment
.
url
assert_equal
"hello"
,
attachment
.
url
end
end
end
end
context
"An attached file"
do
setup
do
rebuild_model
@dummy
=
Dummy
.
new
@file
=
File
.
new
(
File
.
join
(
File
.
dirname
(
__FILE__
),
"fixtures"
,
"5k.png"
),
'rb'
)
@dummy
.
avatar
=
@file
@dummy
.
save!
@attachment
=
@dummy
.
avatar
@path
=
@attachment
.
path
end
should
"not be deleted when the model fails to destroy"
do
@dummy
.
stubs
(
:destroy
).
raises
(
Exception
)
assert_raise
Exception
do
@dummy
.
destroy
end
assert
File
.
exists?
(
@path
)
end
should
"be deleted when the model is destroyed"
do
@dummy
.
destroy
assert
!
File
.
exists?
(
@path
)
end
end
end
end
test/fixtures/fog.yml
0 → 100644
View file @
ce9d7eab
development
:
provider
:
AWS
aws_access_key_id
:
AWS_ID
aws_secret_access_key
:
AWS_SECRET
test
:
provider
:
AWS
aws_access_key_id
:
AWS_ID
aws_secret_access_key
:
AWS_SECRET
test/fog_test.rb
View file @
ce9d7eab
...
@@ -5,6 +5,39 @@ Fog.mock!
...
@@ -5,6 +5,39 @@ Fog.mock!
class
FogTest
<
Test
::
Unit
::
TestCase
class
FogTest
<
Test
::
Unit
::
TestCase
context
""
do
context
""
do
context
"with credentials provided in a path string"
do
setup
do
rebuild_model
:styles
=>
{
:medium
=>
"300x300>"
,
:thumb
=>
"100x100>"
},
:storage
=>
:fog
,
:url
=>
'/:attachment/:filename'
,
:fog_directory
=>
"paperclip"
,
:fog_credentials
=>
File
.
join
(
File
.
dirname
(
__FILE__
),
'fixtures'
,
'fog.yml'
)
@dummy
=
Dummy
.
new
@dummy
.
avatar
=
File
.
new
(
File
.
join
(
File
.
dirname
(
__FILE__
),
'fixtures'
,
'5k.png'
),
'rb'
)
end
should
"have the proper information loading credentials from a file"
do
assert_equal
@dummy
.
avatar
.
instance_variable_get
(
"@fog_credentials"
)[
:provider
],
'AWS'
end
end
context
"with credentials provided in a File object"
do
setup
do
rebuild_model
:styles
=>
{
:medium
=>
"300x300>"
,
:thumb
=>
"100x100>"
},
:storage
=>
:fog
,
:url
=>
'/:attachment/:filename'
,
:fog_directory
=>
"paperclip"
,
:fog_credentials
=>
File
.
open
(
File
.
join
(
File
.
dirname
(
__FILE__
),
'fixtures'
,
'fog.yml'
))
@dummy
=
Dummy
.
new
@dummy
.
avatar
=
File
.
new
(
File
.
join
(
File
.
dirname
(
__FILE__
),
'fixtures'
,
'5k.png'
),
'rb'
)
end
should
"have the proper information loading credentials from a file"
do
assert_equal
@dummy
.
avatar
.
instance_variable_get
(
"@fog_credentials"
)[
:provider
],
'AWS'
end
end
context
"with default values for path and url"
do
context
"with default values for path and url"
do
setup
do
setup
do
rebuild_model
:styles
=>
{
:medium
=>
"300x300>"
,
:thumb
=>
"100x100>"
},
rebuild_model
:styles
=>
{
:medium
=>
"300x300>"
,
:thumb
=>
"100x100>"
},
...
@@ -131,7 +164,7 @@ class FogTest < Test::Unit::TestCase
...
@@ -131,7 +164,7 @@ class FogTest < Test::Unit::TestCase
assert
@dummy
.
avatar
.
url
=~
/^http:\/\/img[0123]\.example\.com\/avatars\/stringio\.txt\?\d*$/
assert
@dummy
.
avatar
.
url
=~
/^http:\/\/img[0123]\.example\.com\/avatars\/stringio\.txt\?\d*$/
end
end
end
end
context
"with fog_public set to false"
do
context
"with fog_public set to false"
do
setup
do
setup
do
rebuild_model
(
@options
.
merge
(
:fog_public
=>
false
))
rebuild_model
(
@options
.
merge
(
:fog_public
=>
false
))
...
@@ -139,7 +172,7 @@ class FogTest < Test::Unit::TestCase
...
@@ -139,7 +172,7 @@ class FogTest < Test::Unit::TestCase
@dummy
.
avatar
=
StringIO
.
new
(
'.'
)
@dummy
.
avatar
=
StringIO
.
new
(
'.'
)
@dummy
.
save
@dummy
.
save
end
end
should
'set the @fog_public instance variable to false'
do
should
'set the @fog_public instance variable to false'
do
assert_equal
false
,
@dummy
.
avatar
.
instance_variable_get
(
'@fog_public'
)
assert_equal
false
,
@dummy
.
avatar
.
instance_variable_get
(
'@fog_public'
)
end
end
...
...
test/upfile_test.rb
View file @
ce9d7eab
...
@@ -24,6 +24,14 @@ class UpfileTest < Test::Unit::TestCase
...
@@ -24,6 +24,14 @@ class UpfileTest < Test::Unit::TestCase
assert_equal
content_type
,
file
.
content_type
assert_equal
content_type
,
file
.
content_type
end
end
should
"return a content_type of text/plain on a real file whose content_type is determined with the file command"
do
file
=
File
.
new
(
File
.
join
(
File
.
dirname
(
__FILE__
),
".."
,
"LICENSE"
))
class
<<
file
include
Paperclip
::
Upfile
end
assert_equal
'text/plain'
,
file
.
content_type
end
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment