Commit a6e2418f by jyurek

S3 works but is untested.

git-svn-id: https://svn.thoughtbot.com/plugins/paperclip/trunk@247 7bbfaf0e-4d1d-0410-9690-a8bb5f8ef2aa
parent 5494e3cf
......@@ -29,6 +29,8 @@ require 'paperclip/attachment_definition'
require 'paperclip/attachment'
require 'paperclip/thumbnail'
require 'paperclip/upfile'
require 'paperclip/storage/filesystem'
require 'paperclip/storage/s3'
module Paperclip
......@@ -160,15 +162,21 @@ module Paperclip
@attachments ||= {}
@attachments[name] ||= Attachment.new(self, name, self.class.attachment_definition_for(name))
end
def each_attachment
self.class.attached_files.each do |name|
yield(name, attachment_for(name))
end
end
def save_attached_files
@attachments.each do |name, attachment|
each_attachment do |name, attachment|
attachment.save
end
end
def destroy_attached_files
@attachments.each do |name, attachment|
each_attachment do |name, attachment|
attachment.destroy!
end
end
......
......@@ -19,10 +19,13 @@ module Paperclip
self.original_filename = @instance["#{name}_file_name"]
self.content_type = @instance["#{name}_content_type"]
self.original_file_size = @instance["#{name}_file_size"]
storage_module = Paperclip::Storage.const_get((definition.storage || :filesystem).to_s.camelize)
self.extend(storage_module)
end
def assign uploaded_file
return queue_destroy if uploaded_file.nil?
return destroy if uploaded_file.nil?
return unless is_a_file? uploaded_file
self.original_filename = sanitize_filename(uploaded_file.original_filename)
......@@ -46,7 +49,7 @@ module Paperclip
def clear_files
@files = {}
definition.styles.each{|style, geo| @files[style] = nil }
definition.styles.each{|style, geo| self[style] = nil }
@dirty = false
end
......@@ -119,53 +122,11 @@ module Paperclip
errors << "file too small. Must be over #{constraints.first} bytes." if original_file_size <= constraints.first
end
protected
def write_attachment
ensure_directories
for_attached_files do |style, data|
File.open( file_name(style), "w" ) do |file|
file.rewind
file.write(data) if data
end
end
end
def read_attachment style = nil
IO.read(file_name(style))
end
def delete_attachment complain = false
for_attached_files do |style, data|
file_path = file_name(style)
begin
FileUtils.rm file_path if file_path
rescue SystemCallError => e
raise PaperclipError, "could not be deleted." if Paperclip.options[:whiny_deletes] || complain
end
end
end
def file_name style = nil
def exists?(style)
style ||= definition.default_style
interpolate( style, definition.path )
end
def attachment_exists?(style)
style ||= definition.default_style
dirty? ? self[style] : File.exists?( file_name(style) )
end
def ensure_directories
for_attached_files do |style, file|
dirname = File.dirname( file_name(style) )
FileUtils.mkdir_p dirname
end
attachment_exists?(style)
end
# Image Methods
public
def make_thumbnails_from data
begin
definition.thumbnails.each do |style, geometry|
......@@ -178,27 +139,23 @@ module Paperclip
end
end
# Helper Methods
public
def interpolations
def self.interpolations
@interpolations ||= {
:rails_root => lambda{|style| RAILS_ROOT },
:id => lambda{|style| self.instance.id },
:class => lambda{|style| self.instance.class.to_s.underscore.pluralize },
:style => lambda{|style| style.to_s },
:attachment => lambda{|style| self.name.to_s.pluralize },
:filename => lambda{|style| self.original_filename },
:basename => lambda{|style| self.original_filename.gsub(/\..*$/, "") },
:extension => lambda{|style| self.original_filename.gsub(/^.*./, "") }
:rails_root => lambda{|style, atch| RAILS_ROOT },
:id => lambda{|style, atch| atch.instance.id },
:class => lambda{|style, atch| atch.instance.class.to_s.underscore.pluralize },
:style => lambda{|style, atch| style.to_s },
:attachment => lambda{|style, atch| atch.name.to_s.pluralize },
:filename => lambda{|style, atch| atch.original_filename },
:basename => lambda{|style, atch| atch.original_filename.gsub(/\..*$/, "") },
:extension => lambda{|style, atch| atch.original_filename.gsub(/^.*\./, "") }
}
end
def interpolate style, source
returning source.dup do |s|
interpolations.each do |key, proc|
s.gsub!(/:#{key}/){ proc.call(style) }
Attachment.interpolations.each do |key, proc|
s.gsub!(/:#{key}/){ proc.call(style, self) }
end
end
end
......
module Paperclip
module Storage
module Filesystem
def write_attachment
ensure_directories
for_attached_files do |style, data|
File.open( file_name(style), "w" ) do |file|
file.rewind
file.write(data) if data
end
end
end
def read_attachment style = nil
IO.read(file_name(style))
end
def delete_attachment complain = false
for_attached_files do |style, data|
file_path = file_name(style)
begin
FileUtils.rm file_path if file_path
rescue SystemCallError => e
raise PaperclipError, "could not be deleted." if Paperclip.options[:whiny_deletes] || complain
end
end
end
def attachment_exists? style = nil
File.exists?( file_name(style) )
end
def file_name style = nil
style ||= definition.default_style
interpolate( style, definition.file_path )
end
def ensure_directories
for_attached_files do |style, file|
dirname = File.dirname( file_name(style) )
FileUtils.mkdir_p dirname
end
end
end
end
end
\ No newline at end of file
module Paperclip
module Storage
module S3
def self.extended(base)
Paperclip.options[:s3] ||= {}
Paperclip::Attachment.interpolations[:bucket] = lambda{|style, atch| atch.definition.bucket }
access_key, secret_key = credentials
require 'aws/s3'
AWS::S3::Base.establish_connection!(
:access_key_id => access_key,
:secret_access_key => secret_key,
:persistent => Paperclip.options[:s3][:persistent] || true
)
end
def self.credentials
if credentials_file
creds = YAML.load_file(credentials_file)
creds = creds[RAILS_ENV] || creds if Object.const_defined?("RAILS_ENV")
[ creds['access_key_id'], creds['secret_access_key'] ]
else
[ Paperclip.options[:s3][:access_key_id], Paperclip.options[:s3][:secret_access_key] ]
end
end
def self.credentials_file
@file ||= [ Paperclip.options[:s3][:credentials_file], File.join(RAILS_ROOT, "config", "s3.yml") ].compact.find do |f|
File.exists?(f)
end
end
def file_name style = nil
style ||= definition.default_style
interpolate( style, definition.path )
end
def attachment_exists? style = nil
AWS::S3::S3Object.exists?( file_name(style), bucket )
end
def bucket
definition.bucket
end
def ensure_bucket
begin
AWS::S3::Bucket.create(bucket)
bucket
rescue AWS::S3::S3Exception => e
raise Paperclip::PaperclipError, "You are not allowed access to the bucket '#{bucket_name}'."
end
end
def write_attachment
ensure_bucket
for_attached_files do |style, data|
AWS::S3::S3Object.store( file_name(style), data, bucket, :access => definition.s3_access || :public_read )
end
end
def read_attachment style = nil
AWS::S3::S3Object.value( file_name(style), bucket )
end
def stream style = nil, &block
AWS::S3::S3Object.stream( file_name(style), bucket, &block )
end
def delete_attachment complain = false
for_attached_files do |style|
AWS::S3::S3Object.delete( file_name(style), bucket )
end
end
end
end
end
\ No newline at end of file
......@@ -60,6 +60,37 @@ class TestAttachment < Test::Unit::TestCase
assert_match /405x375/, `identify '#{@foo.image.send(:file_name)}'`
assert_equal IO.read(@file.path), @foo.image.read
end
context "and then deleted" do
setup do
assert @foo.destroy
end
should "have no errors" do
assert @foo.image.errors.blank?
end
should "have no files on the filesystem" do
assert !File.file?(@foo.image.send(:file_name)), @foo.image.send(:file_name)
assert !File.exist?(@foo.image.send(:file_name)), @foo.image.send(:file_name)
end
end
context "and then set to null and resaved" do
setup do
@foo.image = nil
assert @foo.save
end
should "have no errors" do
assert @foo.image.errors.blank?
end
should "have no files on the filesystem" do
assert !File.file?(@foo.image.send(:file_name)), @foo.image.send(:file_name)
assert !File.exist?(@foo.image.send(:file_name)), @foo.image.send(:file_name)
end
end
end
end
......
......@@ -4,15 +4,15 @@ require File.dirname(__FILE__) + "/test_helper.rb"
class TestAttachmentDefinition < Test::Unit::TestCase
context "Attachment definitions" do
should "allow overriding options" do
not_expected = Paperclip::AttachmentDefinition.defaults[:path]
Paperclip::AttachmentDefinition.defaults[:path] = "123"
assert_not_equal not_expected, Paperclip::AttachmentDefinition.defaults[:path]
assert_equal "123", Paperclip::AttachmentDefinition.defaults[:path]
not_expected = Paperclip::AttachmentDefinition.defaults[:file_path]
Paperclip::AttachmentDefinition.defaults[:file_path] = "123"
assert_not_equal not_expected, Paperclip::AttachmentDefinition.defaults[:file_path]
assert_equal "123", Paperclip::AttachmentDefinition.defaults[:file_path]
end
should "accept options that override defaults" do
@def = Paperclip::AttachmentDefinition.new "attachment", :path => "123", :delete_on_destroy => false
assert_not_equal Paperclip::AttachmentDefinition.defaults[:path], @def.path
@def = Paperclip::AttachmentDefinition.new "attachment", :file_path => "123", :delete_on_destroy => false
assert_not_equal Paperclip::AttachmentDefinition.defaults[:file_path], @def.path
assert_not_equal Paperclip::AttachmentDefinition.defaults[:delete_on_destroy], @def.delete_on_destroy
assert_equal "123", @def.path
assert_equal false, @def.delete_on_destroy
......@@ -22,7 +22,7 @@ class TestAttachmentDefinition < Test::Unit::TestCase
context "An attachment defintion" do
setup do
@options = {
:path => "/home/stuff/place",
:file_path => "/home/stuff/place",
:url => "/attachments/:attachment/:name",
:custom_definition => :boogie!,
:thumbnails => {:thumb => "100x100", :large => "300x300>"},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment