Commit 49b833a4 by Jon Yurek

Refactor shared behavior into AbstractAdapter superclass

parent 67281668
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 @@ module Paperclip
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 @@ module Paperclip
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 @@ module Paperclip
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
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 @@ module Paperclip
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 @@ module Paperclip
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 UploadedFileAdapterTest < Test::Unit::TestCase
:original_filename => "5k.png",
:content_type => "image/png",
:head => "",
:tempfile => tempfile
:tempfile => tempfile,
:path => tempfile.path
)
@subject = Paperclip.io_adapters.for(@file)
end
......
......@@ -276,8 +276,13 @@ class S3Test < Test::Unit::TestCase
'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
......
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