Permalink
Browse files

Refactor shared behavior into AbstractAdapter superclass

  • Loading branch information...
1 parent 6728166 commit 49b833a48acd33cca1264ec67f4ede3cfa06081d @jyurek jyurek committed Jun 15, 2012
@@ -1,5 +1,43 @@
module Paperclip
class AbstractAdapter
+
+ def original_filename
+ @original_filename
+ end
+
+ def content_type
+ @content_type
+ end
+
+ def size
+ @size
+ end
+
+ def fingerprint
+ @fingerprint ||= Digest::MD5.file(path).to_s
+ end
+
+ def nil?
+ false
+ end
+
+ def read(length = nil, buffer = nil)
+ @tempfile.read(length, buffer)
+ end
+
+ # We don't use this directly, but aws/sdk does.
+ def rewind
+ @tempfile.rewind
+ end
+
+ def eof?
+ @tempfile.eof?
+ end
+
+ def path
+ @tempfile.path
+ end
+
private
def destination
@@ -22,8 +60,9 @@ def best_content_type_option(types)
def type_from_file_command
# On BSDs, `file` doesn't give a result code of 1 if the file doesn't exist.
- type = (self.original_filename.match(/\.(\w+)$/)[1] rescue "octet-stream").downcase
- mime_type = (Paperclip.run("file", "-b --mime :file", :file => self.path).split(/[:;\s]+/)[0] rescue "application/x-#{type}")
+ type = (File.extname(self.path.to_s)).downcase
+ type = "octet-stream" if type.empty?
+ mime_type = Paperclip.run("file", "-b --mime :file", :file => self.path).split(/[:;\s]+/)[0]
mime_type = "application/x-#{type}" if mime_type.match(/\(.*?\)/)
mime_type
end
@@ -11,43 +11,6 @@ def initialize(target)
cache_current_values
end
- def original_filename
- @original_filename
- end
-
- def content_type
- @content_type
- end
-
- def size
- @size
- end
-
- def nil?
- false
- end
-
- def fingerprint
- @fingerprint ||= Digest::MD5.file(path).to_s
- end
-
- def read(length = nil, buffer = nil)
- @tempfile.read(length, buffer)
- end
-
- # We don't use this directly, but aws/sdk does.
- def rewind
- @tempfile.rewind
- end
-
- def eof?
- @tempfile.eof?
- end
-
- def path
- @tempfile.path
- end
-
private
def cache_current_values
@@ -2,18 +2,20 @@ module Paperclip
class FileAdapter < AbstractAdapter
def initialize(target)
@target = target
- @tempfile = copy_to_tempfile(@target)
+ cache_current_values
end
- def original_filename
- if @target.respond_to?(:original_filename)
- @target.original_filename
- else
- File.basename(@target.path)
- end
+ private
+
+ def cache_current_values
+ @original_filename = @target.original_filename if @target.respond_to?(:original_filename)
+ @original_filename ||= File.basename(@target.path)
+ @tempfile = copy_to_tempfile(@target)
+ @content_type = calculate_content_type
+ @size = File.size(@target)
end
- def content_type
+ def calculate_content_type
types = MIME::Types.type_for(original_filename)
if types.length == 0
type_from_file_command
@@ -23,35 +25,6 @@ def content_type
best_content_type_option(types)
end
end
-
- def fingerprint
- @fingerprint ||= Digest::MD5.file(path).to_s
- end
-
- def size
- File.size(@tempfile)
- end
-
- def nil?
- @target.nil?
- end
-
- def read(length = nil, buffer = nil)
- @tempfile.read(length, buffer)
- end
-
- # We don't use this directly, but aws/sdk does.
- def rewind
- @tempfile.rewind
- end
-
- def eof?
- @tempfile.eof?
- end
-
- def path
- @tempfile.path
- end
end
end
@@ -2,55 +2,23 @@ module Paperclip
class StringioAdapter < AbstractAdapter
def initialize(target)
@target = target
+ cache_current_values
@tempfile = copy_to_tempfile(@target)
end
- attr_writer :original_filename, :content_type
@twalpole

twalpole Jun 16, 2012

I believe this functionality is still needed for the StringioAdapter since without it theres no way to set the content_type or original_filename

