
:mod:`multifile` --- Support for files containing distinct parts
================================================================

.. module:: multifile
   :synopsis: Support for reading files which contain distinct parts, such as some MIME data.
   :deprecated:
.. sectionauthor:: Eric S. Raymond <esr@snark.thyrsus.com>


.. deprecated:: 2.5
   The :mod:`email` package should be used in preference to the :mod:`multifile`
   module. This module is present only to maintain backward compatibility.

The :class:`MultiFile` object enables you to treat sections of a text file as
file-like input objects, with ``''`` being returned by :meth:`readline` when a
given delimiter pattern is encountered.  The defaults of this class are designed
to make it useful for parsing MIME multipart messages, but by subclassing it and
overriding methods  it can be easily adapted for more general use.


.. class:: MultiFile(fp[, seekable])

   Create a multi-file.  You must instantiate this class with an input object
   argument for the :class:`MultiFile` instance to get lines from, such as a file
   object returned by :func:`open`.

   :class:`MultiFile` only ever looks at the input object's :meth:`readline`,
   :meth:`seek` and :meth:`tell` methods, and the latter two are only needed if you
   want random access to the individual MIME parts. To use :class:`MultiFile` on a
   non-seekable stream object, set the optional *seekable* argument to false; this
   will prevent using the input object's :meth:`seek` and :meth:`tell` methods.

It will be useful to know that in :class:`MultiFile`'s view of the world, text
is composed of three kinds of lines: data, section-dividers, and end-markers.
MultiFile is designed to support parsing of messages that may have multiple
nested message parts, each with its own pattern for section-divider and
end-marker lines.


.. seealso::

   Module :mod:`email`
      Comprehensive email handling package; supersedes the :mod:`multifile` module.


.. _multifile-objects:

MultiFile Objects
-----------------

A :class:`MultiFile` instance has the following methods:


.. method:: MultiFile.readline(str)

   Read a line.  If the line is data (not a section-divider or end-marker or real
   EOF) return it.  If the line matches the most-recently-stacked boundary, return
   ``''`` and set ``self.last`` to 1 or 0 according as the match is or is not an
   end-marker.  If the line matches any other stacked boundary, raise an error.  On
   encountering end-of-file on the underlying stream object, the method raises
   :exc:`Error` unless all boundaries have been popped.


.. method:: MultiFile.readlines(str)

   Return all lines remaining in this part as a list of strings.


.. method:: MultiFile.read()

   Read all lines, up to the next section.  Return them as a single (multiline)
   string.  Note that this doesn't take a size argument!


.. method:: MultiFile.seek(pos[, whence])

   Seek.  Seek indices are relative to the start of the current section. The *pos*
   and *whence* arguments are interpreted as for a file seek.


.. method:: MultiFile.tell()

   Return the file position relative to the start of the current section.


.. method:: MultiFile.next()

   Skip lines to the next section (that is, read lines until a section-divider or
   end-marker has been consumed).  Return true if there is such a section, false if
   an end-marker is seen.  Re-enable the most-recently-pushed boundary.


.. method:: MultiFile.is_data(str)

   Return true if *str* is data and false if it might be a section boundary.  As
   written, it tests for a prefix other than ``'-``\ ``-'`` at start of line (which
   all MIME boundaries have) but it is declared so it can be overridden in derived
   classes.

   Note that this test is used intended as a fast guard for the real boundary
   tests; if it always returns false it will merely slow processing, not cause it
   to fail.


.. method:: MultiFile.push(str)

   Push a boundary string.  When a decorated version of this boundary  is found as
   an input line, it will be interpreted as a section-divider  or end-marker
   (depending on the decoration, see :rfc:`2045`).  All subsequent reads will
   return the empty string to indicate end-of-file, until a call to :meth:`pop`
   removes the boundary a or :meth:`next` call reenables it.

   It is possible to push more than one boundary.  Encountering the
   most-recently-pushed boundary will return EOF; encountering any other
   boundary will raise an error.


.. method:: MultiFile.pop()

   Pop a section boundary.  This boundary will no longer be interpreted as EOF.


.. method:: MultiFile.section_divider(str)

   Turn a boundary into a section-divider line.  By default, this method
   prepends ``'--'`` (which MIME section boundaries have) but it is declared so
   it can be overridden in derived classes.  This method need not append LF or
   CR-LF, as comparison with the result ignores trailing whitespace.


.. method:: MultiFile.end_marker(str)

   Turn a boundary string into an end-marker line.  By default, this method
   prepends ``'--'`` and appends ``'--'`` (like a MIME-multipart end-of-message
   marker) but it is declared so it can be overridden in derived classes.  This
   method need not append LF or CR-LF, as comparison with the result ignores
   trailing whitespace.

Finally, :class:`MultiFile` instances have two public instance variables:


.. attribute:: MultiFile.level

   Nesting depth of the current part.


.. attribute:: MultiFile.last

   True if the last end-of-file was for an end-of-message marker.


.. _multifile-example:

:class:`MultiFile` Example
--------------------------

.. sectionauthor:: Skip Montanaro <skip@mojam.com>


::

   import mimetools
   import multifile
   import StringIO

   def extract_mime_part_matching(stream, mimetype):
       """Return the first element in a multipart MIME message on stream
       matching mimetype."""

       msg = mimetools.Message(stream)
       msgtype = msg.gettype()
       params = msg.getplist()

       data = StringIO.StringIO()
       if msgtype[:10] == "multipart/":

           file = multifile.MultiFile(stream)
           file.push(msg.getparam("boundary"))
           while file.next():
               submsg = mimetools.Message(file)
               try:
                   data = StringIO.StringIO()
                   mimetools.decode(file, data, submsg.getencoding())
               except ValueError:
                   continue
               if submsg.gettype() == mimetype:
                   break
           file.pop()
       return data.getvalue()

