http://qs321.pair.com?node_id=207669

hacker has asked for the wisdom of the Perl Monks concerning the following question:

I've been working on a script that takes an incoming mail message (via Mail::Internet), parses out a template from the body of the message (via Config::General), executes on the key=value elements inside that template, runs a process that generates a few files (one binary file, one text file, one small html file), and sends them back to the user as attachments (via MIME::Lite) in either "raw" format (three files attached), or as one zip file containing the three attachments (via Archive::Zip). So far, this works beautifully.

What I'd like to do next, is allow the user to send the original mail with the template attached to the incoming message, rather than copied into the body of the message. I would then "detach" the template, parse it as before, and reply as normal. The problem I've run into is finding actual code that can deal with "detachments" in this fashion, where the incoming message is a stream, not written to a file on disk or into a mailbox.

I've Super Searched for anything related to "attachments" here, and found quite a few examples and code snippets, but almost all of them assume that the message resides inside a mailbox of mbox or maildir type. The incoming message is literally a stream of bytes, which I have to then splice up into header, body, and attachment. I did find MIME Attachment Extractor, which looked promising, but didn't seem to work with the incoming data I've got (never decoded it back to the original text file).

I've also looked at MIME::Decoder, MIME::Entity, MIME::Parser, and others, without much success. I can get the envelope and body, but for some reason, the attachment eludes me, or never decodes off in the right format (i.e. as a text file). It always seems to decode back to even worse binary junk than the raw attachment itself.

Has anyone done something similar to this, where the message is in a stream (not a mailbox) and successfully splice off the relevant parts of the incoming stream (envelope, body, attachment(s))? I'm looking for pointers to workable modules I may have overlooked, or small bits of code to point me in the right direction to banging this next feature out. Thanks again for any help, my fellow monks.

Replies are listed 'Best First'.
Re: Dealing with "Detachments"
by joe++ (Friar) on Oct 24, 2002 at 12:50 UTC
    Maybe a partial solution: if your stream is actually just a scalar (e.g. in variable $body), then you may treat is as a file handle via IO::Scalar. If the method you'd like to call accepts a filehandle, this does the trick:

    use strict; use IO::Scalar; my $body = &get_body(); # whatever... my $handle = new IO::Scalar($body); # now call the method that expects a file handle
    I used this succesfully on XML::Simple, which can be instantiated with either a filename or a filehandle. If your module really only groks filenames, then you're out of luck and may need to revert to a tempfile of some kind.

    HTH!

    --
    Cheers, Joe

Re: Dealing with "Detachments"
by jlongino (Parson) on Oct 24, 2002 at 15:13 UTC
    I think that if you want to work with attachments that Mail::Internet isn't going to be much help. Maybe the best course of action would be to find out why MIME::Parser isn't working for you. Is it possible that the message you're receiving doesn't comply fully with RFC822 standards?

    Also, since I suspect you'll need a different method for getting your message from the mailserver, can you use Mail::POP3Client or Mail::IMAPClient to get the message?

    If you can send me a sample E-mail I'll try a few things and let you know what I find. The process might take a few hours though since I'd probably have to wait until lunch to take a look at it.

    --Jim

    A reply falls below the community's threshold of quality. You may see it by logging in.