Skip to content

Instantly share code, notes, and snippets.

@maxim
Created February 4, 2009 03:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxim/57905 to your computer and use it in GitHub Desktop.
Save maxim/57905 to your computer and use it in GitHub Desktop.
module Paperclipful
module UploadedFileExtensions
def to_xml(options = {})
options.reverse_merge! :indent => 2, :root => self.class.to_s.split('::').last.underscore
xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent], :root => options[:root])
xml.instruct! unless options[:skip_instruct]
self.rewind
xml.tag!(options[:root], :type => :attachment) do
xml.original_path self.original_path
xml.content_type self.content_type
xml.file_size self.size
xml.data Base64::encode64s(self.read)
end
end
end
module PaperclipAttachmentExtensions
def to_xml(options = {})
options.reverse_merge! :indent => 2, :root => self.class.to_s.demodulize.underscore
xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent], :root => options[:root])
xml.instruct! unless options[:skip_instruct]
xml.tag!(options[:root], :type => :attachment) do
self.instance.attributes.select do |k,v|
k.starts_with?("#{options[:root]}_")
end.each do |name, value|
xml.tag!((name.split('_') - [options[:root].to_s]).join('_'), value)
end
xml.url do
xml.original self.url
self.styles.keys.each do |style|
xml.tag!(style, self.url(style))
end
end
xml.path do
xml.original self.path
self.styles.keys.each do |style|
xml.tag!(style, self.path(style))
end
end
end
end
end
module ActiveRecordExtensions
def self.included(base)
base.class_eval do
alias_method_chain :to_xml, :attachments
if attachment_definitions
attachment_definitions.each do |name, value|
define_method "#{name}_with_attachment=" do |arg|
uploaded_object = if (arg.is_a?(Hash) && arg["type"] == "attachment")
uploaded_object = UploadedStringIO.new(Base64::decode64(arg.data))
uploaded_object.original_path = arg.original_path
uploaded_object.content_type = arg.content_type
uploaded_object
else
arg
end
method("#{name}_without_attachment=").call(uploaded_object)
end
alias_method_chain "#{name}=", :attachment
end
end
end
end
def to_xml_with_attachments(options = {}, &block)
options[:indent] ||= 2
xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
if (self.class.respond_to?(:attachment_definitions) &&
self.class.attachment_definitions &&
self.class.attachment_definitions.size > 0)
attachment_names = self.class.attachment_definitions.keys
unneeded_attributes = attributes.keys.select do |attr_name|
attachment_names.any?{|attachment_name| attr_name.starts_with?("#{attachment_name}_")}
end
options[:except] ||= []
options[:except] = unneeded_attributes
to_xml_without_attachments(options) do
each_attachment do |name, attachment|
attachment.to_xml(:builder => xml, :skip_instruct => true, :root => name)
end
block.call(xml) if block
end
else
to_xml_without_attachments(options, &block)
end
end
end
end
class ActiveResource::Base
# Patching ActiveResource::Base to make it work with <object> tag
# Ticket #1828
def find_or_create_resource_for(name)
resource_name = name.to_s.camelize
raise NameError if name.to_s.downcase == "object"
ancestors = self.class.name.split("::")
if ancestors.size > 1
find_resource_in_modules(resource_name, ancestors)
else
self.class.const_get(resource_name)
end
rescue NameError
if self.class.const_defined?(resource_name)
resource = self.class.const_get(resource_name)
else
resource = self.class.const_set(resource_name, Class.new(ActiveResource::Base))
end
resource.prefix = self.class.prefix
resource.site = self.class.site
resource
end
# Patching ActiveResource::Base missing new_record?
# Ticket #1455
if !respond_to?(:new_record?)
alias :new_record? :new?
end
end
# Patching UploadedStringIO and UploadedTempfile to make it XML-serializable
[ ActionController::UploadedStringIO,
ActionController::UploadedTempfile ].each do |klass|
klass.send :include, Paperclipful::UploadedFileExtensions
end
# Patching Paperclip::Attachment to make it XML-serializable
Paperclip::Attachment.send :include, Paperclipful::PaperclipAttachmentExtensions
# Patching ActiveRecord::Base to make it handle XML-serialize attachments
ActiveRecord::Base.send :include, Paperclipful::ActiveRecordExtensions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment