Commit 5d06ad8c by Aditya Sanghi Committed by Jon Yurek

Allow for URI Adapter as an optional paperclip io adapter

This PR allows you to assign a URI object to an attachment. The
attachment is downloaded and saved with a proper content type and
filename based on the path of the URL.
parent 786a13f0
...@@ -223,3 +223,4 @@ require 'paperclip/io_adapters/stringio_adapter' ...@@ -223,3 +223,4 @@ require 'paperclip/io_adapters/stringio_adapter'
require 'paperclip/io_adapters/nil_adapter' require 'paperclip/io_adapters/nil_adapter'
require 'paperclip/io_adapters/attachment_adapter' require 'paperclip/io_adapters/attachment_adapter'
require 'paperclip/io_adapters/uploaded_file_adapter' require 'paperclip/io_adapters/uploaded_file_adapter'
require 'paperclip/io_adapters/uri_adapter'
require 'open-uri'
module Paperclip
class UriAdapter < AbstractAdapter
def initialize(target)
@target = target
@content = download_content
cache_current_values
@tempfile = copy_to_tempfile(@content)
end
attr_writer :original_filename, :content_type
private
def download_content
open(@target)
end
def cache_current_values
@original_filename = @target.path.split("/").last
@original_filename ||= "index.html"
@original_filename = @original_filename.strip
@content_type = @content.content_type if @content.respond_to?(:content_type)
@content_type ||= "text/html"
@size = @content.size
end
def copy_to_tempfile(src)
while data = src.read(16*1024)
destination.write(data)
end
destination.rewind
destination
end
end
end
Paperclip.io_adapters.register Paperclip::UriAdapter do |target|
target.kind_of?(URI)
end
require './test/helper' require './test/helper'
class AttachmentAdapterTest < Test::Unit::TestCase class AttachmentAdapterTest < Test::Unit::TestCase
def setup def setup
rebuild_model :path => "tmp/:class/:attachment/:style/:filename", :styles => {:thumb => '50x50'} rebuild_model :path => "tmp/:class/:attachment/:style/:filename", :styles => {:thumb => '50x50'}
@attachment = Dummy.new.avatar @attachment = Dummy.new.avatar
end end
context "for an attachment" do context "for an attachment" do
setup do setup do
@file = File.new(fixture_file("5k.png")) @file = File.new(fixture_file("5k.png"))
...@@ -53,19 +53,19 @@ class AttachmentAdapterTest < Test::Unit::TestCase ...@@ -53,19 +53,19 @@ class AttachmentAdapterTest < Test::Unit::TestCase
assert_equal expected.length, actual.length assert_equal expected.length, actual.length
assert_equal expected, actual assert_equal expected, actual
end end
end end
context "for a style" do context "for a style" do
setup do setup do
@file = File.new(fixture_file("5k.png")) @file = File.new(fixture_file("5k.png"))
@file.binmode @file.binmode
@attachment.assign(@file) @attachment.assign(@file)
@thumb = Tempfile.new("thumbnail").tap(&:binmode) @thumb = Tempfile.new("thumbnail").tap(&:binmode)
FileUtils.cp @attachment.queued_for_write[:thumb].path, @thumb.path FileUtils.cp @attachment.queued_for_write[:thumb].path, @thumb.path
@attachment.save @attachment.save
@subject = Paperclip.io_adapters.for(@attachment.styles[:thumb]) @subject = Paperclip.io_adapters.for(@attachment.styles[:thumb])
end end
...@@ -108,6 +108,6 @@ class AttachmentAdapterTest < Test::Unit::TestCase ...@@ -108,6 +108,6 @@ class AttachmentAdapterTest < Test::Unit::TestCase
assert_equal expected.length, actual.length assert_equal expected.length, actual.length
assert_equal expected, actual assert_equal expected, actual
end end
end end
end end
...@@ -36,16 +36,16 @@ class StringioFileProxyTest < Test::Unit::TestCase ...@@ -36,16 +36,16 @@ class StringioFileProxyTest < Test::Unit::TestCase
should "return the data contained in the StringIO" do should "return the data contained in the StringIO" do
assert_equal "abc123", @subject.read assert_equal "abc123", @subject.read
end end
should 'accept a content_type' do should 'accept a content_type' do
@subject.content_type = 'image/png' @subject.content_type = 'image/png'
assert_equal 'image/png', @subject.content_type assert_equal 'image/png', @subject.content_type
end end
should 'accept an orgiginal_filename' do should 'accept an orgiginal_filename' do
@subject.original_filename = 'image.png' @subject.original_filename = 'image.png'
assert_equal 'image.png', @subject.original_filename assert_equal 'image.png', @subject.original_filename
end end
end end
end end
require './test/helper'
class UriProxyTest < Test::Unit::TestCase
context "a new instance" do
setup do
@open_return = StringIO.new("xxx")
@open_return.stubs(:content_type).returns("image/png")
Paperclip::UriAdapter.any_instance.stubs(:download_content).returns(@open_return)
@uri = URI.parse("http://thoughtbot.com/images/thoughtbot-logo.png")
@subject = Paperclip.io_adapters.for(@uri)
end
should "return a file name" do
assert_equal "thoughtbot-logo.png", @subject.original_filename
end
should "return a content type" do
assert_equal "image/png", @subject.content_type
end
should "return the size of the data" do
assert_equal @open_return.size, @subject.size
end
should "generate an MD5 hash of the contents" do
assert_equal Digest::MD5.hexdigest("xxx"), @subject.fingerprint
end
should "generate correct fingerprint after read" do
fingerprint = Digest::MD5.hexdigest(@subject.read)
assert_equal fingerprint, @subject.fingerprint
end
should "generate same fingerprint" do
assert_equal @subject.fingerprint, @subject.fingerprint
end
should "return the data contained in the StringIO" do
assert_equal "xxx", @subject.read
end
should 'accept a content_type' do
@subject.content_type = 'image/png'
assert_equal 'image/png', @subject.content_type
end
should 'accept an orgiginal_filename' do
@subject.original_filename = 'image.png'
assert_equal 'image.png', @subject.original_filename
end
end
context "a directory index url" do
setup do
Paperclip::UriAdapter.any_instance.stubs(:download_content).returns(StringIO.new("xxx"))
@uri = URI.parse("http://thoughtbot.com")
@subject = Paperclip.io_adapters.for(@uri)
end
should "return a file name" do
assert_equal "index.html", @subject.original_filename
end
should "return a content type" do
assert_equal "text/html", @subject.content_type
end
end
context "a url with query params" do
setup do
Paperclip::UriAdapter.any_instance.stubs(:download_content).returns(StringIO.new("xxx"))
@uri = URI.parse("https://github.com/thoughtbot/paperclip?file=test")
@subject = Paperclip.io_adapters.for(@uri)
end
should "return a file name" do
assert_equal "paperclip", @subject.original_filename
end
end
end
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