+ private
- def original_filename
- @original_filename ||= @target.original_filename if @target.respond_to?(:original_filename)
+ def cache_current_values
+ @original_filename = @target.original_filename if @target.respond_to?(:original_filename)
@original_filename ||= "stringio.txt"
- @original_filename.strip
- end
+ @original_filename = @original_filename.strip
- def content_type
- @content_type ||= @target.content_type if @target.respond_to?(:content_type)
+ @content_type = @target.content_type if @target.respond_to?(:content_type)
@content_type ||= "text/plain"
- @content_type
- end
-
- def size
- @target.size
- end
-
- def fingerprint
- if (@cached_fingerprint.nil?)
- rewind # start reading from the beginning
- @cached_fingerprint = Digest::MD5.hexdigest(read)
- rewind # for later read()
- end
- @cached_fingerprint
- end
- def read(length = nil, buffer = nil)
- @tempfile.read(length, buffer)
+ @size = @target.size
end
- # We don't use this directly, but aws/sdk does.
- def rewind
- @tempfile.rewind
- end
-
- def eof?
- @tempfile.eof?
- end
-
- def path
- @tempfile.path
- end
-
- private
-
def copy_to_tempfile(src)
while data = src.read(16*1024)
destination.write(data)
@@ -2,6 +2,7 @@ module Paperclip
class UploadedFileAdapter < AbstractAdapter
def initialize(target)
@target = target
+ cache_current_values
if @target.respond_to?(:tempfile)
@tempfile = copy_to_tempfile(@target.tempfile)
@@ -10,41 +11,12 @@ def initialize(target)
end
end
- def original_filename
- @target.original_filename
- end
-
- def content_type
- @target.content_type
- end
-
- def fingerprint
- @fingerprint ||= Digest::MD5.file(path).to_s
- end
-
- def size
- File.size(path)
- end
-
- def nil?
- false
- end
-
- def read(length = nil, buffer = nil)
- @tempfile.read(length, buffer)
- end
-
- # We don't use this directly, but aws/sdk does.
- def rewind
- @tempfile.rewind
- end
-
- def eof?
- @tempfile.eof?
- end
+ private
- def path
- @tempfile.path
+ def cache_current_values
+ @original_filename = @target.original_filename
+ @content_type = @target.content_type
+ @size = File.size(@target.path)
end
end
end
@@ -68,5 +68,9 @@ def flush_deletes #:nodoc:
end
end
+ def copy_to_local_file(style, local_dest_path)
+ FileUtils.cp(path(style), local_dest_path)
+ end
+
end
end
@@ -63,6 +63,7 @@ class FileAdapterTest < Test::Unit::TestCase
context "file with multiple possible x-types but no official type" do
setup do
MIME::Types.stubs(:type_for).returns([MIME::Type.new('image/x-mp4'), MIME::Type.new('image/x-video')])
+ @subject = Paperclip.io_adapters.for(@file)
end
should "return the first" do
@@ -74,6 +75,7 @@ class FileAdapterTest < Test::Unit::TestCase
setup do
MIME::Types.stubs(:type_for).returns([])
Paperclip.stubs(:run).returns("application/vnd.ms-office\n")
+ @subject = Paperclip.io_adapters.for(@file)
end
should "return content type without newline character" do
@@ -12,20 +12,10 @@ class StringioFileProxyTest < Test::Unit::TestCase
assert_equal "stringio.txt", @subject.original_filename
end
- should "allow us to set a name" do
- @subject.original_filename = "data.txt"
- assert_equal "data.txt", @subject.original_filename
- end
-
should "return a content type" do
assert_equal "text/plain", @subject.content_type
end
- should "allow us to set a content type" do
- @subject.content_type = "image/jpg"
- assert_equal "image/jpg", @subject.content_type
- end
-
should "return the size of the data" do
assert_equal 6, @subject.size
end
@@ -12,7 +12,8 @@ class UploadedFile < OpenStruct; end
:original_filename => "5k.png",
:content_type => "image/png",
:head => "",
- :tempfile => tempfile
+ :tempfile => tempfile,
+ :path => tempfile.path
)
@subject = Paperclip.io_adapters.for(@file)
end
View
@@ -276,8 +276,13 @@ def teardown
'secret_access_key' => "54321"
}
- file = Paperclip.io_adapters.for(StringIO.new("."))
- file.original_filename = "question?mark.png"
+ stringio = StringIO.new(".")
+ class << stringio
+ def original_filename
+ "question?mark.png"
+ end
+ end
+ file = Paperclip.io_adapters.for(stringio)
@dummy = Dummy.new
@dummy.avatar = file
@dummy.save

0 comments on commit 49b833a

Please sign in to comment.