Re: Sample code for displaying a MIME email message on a web page?

Joshua Baer
Sun, 05 Aug 2007 01:00:45 -0000

Thanks Kip!

I just found sanitize() and that seems to be a big part of what I''m
looking for. I''ll check out strip_links and strip_tags also!

~Josh



On Aug 4, 7:38 pm, Kip <kipco...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:
> Josh, I have done a *very* simple wrapper around this message parsing
> bit.  This will let you get at the parts of a mime multipart message.
> I guess you could use sanitize() strip_tags() and strip_links() to
> help make the html more displayable.  Note I just put this together
> for a proof-of-concept for emailing articles and images to a content
> system I''m writing so i sure wouldn''t cut and paste!
>
>   require ''hermes_messages.rb''
>   my_messages.HermesMessages.new
>   my_messages.get_messages(pop server parameters)
>   my_messages.message.each do |m|
>     # Each message has many parts, but we simplifiy with some helper
> methods
>     puts m.subject
>     puts m.from
>     puts m.body       # Note the ''body'' method retrieves
the text/
> plain part for my needs - modify as required to get the html part
>   end
>
> Hope this helps a little more,
>
> --Kip
>
> class HermesMessages
>   require ''net/pop''
>   require ''action_mailer''
>
>   EMPTY_PART = " \r\n\r\n"
>   TEXT_PLAIN = ''text/plain''
>   MULTIPART_ALTERNATIVE = ''multipart/alternative''
>
>   attr_reader :messages
>
>   def get_messages(host, user, password, port, *args)
>     options = args.last.is_a?(Hash) ? args.pop : {}
>     @messages = []
>     begin
>       Net::POP3.start(host, port, user, password) do |pop|
>         if pop.mails.empty?
>           puts ''No mail.''
>         else
>           puts "#{pop.mails.size} messages will be processed."
>           pop.each_mail do |m|
>            @messages << IncomingImageHandler.receive(m.pop)
>            m.delete if options[:delete] == true
>           end
>         end
>         puts "#{pop.mails.size} mails popped."
>         return pop.mails.size
>       end
>     rescue
>       puts "Exception detected - could not retrieve email"
>       return -1
>     end
>   end
>
>   class Message
>     attr_accessor :subject, :from
>     attr_reader :parts
>
>     def initialize
>       @parts = []
>     end
>
>     def add_part(p)
>       @parts << p
>     end
>
>     def has_jpeg?
>       parts.each {|p| return true if p.sub_type == "jpeg"}
>       return false
>     end
>
>     def has_body?
>       parts.each {|p| return true if p.main_type == "text"
&&
> p.sub_type == "plain"}
>       return false
>     end
>
>     def body
>       parts.each {|p| return p.body if p.main_type == "text"
&&
> p.sub_type == "plain"}
>       return ""
>     end
>
>     def jpeg
>       parts.each {|p| return p.body if p.main_type == "image"
&&
> p.sub_type == "jpeg"}
>       return ""
>     end
>
>     def image_filename
>       parts.each {|p| return p.filename if p.main_type == "image"
&&
> p.sub_type == "jpeg"}
>       return ""
>     end
>
>   end
>
>   class Content
>
> attr_accessor :main_type, :sub_type, :body, :filename, :file_extension,
:index
>   end
>
>   class IncomingImageHandler < ActionMailer::Base
>     # email is a TMail::Mail
>     def receive(email)
>       @message = Message.new
>       @message.from = email.from[0]
>       @message.subject = email.subject
>       puts "Processing message: #...@message.subject}"
>       process(email)
>     end
>
>   protected
>
>     def process(part)
>       if part.multipart? then
>         part.parts.each {|p| process(p) } unless
>           part.content_type == MULTIPART_ALTERNATIVE &&
>           plain_part_is_empty(part)
>       else
>         process_part(part)
>       end
>       return @message
>     end
>
>     def process_part(part)
>       puts "   part: #{part.content_type} with size
> #{part.body.length}"
>       pp "     content is: ''#{part.body}''" if
part.body.length <= 10
>       content = Content.new
>       content.main_type = part.main_type
>       content.sub_type = part.sub_type
>       content.body = part.body
>       content.filename = part_filename(part)
>       content.file_extension = ext(part)
>       @message.add_part(content)
>     end
>
>   private
>
>     def plain_part_is_empty(part)
>       part.parts.each do |p|
>         return true if p.content_type == TEXT_PLAIN && p.body =>
EMPTY_PART
>       end
>       return false
>     end
>
>     def part_filename(part)
>       # get filename
>       if part[''content-location''] != nil &&
part[''content-
> location''].body.length != 0
>         filename = part[''content-location''].body
>       elsif part.type_param(''name'') != nil  &&
> part.type_param(''name'').length != 0
>         filename = part.type_param(''name'')
>       elsif part.disposition_param(''filename'') != nil
&&
> part.disposition_param(''filename'').length != 0
>         filename = part.disposition_param(''filename'')
>       else
>         filename = nil
>       end
>     end
>
>     CTYPE_TO_EXT = {
>       ''image/jpeg'' => ''jpg'',
>       ''image/gif''  => ''gif'',
>       ''image/png''  => ''png'',
>       ''image/tiff'' => ''tif''
>     }
>
>     def ext( mail )
>       CTYPE_TO_EXT[mail.content_type] || ''txt''
>     end
>   end #class
> end
>
> On Aug 4, 6:37 pm, Kip
<kipco...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> > Josh, I found the following very helpful:
>
>
>http://blog.mondragon.cc/articles/2006/12/30/decoding-email-attachmen...
>
> > Cheers, --Kip
>
> > On Aug 4, 11:08 am, Joshua Baer
<joshuab...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
> > > Can anyone point me to a good source of sample code for taking a
raw
> > > email message (multipart, with attachments) and displaying it on
a web
> > > page? Also same thing for composing a new message with
attachments?
>
> > > ~Josh