Maildir::Lite - A very simple implementation of Maildir
Write to a file handle:
my $mdir=Maildir::Lite->new(dir=>'/home/d/.maildir'); ... # write messages my ($fh,$status)=$mdir->creat_message(); die "creat_message failed" if $status; print $fh "Content-Type: text/plain\n" ."Date: $date\n" ."From: $from\n" ."To: $to\n" ."Subject: $subject\n\n" ."$message"; die "delivery failed!\n" if $mdir->deliver_message($fh);
Write string and deliver message directly:
my $status=$mdir->creat_message($email_content); die "creat_message failed" if $status;
Read new messages given a file handle:
my ($fh,$status)=$mdir->get_next_message("new"); unless($status) { while(<$fh>) { # read message ... } } $mdir->act($fh,'S'); # flag message as seen and move to cur
Read new messages into an array and flag message as seen while moving it to cur:
my ($fh,$status)=$mdir->get_next_message("new",\@lines,'S');
This is a simple and very light implementation of Maildir as specified by D. J. Bernstein at http://cr.yp.to/proto/maildir.html
This module provide the user with a simple interface to reading and writing email messages to maildir folders. Some additional useful features are also supported (e.g. support for additional subdirecties and user defined actions for the maildir flags).
my $maildir = Maildir::Lite->new(); my $maildir = Maildir::Lite->new(create=>1, dir=>'.maildir/', mode=>0750, sort=>'asc');
create - if set to 0, the directory and the subdirectories will not be created and are assumed to exist.
create
dir - the maildir directory; it defaults to ~/.maildir (if $ENV{HOME} exits).
dir
$ENV{HOME}
mode - the (default 0750) directory permissions of dir and sub-directories.
mode
uniq - set unique integer which will be otherwise randomly generated for filennames; it is important that uniq is actually unique.
uniq
sort - the read messege sorting method. See "sort".
sort
Add a specific $action (function or 'close') to $folder for the $flag flag.
$action
$folder
$flag
For example, if you wish to move files from new to trash when given the flag 'T' (or 'trash'):
$mdir->add_action('new','trash',\&new_to_trash);
Specifiying 'close' closes the file, without appending the info or moving the file.
The default action for folder new is to move it to cur and append the flag 'S' flag. Reading messages from cur or tmp by default only closes the file.
Returns 0 upon success, -1 otherwise.
Example of action function:
sub new_to_trash { my ($path, $filename,$action)=@_; my $flag=uc(substr($action,0,1)); if($flag eq 'T') { if(-d "$path/trash/") { my $old="$path/new/$filename"; my $new="$path/trash/$filename:2,$flag"; if(rename($old,$new)) { return 0; } else { die("failed to rename \'$old\' to \'$new\'"); } } else { die("\'$path/trash\' directory does not exist"); } } return -1; }
Set the maildir path:
$maildir->dir('/tmp/.maildir/');
Get the maildir path:
$maildir->dir();
Set the mode for creating the directory and subdirectories tmp, cur and new:
$maildir->mode(0754);
Get the mode:
$maildir->mode();
Create the directory and subdirectories tmp, cur and new if they do not already exist:
$maildir->mkdir();
As above, but create the additional directories trash, sent:
$maildir->mkdir("trash","sent");
This subroutine does not need to be explicitly called before creating new messages (unless you want to create folders other than tmp, new, and cur).
This subroutine returns 0 if the directories were created (or exist), otherwise it returns -1 and a warning with carp.
Get a file handle $fh to a unique file in the tmp subdirectory:
$fh
my ($fh,$status) = $maildir->creat_message();
Write message to unique file in tmp subdirectory which is then delivered to new:
my $status=$maildir->creat_message($message);
Return: $status is 0 if success, -1 otherwise. $fh is the filehandle (undef if you pass create_message an argument).
$status
undef
create_message
Given file handle $fh, deliver message and close handle:
$maildir->deliver_message($fh);
Deliver all messages and close all handles:
$maildir->deliver_all_messages();
Get the current method for sorting messages:
my $sort=$maildir->sort();
Set the sorting function of method:
$maildir->sort('non'); # no specific sorting $maildir->sort('asc'); # sort based on mtime in increasing order $maildir->sort('des'); # sort based on mtime in decreasing order $maildir->sort(\&func); # sort based on user defined function
Example of sorting function which sorts according to a line in the message beggining with "sort:" followed by possible spaces and then a digit:
sub func { my ($path,@messages)=@_; my %files; my @newmessages; foreach my $file (@messages) { my $f; open($f,"<$path/$file") or return @messages; #don't sort while(my $line=<$f>) { if($line=~m/sort:\s*(\d)+$/) { # string where sort info is $files{$file}=$1; close($f); last; } } } @newmessages= sort { $files{$a} <=> $files{$b}} keys %files; return @newmessages; }
Get the next message (as file handle) from directory new:
my ($fh,$status)=$maildir->get_next_message("new");
NOTE: It is important to properly close file handle once finished with "close_message" or "act".
Read lines of next message in array @lines then, close message and execute the action specified for flag 'P' (default for new: move to cur and append ':2,P'):
my $status=$maildir->get_next_message("new",\@lines,'passed');
Return: $status is 0 if success, -1 otherwise. $fh is the filehandle (undef if you pass get_next_message a second argument).
get_next_message
Force a readdir during the next "get_next_message". This is useful if you are reading messages from new and then from cur as some of the messages will be moved there.
$mdir->force_readdir();
Given file handle $fh, close handle:
$maildir->close_message($fh);
Given file handle $fh, and flag ('P','R','S','T','D','F') close message, append the info and execute the specified action for the flag:
$maildir->act($fh,'T');
The example shows the use of this module with MIME::Entity to write messages.
#!/usr/bin/perl use strict; use warnings; use MIME::Entity; use Maildir::Lite; my $mdir=Maildir::Lite->new(dir=>'/tmp/.your_mdir'); # print message to file handle sub print_message { my ($from,$to,$subj,$message,$fh)=@_; my $date=localtime; my $msg = MIME::Entity->build( Type => 'text/plain', Date => $date, From => $from, To => $to, Subject => $subj, Data => $message); $msg->print($fh); } # write messages to maildir folder sub write_message { my ($from,$to,$subj,$message)=@_; my ($fh,$stat0)=$mdir->creat_message(); die "creat_message failed" if $stat0; print_message($from,$to,$subj,$message,$fh); die "delivery failed!\n" if $mdir->deliver_message($fh); } write_message('me@foo.org', 'you@bar.com','Hi!','One line message'); write_message('me@foo.org', 'bar@foo.com','Bye!','Who are you?'); write_message('me2@food.org', 'bar@beer.org','Hello!','You again?');
The example shows the use of this module with MIME::Parser to read messages.
#!/usr/bin/perl use strict; use warnings; use MIME::Parser; use Maildir::Lite; my $mdir=Maildir::Lite->new(dir=>'/tmp/.your_mdir'); # move file from new to trash with changed filename sub read_from { my $folder=shift; my $i=0; $mdir->force_readdir(); print "$folder:\n|".("-"x20)."\n"; while(1) { my $parser = new MIME::Parser; $parser->output_under("/tmp"); my ($fh,$status)=$mdir->get_next_message($folder); last if $status; my $entity=$parser->parse($fh); print "Message $i:\n".$entity->stringify."\n"; $i++; if($mdir->act($fh,'S')) { warn("act failed!\n"); } } print "|".("-"x20)."\n\n"; } read_from("cur"); read_from("new"); read_from("cur"); # to see the force_readdir in action read_from("new");
There is already an implementation of Maildir, Mail::Box::Maildir, which is great, but more bulky and complicated.
Maildir specifications at http://cr.yp.to/proto/maildir.html
Version 0.01
Deian Stefan, <stefan at cooper.edu>
<stefan at cooper.edu>
http://www.deian.net
Please report any bugs or feature requests to bug-maildir-lite at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Maildir-Lite. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
bug-maildir-lite at rt.cpan.org
You can find documentation for this module with the perldoc command.
perldoc Maildir::Lite
You can also look for information at:
RT: CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Maildir-Lite
AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/Maildir-Lite
CPAN Ratings
http://cpanratings.perl.org/d/Maildir-Lite
Search CPAN
http://search.cpan.org/dist/Maildir-Lite
Copyright 2008 Deian Stefan, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
To install Maildir::Lite, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Maildir::Lite
CPAN shell
perl -MCPAN -e shell install Maildir::Lite
For more information on module installation, please visit the detailed CPAN module installation guide.