NAME

Mail::MboxParser - read-only access to UNIX-mailboxes

SYNOPSIS

use Mail::MboxParser;

my $mb = Mail::MboxParser->new('some_mailbox');

for my $msg ($mb->get_messages) {
	print $msg->from->{name}, "\n";
	print $msg->from->{email}, "\n";
	print $msg->header->{subject}, "\n";
	print $msg->header->{'reply-to'}, "\n";
	$msg->store_all_attachements('/tmp');
}

DESCRIPTION

This module attempts to provide a simplified access to standard UNIX-mailboxes. It offers only a subset of methods to get 'straight to the point'. More sophisticated things can still be done by invoking any method from MIME::Tools on the appropriate return values.

METHODS

The below methods refer to Mail::MboxParser-objects.

new
new(MAILBOX)

This creates a new MboxParser-object opening the specified MAILBOX with either absolute or relative path. It does not necessarily need a parameter in which case you need to pass the mailbox to the object using the method 'open'. Returns nothing.

open(mailbox)

Can be used to either pass a mailbox to the MboxParser-object either the first time or for changing the mailbox. Returns nothing.

get_messages

Returns an array containing all messages in the mailbox respresented as Mail::MboxParser::Mail objects.

nmsgs

Returns the number of messages in a mailbox. You could naturally also call get_messages in an array context, but this one wont create new objects. It just counts them and thus it is much quicker and wont eat a lot of memory.

The below methods refer to Mail::MboxParser::Mail-objects returned by get_messages.

new(header, body)

This is usually not called directly but instead by $mb->get_messages. You could however create a mail-object manually providing the header and body both as one string.

Returns the mail-header as a hash-ref with header-fields as keys. All keys are turned to lower-case, so $header{Subject} has to be written as $header{subject}.

body

Returns the body as a single string.

from

Returns a hash-ref with the two fields 'name' and 'email'. Returns undef if empty.

id

Returns the message-id of a message cutting off the leading and trailing '<' and '>' respectively.

num_entitities

Returns the number of MIME-entities. That is, the number of sub-entitities actually.

get_entitities([n])

Either returns an array of all MIME::Entity objects or one particular if called with a number.

get_entity_body(n)

Returns the body of the n-th MIME::Entity as a single string.

store_entity_body(n, FILEHANDLE)

Stores the stringified body of n-th entity to the specified filehandle. That's basically the same as:

my $body = $mail->get_entity_body(0);
print FILEHANDLE $body;

and could be shortened to this:

$mail->store_entity_body(0, \*FILEHANDLE);
store_attachement(n, path)

It is really just a call to store_entity_body but it will take care that the n-th entity really is a saveable attachement. That is, it wont save anything with a MIME-type of, say, text/html or so. It uses the recommended-filename found in the MIME-header. 'path' is the place where the new file will go to.

store_all_attachements(path)

Walks through an entire mail and stores all apparent attachements to 'path'. See the supplied store_att.pl script in the eg-directory of the package to see a useful example.

FIELDS

Mail::MboxParser basically is a hash-ref:

$mb->{READER}

This is the filehandle from which is read internally. As to yet, it is read-only so you can't use it for writing. This may be changed later.

$mb->{NMSGS}

Having called nmsgs once this field contains the number of messages in the mailbox. Thus there is no need for calling the method twice which speeds up matters a little.

Mail::MboxParser::Mail consists of the following fields:

$mail->{RAW}

This field no longer exists in order to save memory. Instead, do something like

$entire_message = $mail->{HEADER}.$mail->{BODY};
$mail->{HEADER}

Well, just the header of the message as a string.

$mail->{BODY}

You guess it.

$mail->{TOP_ENTITY}

The top-level MIME::Entity of a message. You can call any suitable methods from the MIME::tools upon this object to give you more specific access to MIME-parts.

This field is undefined until one of the MIME-methods (num_entities, get_entities etc.) is called for the sake of efficiency.

CAVEATS

I have been working hard on making Mail::MboxParser eat less memory and as quick as possible. Due to that, two time and memory consuming matters are now called on demand. That is, parsing out the MIME-parts and turning the raw header into a hash have become closures.

The drawback of that is that it may get inefficient if you often call

$mail->header->{field}

In this case you should probably save the return value of $mail->header (a hashref) into a variable since each time you call it the raw header is parsed.

On the other hand, if you have a mailbox of, say, 25MB, and hold each header of each message in memory, you'll quickly run out of that. So, you can now choose between more performance and more memory.

This all does not happen if you just parse a mailbox to extract one header-field (eg. subject), work with that and exit. In this case it will need both less memory and is still considerably quicker. :-)

Below you see two tables produced by the Benchmark module. I compared my module (0.06) with Mail::Box, Mail::Folder and Mail::Folder::FastReader (grepmail), while the second table shows the same with 0.07 of Mail::MboxParser. I only let the modules iterate over the mailbox and count the number of messages by extracting them. There is no single header-field extracted. So keep that in mind. Mail::MboxParser is slower than 330/s when you call $mail->header.

Rate Mail::Folder Mail::Box Mail::MboxParser grepmail
Mail::Folder     23.2/s           --      -76%             -89%     -99%
Mail::Box        97.1/s         318%        --             -53%     -95%
MboxParser        206/s         786%      112%               --     -89%
grepmail         1852/s        7878%     1807%             800%       --

Rate Mail::Folder Mail::Box Mail::MboxParser grepmail
Mail::Folder     23.2/s           --      -76%             -93%     -99%
Mail::Box        97.2/s         318%        --             -71%     -95%
Mail::MboxParser  330/s        1320%      240%               --     -82%
grepmail         1852/s        7867%     1806%             461%       --

grepmail is obviously the fastest of all (it is written in C using Inline). Mail::Folder performs worst, but that's because it uses temporary files and will probably need only a little memory.

Mail::Box by Mark Overmeer is closer to Mail::MboxParser with mailboxes that contain binary-attachements, I don't know why. More to that, it only eats about 50% the memory that Mail::MboxParser needs while still providing more features (at the same time being a little bit more complex in usage).

BUGS

Don't know yet of any. However, since I only have a limited number of mailboxes on which I could test the module, there might be circumstances under which Mail::MboxParser fails to work correctly. It might fail on mal-formated mails produced by some cheap CGI-webmailers.

The way of counting the messages and detecting them now complies to RFC 822. This is, however, no guarentee that it all works seamlessly. There are just so many mailboxes that get screwed up by mal-formated mails.

THANKS

Thanks to a number of people who gave me invaluable hints that helped me with Mail::Box, notably Kenn Frankel and Mark Overmeer.

AUTHOR AND COPYRIGHT

Tassilo von Parseval <Tassilo.Parseval@post.RWTH-Aachen.de>.

Copyright (c) 2001 Tassilo von Parseval. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 283:

'=end' without a target?