<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 01/29/2014 01:48 PM, Zack Allen
      wrote:<br>
    </div>
    <blockquote
      cite="mid:FBBDC68B-C52D-487F-BF1B-D63BF1D6D18A@gmail.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=ISO-8859-1">
      <div>I am using the template file located here <a
          moz-do-not-send="true"
          href="http://pythonhosted.org/pymilter/milter-template_8py-example.html">http://pythonhosted.org/pymilter/milter-template_8py-example.html</a> to
        create my own kilter. For now, this milter should be adding a
        custom footer to every email message sent through. The issue I
        am having is that self.replacebody(self.fp.getvalue() + footer)
        destroys HTML messages and messages with attachments. Is there a
        way to specifically edit *only* the body of the message, and
        keep the integrity of HTML, attachments and headers?</div>
      <div><br>
      </div>
    </blockquote>
    You are processing the message at the rfc2821 level.  There is no
    such thing as HTML or attachments - which are added at the rfc2822
    level via standards such as MIME or Microsoft TNEF. <br>
    <br>
    Note that the sample (template) uses the email package to split the
    message into attachments in the 'msg' object.  You can iterate
    through those to identify the "body" (not an official term - perhaps
    the first text/plain attachment?)  Please see the email API for
    replacing a particular attachment.  After making your changes, you
    extract the SMTP form of the email body (with all the attachment
    encoded as MIME) from the msg object with msg.dump(outfp).  The
    milter (not pymilter) project uses pymilter and does quite a bit of
    MIME attachment replacement and scanning.  You might get some ideas
    from its code (e.g. hooking msg.headerchange), although it does
    maybe too many things.<br>
    <br>
    Note that the message collected by the template in self.fp includes
    the email header (with fields like From:, To:, etc).  You can:<br>
    <br>
    a) not collect header data in the header and eoh callbacks.  The
    template does that to enable using the email package.<br>
    <br>
    b) split the header and body with something like <font
      face="monospace">hdr,body = self.fp.getvalue().split('\n\n',1)</font><br>
         You then pass just the body to replacebody().  (Or <font
      face="monospace">hdr,body = msg.dump().split('\n\n',1)</font> if
    using the email package to parse attachments.)<br>
  </body>
</html>