NAME

IMAP::BodyStructure - IMAP4-compatible BODYSTRUCTURE and ENVELOPE parser

SYNOPSIS

use IMAP::BodyStructure;

# $imap is a low-level IMAP-client with an ability to fetch items
# by message uids

my $bs = new IMAP::BodyStructure
    $imap->imap_fetch($msg_uid,
            'BODYSTRUCTURE', 1)->[0]->{BODYSTRUCTURE};

print "[UID:$msg_uid] message is in Russian. Sure.\n"
    if $bs->charset =~ /(?:koi8-r|windows-1251)/i;

my $part = $bs->part_at('1.3');
$part->type =~ m#^image/#
    and print "The 3rd part is an image named \""
        . $part->filename . "\"\n";

DESCRIPTION

An IMAP4-compatible IMAP server MUST include a full MIME-parser which parses the messages inside IMAP mailboxes and is accessible via BODYSTRUCTURE fetch item. This module provides a Perl interface to parse the output of IMAP4 MIME-parser. Hope no one will have problems with parsing this doc.

It is a rather straightforward m/\G.../gc-style parser and is therefore much, much faster then the venerable Mail::IMAPClient::BodyStructure which is based on a Parse::RecDescent grammar. I believe it is also more correct when parsing nested multipart message/rfc822 parts. See testsuite if interested.

I'd also like to emphasize that this module does not contain IMAP4 client! You will need to employ one from CPAN, there are many. A section with examples of getting to a BODYSTRUCTURE fetch item with various Perl IMAP clients available on CPAN would greatly enhance this document.

INTERFACE

METHODS

DATA MEMBERS

These are additional pieces of information returned by IMAP server and parsed. They are rarely used, though (and rarely defined too, btw), so I chose not to provide access methods for them.

cid and md5 members exist only in singlepart parts.

IMAP::BodyStructure::Envelope CLASS

Every message on an IMAP server has an envelope. You can get it using ENVELOPE fetch item or, and this is relevant, from BODYSTRUCTURE response in case there are some nested messages (parts with type of message/rfc822). So, if we have a part with such a type then the corresponding IMAP::BodyStructure object always has envelope data member which is, in turn, an object of IMAP::BodyStructure::Envelope.

You can of course use this satellite class on its own, this is very useful when generating meaningful message lists in IMAP folders.

METHODS

DATA MEMBERS

EXAMPLES

The usual way to determine if an email has some files attached (in order to display a cute little scrap in the message list, e.g.) is to check whether the message is multipart or not. This method tends to give many false positives on multipart/alternative messages with a HTML and plaintext parts and no files. The following sub tries to be a little smarter.

sub _has_files {
    my $bs = shift;

    return 1 if $bs->{type} !~ m#^(?:text|multipart)/#;

    if ($bs->{type} =~ m#^multipart/#) {
        foreach my $part (@{$bs->{parts}}) {
            return 1 if _has_files($part);
        }
    }

    return 0;
}

This snippet selects a rendering routine for a message part.

foreach (
    [ qr{text/plain}            => \&_render_textplain  ],
    [ qr{text/html}             => \&_render_texthtml   ],
    [ qr{multipart/alternative} => \&_render_alt        ],
    [ qr{multipart/mixed}       => \&_render_mixed      ],
    [ qr{multipart/related}     => \&_render_related    ],
    [ qr{image/}                => \&_render_image      ],
    [ qr{message/rfc822}        => \&_render_rfc822     ],
    [ qr{multipart/parallel}    => \&_render_mixed      ],
    [ qr{multipart/report}      => \&_render_mixed      ],
    [ qr{multipart/}            => \&_render_mixed      ],
    [ qr{text/}                 => \&_render_textplain  ],
    [ qr{message/delivery-status}=> \&_render_textplain ],
) {
    $bs->type =~ $_->[0]
        and $renderer = $_->[1]
        and last;
}

BUGS

Shouldn't be any, as this is a simple parser of a standard structure.

AUTHOR

Alex Kapranoff <alex@kapranoff.ru>

ACKNOWLEDGMENTS

Jonas Liljegren contributed support for multivalued "lang" items.

COPYRIGHT AND LICENSE

This software is copyright (C) 2015 by Alex Kapranoff <alex@kapranoff.ru>.

This is free software; you can redistribute it and/or modify it under the terms GNU General Public License version 3.

SEE ALSO

Mail::IMAPClient, Net::IMAP::Simple, RFC3501, RFC2045, RFC2046.