Re: Mail::Box::IMAP updates

Trond Michelsen <[email protected]> Tue, 21 Dec 2004 15:07:59 +0100
Newsgroups gmane.comp.lang.perl.modules.mail-box
Message-ID <[email protected]>
On Sun, Dec 19, 2004 at 09:02:17PM -0500, Tom Allison wrote:
> What I'm really after is trying to use the Mail::Box architecture to 
> build an IMAP webclient that runs with HTML::Mason.  From what I've done 

I was trying this a while ago, but had to abandon it due to memory
issues. A message with a 30MB attachment would eat up something like
150MB of memory. Which is rather unacceptable in a mod_perl
environment. I meant to have a look at the Mail::Message modules to
see if I could get it to not read the entire message into memory,
unless the user requests it, but I got a new job before I had the
time. I'm not sure if anything's changed with Mail::Box by now, though.

This could also be a problem with the IMAP-module. Even in a local
network, you can easily get performance issues if you download 30MB
unneccessarily, fairly often.

If you're sure you'll never encounter emails this large, then you can
probably ignore the issue, though :)

Another problem is the number of mails. If you have a mailbox with
10,000 entries, and you're only interested in displaying 100 of them,
you'd want to make sure that you're only pulling 100 headers from the
IMAP-server. Even if the objects are fairly small and fast to create,
it can slow down things a lot if you're only using 1% of the objects
you've created.

I've also had a look at the Email::* modules, but it seems that one of
the design goals of that project has been to make a system that's
unusable in the real world.

> so far with the directories and other searches, the combination of 
> Mail::Box (Mail::IMAPClient) and HTML::Mason creates an extremely high 
> performance interface.  I have looked into the various methods of Mail 
> to HTML and quite frankly they all give me a headache.  MIME is 
> fantastically ugly.

Well, MIME::Entity (the object returned from MIME::Parser) goes pretty
well together with Template::Toolkit. I expect it to work equally well
with HTML::Mason.

The template show_entity.tt that displays the MIME-body looks
something like this:

--8<--
[%
   mime = part.mime_type;
   TRY;
     template = "mime/" _ mime _ ".tt";
     INCLUDE $template part = part;
   CATCH;
     IF error.type == "file";
        IF part.is_multipart;
           INCLUDE mime/multipart/mixed.tt part = part;
        ELSE;
           INCLUDE mime/attachment.tt part = part;
        END;
     ELSE;
        INCLUDE mime/error.tt part = part;
     END;
   END;
%]
--8<--

then I have different templates for each mime-type, e.g. text/plain.tt

--8<--
[%
   charset = part.head.mime_attr("content-type.charset");
   content = part.bodyhandle.as_string | to_utf8(charset);
   filename = part.head.recommended_filename;

   IF filename;
      PROCESS add_attachment part=part;
   ELSE;
      INCLUDE mime/plaintext.tt content = content;
   END;
%]
--8<--


multipart/mixed.tt:
--8<--
[%
   FOREACH subpart IN part.parts;
      INCLUDE mime/show_entity.tt part = subpart;
   END;
%]
--8<--


image/jpeg.tt:
--8<--
[%- PROCESS mime/save_attachment.tt part = part;
filename = part.bodyhandle.path | replace(".*/", "");
IF inline_images -%]
<img src="/mail/attachment/[% filename %]"><br>
[%- END -%]
--8<--

and so on. 

It worked very well, and it made it very easy to support pretty much
any mime-type we felt like displaying in the web-interface.

-- 
Trond Michelsen