Skip to content

Instantly share code, notes, and snippets.

@chuckg
Last active February 22, 2016 08:23
Show Gist options
  • Save chuckg/5529193 to your computer and use it in GitHub Desktop.
Save chuckg/5529193 to your computer and use it in GitHub Desktop.
A Paperclip adapter to allow attachments to be set using a Mechanize::Download object; the default Paperclip::FileAdapter is incompatible with unlinked Tempfiles which Mechanize returns.
require 'paperclip'
module Paperclip
# Mechanize unlinks its Tempfiles immediately after creating them and some
# Paperclip functionality relies on an actual file available in the
# filesystem; not just a reference.
class MechanizeDownloadAdapter < AbstractAdapter
def initialize(target)
@target = target
cache_current_values
end
def cache_current_values
@original_filename = @target.filename
@tempfile = copy_to_tempfile(@target.body_io)
@content_type = ContentTypeDetector.new(@original_filename).detect
@size = @tempfile.size
end
def copy_to_tempfile(src)
# Download's are either a StringIO or a Tempfile; both respond to read.
while data = src.read(16*1024)
destination.write(data)
end
destination.rewind
destination
end
end
end
Paperclip.io_adapters.register Paperclip::MechanizeDownloadAdapter do |target|
target.is_a?(Mechanize::Download)
end
require 'spec_helper'
require 'paperclip/mechanize_download_adapter'
describe Paperclip::MechanizeDownloadAdapter do
let(:filename) { 'chuckg.jpg' }
let(:body_io) { StringIO.new('HELLO FRIENDS') }
class Mechanize::Download
# Stub initializer to nothing
def initialize
end
end
before do
@download = Mechanize::Download.new
@download.stub(:filename).and_return(filename)
@download.stub(:body_io).and_return(body_io)
end
subject { Paperclip.io_adapters.for(@download) }
it 'sets the original_filename' do
subject.instance_variable_get(:'@original_filename').should eq(filename)
end
it 'sets the tempfile' do
tempfile = subject.instance_variable_get(:'@tempfile')
tempfile.should be_a(Tempfile)
tempfile.length.should > 0
end
it 'sets the content_type' do
subject.instance_variable_get(:'@content_type').should eq('image/jpeg')
end
it 'sets the size' do
subject.instance_variable_get(:'@size').should eq(body_io.size)
end
it 'copies the contents of body_io to tempfile' do
expected = body_io.read
body_io.rewind
subject.read.should eq(expected)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment