The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Mail::Box::MH - Handle folders with a file per message.

SYNOPSIS

   use Mail::Box::MH;
   my $folder = new Mail::Box::MH folder => $ENV{MAIL}, ...;

DESCRIPTION

Mail::Box::MH extends Mail::Box and Mail::Box::Index to implements MH-type folders. This manual-page describes Mail::Box::MH and Mail::Box::MH::* packages. Read Mail::Box::Manager and Mail::Box first.

Handle file-based folders, where each folder is represented by a directory, and each message by a file in that directory. Messages are numbered.

The name of a folder may be an absolute or relative path. You can also preceed the foldername by =, which means that it is relative to the folderdir as specified at new.

Delayed loading

Folder-types which store their messages each in one file, together in one directory, are bad for performance. Consider that you want to know the subjects of all messages.

Mail::Box::MH has two ways to try improve performance. If you specify keep_index as option to the folder creation method new(), then all header-lines of all messages will be written into the specified index-file (one file per folder).

If you do not use an index-file, then the only thing what the opening of a folder does is invertoring which message-files exists. Nothing else. For any request to any message, that message will be autoloaded. If the first request is for a header-line, then only the header is parsed, and the message still left in the file. For anything else, the whole message is parsed.

The index-file is farmost best performing, but also in the second case, performance can be ok. When you have opened a huge folder, only a few of those folders will be presented on the screen as index. To present the index we need the subject, hence we need to load the header of these messages. When you scroll through the index, header after header is parsed. If you want to read you messages in threads, you have a serious performance problem: threads can only be displayed if all message headers were read. In this case, you should use an index-file.

PUBLIC INTERFACE

new ARGS

Create a new folder. The are many options which are taken from other objects. For some, different options are set. For MH-specific options see below, but first the full list.

 access            Mail::Box          'r'
 dummy_type        Mail::Box::Threads 'Mail::Box::Message::Dummy'
 folder            Mail::Box          $ENV{MAIL}
 folderdir         Mail::Box          <no default>
 index_filename    Mail::Box::Index   foldername.'/.index'
 keep_index        Mail::Box::Index   0
 labels_filename   Mail::Box::MH      foldername.'/.mh_sequence'
 lazy_extract      Mail::Box          10kb
 lockfile          Mail::Box::Locker  foldername.'/.lock'
 lock_method       Mail::Box::Locker  'dotlock'
 lock_timeout      Mail::Box::Locker  1 hour
 lock_wait         Mail::Box::Locker  10 seconds
 message_type      Mail::Box          'Mail::Box::MH::Message'
 notreadhead_type  Mail::Box          'Mail::Box::Message::NotReadHead'
 notread_type      Mail::Box          'Mail::Box::MH::Message::NotParsed'
 realhead_type     Mail::Box          'MIME::Head'
 remove_when_empty Mail::Box          1
 save_on_exit      Mail::Box          1
 take_headers      Mail::Box          <specify everything you need>
 <none>            Mail::Box::Tie

MH specific options:

  • labels_filename => FILENAME

    In MH-folders, messages can be labeled, for instance based on the sender or whether it is read or not. This status is kept in a file which is usually called .mh_sequences, but that name can be overruled with this flag.

readMessages

Read all messages from the folder. This method is called at instantiation of the folder, so do not call it yourself unless you have a very good reason.

write

Write all messages to the folder-file. Returns whether this was successful. If you want to write to a different file, you first create a new folder, then move the messages, and then write that file.

appendMessages LIST-OF-OPTIONS

(Class method) Append one or more messages to this folder. See the manual-page of Mail::Box for explantion of the options. The folder will not be opened. Returns the list of written messages on success.

Example: my $message = Mail::Internet->new(...); Mail::Box::Mbox->appendMessages ( folder => '=xyz' , message => $message , folderdir => $ENV{FOLDERS} );

dirname

Returns the dirname related to this folder.

Example: print $folder->dirname;

folderToDirname FOLDERNAME, FOLDERDIR

(class method) Translate a foldername into a filename, with use of the FOLDERDIR to replace a leading =.

highestMessageNumber

Returns the highest number which is used in the folder to store a file. This method may be called when the folder is read (then this number can be derived without file-system access), but also when the folder is not read (yet).

Manage message labels

