Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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.
  • Loading branch information...
commit 5d06ad8c570354db59d067613b04841833252a8d 1 parent 786a13f
Aditya Sanghi asanghi authored jyurek committed
1  lib/paperclip.rb
View
@@ -223,3 +223,4 @@ def attachment_definitions
require 'paperclip/io_adapters/nil_adapter'
require 'paperclip/io_adapters/attachment_adapter'
require 'paperclip/io_adapters/uploaded_file_adapter'
+require 'paperclip/io_adapters/uri_adapter'
42 lib/paperclip/io_adapters/uri_adapter.rb
View
@@ -0,0 +1,42 @@
+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
14 test/io_adapters/attachment_adapter_test.rb
View
@@ -1,12 +1,12 @@
require './test/helper'
class AttachmentAdapterTest < Test::Unit::TestCase
-
+
def setup
rebuild_model :path => "tmp/:class/:attachment/:style/:filename", :styles => {:thumb => '50x50'}
@attachment = Dummy.new.avatar
end
-
+
context "for an attachment" do
setup do
@file = File.new(fixture_file("5k.png"))
@@ -53,19 +53,19 @@ def setup
assert_equal expected.length, actual.length
assert_equal expected, actual
end
-
+
end
-
+
context "for a style" do
setup do
@file = File.new(fixture_file("5k.png"))
@file.binmode
@attachment.assign(@file)
-
+
@thumb = Tempfile.new("thumbnail").tap(&:binmode)
FileUtils.cp @attachment.queued_for_write[:thumb].path, @thumb.path
-
+
@attachment.save
@subject = Paperclip.io_adapters.for(@attachment.styles[:thumb])
end
@@ -108,6 +108,6 @@ def setup
assert_equal expected.length, actual.length
assert_equal expected, actual
end
-
+
end
end
6 test/io_adapters/stringio_adapter_test.rb
View
@@ -36,16 +36,16 @@ class StringioFileProxyTest < Test::Unit::TestCase
should "return the data contained in the StringIO" do
assert_equal "abc123", @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
end
82 test/io_adapters/uri_adapter_test.rb
View
@@ -0,0 +1,82 @@
+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
Please sign in to comment.
Something went wrong with that request. Please try again.