MH-folder use one dedicated file per folder-directory to list special tags to messages in the folder. Typically, this file is called .mh_sequences. The messages are numbered from 1.

Example content of .mh_sequences: cur: 93 unseen: 32 35-56 67-80

To generalize labels on messages, two are treated specially:

  • cur

    The cur specifies the number of the message where the user stopped reading mail from this folder at last access. Internally in these modules refered to as label current.

  • unseen

    With unseen is listed which message was never read. This must be a mistake in the design of MH: it must be a source of confusion. People should never use labels with a negation in the name:

        if($seen)           if(!$unseen)    #yuk!
        if(!$seen)          if($unseen)
        unless($seen)       unless($unseen) #yuk!

    So: label unseen is translated into seen for internal use.

    labelsFilename [FILENAME]

    Returns the filename of the dedicated file which contains the label related to the messages in this folder-directory.

  • readLabels

    In MH-folders, messages can be labeled to easily select sets which are, for instance, posted by who. The file is usually called .mh_sequences but that name can be overruled using the labels_filename option of new().

  • writeLabels HASH

    Write the file which contains the relation between messages (actually the messages' sequence-numbers) and the labels those messages have. The parameter is a reference to an hash which contains for each label a reference to a list of message-numbers which have to be written.

folder management methods

Read the Mail::Box manual for more details and more options on each method.

foundIn FOLDERNAME [,OPTIONS]

Autodetect if there is a Mail::Box::MH folder specified here. The FOLDERNAME specifies the name of the folder, as is specified by the application. The OPTIONS is a list of extra parameters to the request.

For this class, we use (if defined):

  • folderdir => DIRECTORY

Example: Mail::Box::MH->foundIn ( '=markov' , folderdir => "$ENV{HOME}/.mh" );

listFolders [OPTIONS]

List the folders in a certain directory.

  • folderdir => DIRECTORY

  • check => BOOL

  • skip_empty => BOOL

subFolders [OPTIONS]

Returns the subfolders to a folder. Although file-type folders do not have a natural form of sub-folders, we can simulate them. The subfolder_extention option of the constructor (new()) defines how sub-folders can be recognized.

  • check => BOOL

  • skip_empty => BOOL

openSubFolder NAME [,OPTIONS]

Open (or create, if it does not exist yet) a new subfolder to an existing folder.

Example: my $folder = Mail::Box::MH->new(folder => '=Inbox'); my $sub = $folder->openSubFolder('read');

Mail::Box::MH::Message::Runtime

This object contains methods which are part of as well delay-loaded (not-parsed) as loaded messages, but not general for all folders.

PUBLIC INTERFACE

new ARGS

Messages in directory-based folders use the following extra options for creation:

Write one message to a file-handle. Unmodified messages are taken from the folder-file where they were stored in. Modified messages are written as in memory. Specify a file-handle to write TO (defaults to STDOUT).

printIndex [FILEHANDLE]

Print the information of this message which is required to maintain an index-file. By default, this prints to STDOUT.

readIndex CLASS [,FILEHANDLE]

Read the headers of one message from the index into a CLASS structure. CLASS is (a sub-class of) a MIME::Head. If no FILEHANDLE is specified, the data is read from STDIN.

filename

Returns the name of the file in which this message is actually stored. This will return undef when the message is not read from a file.

messageNr

Returns the number of the message as is used in its filename. MH-folders do put each message is a seperate file. The files are numbers, but there may some numbers missing.

Mail::Box::MH::Message

This object extends a Mail::Box::Message with extra tools and facts on what is special to messages in file-based folders, with respect to messages in other types of folders.

PUBLIC INTERFACE

Mail::Box::MH::Message::NotParsed

Not parsed messages stay in the file until the message is used. Because this folder structure uses many messages in the same file, the byte-locations are remembered.

PUBLIC INTERFACE

load

This method is called by the autoloader then the data of the message is required. If you specified REAL for the take_headers option for new(), you did have a MIME::Head in your hands, however this will be destroyed when the whole message is loaded.

AUTHOR

Mark Overmeer (Mark@Overmeer.net). All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

VERSION

This code is alpha, version 0.3

3 POD Errors

The following errors were encountered while parsing the POD:

Around line 601:

Expected '=item *'

Around line 644:

Expected '=item *'

Around line 1019:

'=item' outside of any '=over'