def as_string(self, unixfrom=False):
     Generator = Generator
     import email.Generator
     fp = StringIO()
     g = Generator(fp)
     g.flatten(self, unixfrom=unixfrom)
     return fp.getvalue()
Beispiel #2
0
    def createRedirectedMessage(self, fromAddress, toAddresses, message):
        """
        Create a L{Message} item based on C{message}, with the C{Resent-From}
        and C{Resent-To} headers set

        @type fromAddress: L{smtpout.FromAddress}

        @type toAddresses: sequence of L{mimeutil.EmailAddress}

        @type message: L{Message}

        @rtype: L{Message}
        """
        m = P.Parser().parse(message.impl.source.open())
        def insertResentHeaders(i):
            m._headers.insert(i, ('resent-from', MH.Header(
                fromAddress.address).encode()))
            m._headers.insert(i, ('resent-to', MH.Header(
                mimeutil.flattenEmailAddresses(toAddresses)).encode()))
            m._headers.insert(i, ('resent-date', EU.formatdate()))
            m._headers.insert(i, ('resent-message-id',
                                  smtp.messageid('divmod.xquotient')))
        for (i, (name, _)) in enumerate(m._headers):
            #insert Resent-* headers after all Received headers but
            #before the rest
            if name.lower() != "received":
                insertResentHeaders(i)
                break
        else:
            insertResentHeaders(0)
        s = S.StringIO()
        G.Generator(s).flatten(m)
        s.seek(0)

        return self.createMessageAndQueueIt(fromAddress.address, s, True)
Beispiel #3
0
 def make(self):
     """
     Serialize this part using the stdlib L{email} package.
     @return: string
     """
     s = StringIO()
     G.Generator(s).flatten(self._make())
     s.seek(0)
     return s.read()
Beispiel #4
0
def msg_repr(msg):
    from email import Generator
    try:
        import cStringIO as StringIO
    except ImportError:
        import StringIO as StringIO
    fp = StringIO.StringIO()
    Generator.Generator(fp, mangle_from_=False).flatten(msg)
    return fp.getvalue()
Beispiel #5
0
    def _sendBounceMessage(self, m):
        """
        Insert the given MIME message into the inbox for this user.

        @param m: L{MMP.MIMEMultipart}
        """
        s = S.StringIO()
        G.Generator(s).flatten(m)
        s.seek(0)
        self.createMessageAndQueueIt(
            FromAddress.findDefault(self.store).address, s, False)
Beispiel #6
0
    def as_string(self, unixfrom=False, mangle_from_=True):
        """Return entire formatted message as a string using
        Mailman.Message.Generator.

        Operates like email.Message.Message.as_string, only
	using Mailman's Message.Generator class. Only the top headers will
        get folded.
        """
        fp = StringIO()
        g = Generator(fp, mangle_from_=mangle_from_)
        g.flatten(self, unixfrom=unixfrom)
        return fp.getvalue()
Beispiel #7
0
def createMessage(composer,
                  cabinet,
                  msgRepliedTo,
                  fromAddress,
                  toAddresses,
                  subject,
                  messageBody,
                  cc,
                  bcc,
                  files,
                  createMessageObject=None):
    """
    Create an outgoing message, format the body into MIME parts, and
    populate its headers.

    @param createMessageObject: A one-argument callable which will be
    invoked with a file-like object containing MIME text and which
    should return a Message instance associated with objects
    representing that MIME data.
    """
    MC.add_charset('utf-8', None, MC.QP, 'utf-8')

    encode = lambda s: MH.Header(s).encode()

    s = S.StringIO()
    wrappedMsgBody = FlowedParagraph.fromRFC2646(messageBody).asRFC2646()
    m = MT.MIMEText(wrappedMsgBody, 'plain', 'utf-8')
    m.set_param("format", "flowed")

    fileItems = []
    if files:
        attachmentParts = []
        for storeID in files:
            a = composer.store.getItemByID(long(storeID))
            if isinstance(a, Part):
                a = cabinet.createFileItem(
                    a.getParam('filename',
                               default=u'',
                               header=u'content-disposition'),
                    unicode(a.getContentType()), a.getBody(decode=True))
            fileItems.append(a)
            attachmentParts.append(_fileItemToEmailPart(a))

        m = MMP.MIMEMultipart('mixed', None, [m] + attachmentParts)

    m['From'] = encode(fromAddress.address)
    m['To'] = encode(mimeutil.flattenEmailAddresses(toAddresses))
    m['Subject'] = encode(subject)
    m['Date'] = EU.formatdate()
    m['Message-ID'] = smtp.messageid('divmod.xquotient')

    if cc:
        m['Cc'] = encode(mimeutil.flattenEmailAddresses(cc))
    if msgRepliedTo is not None:
        #our parser does not remove continuation whitespace, so to
        #avoid duplicating it --
        refs = [
            hdr.value for hdr in msgRepliedTo.impl.getHeaders("References")
        ]
        if len(refs) == 0:
            irt = [
                hdr.value
                for hdr in msgRepliedTo.impl.getHeaders("In-Reply-To")
            ]
            if len(irt) == 1:
                refs = irt
            else:
                refs = []
        msgids = msgRepliedTo.impl.getHeaders("Message-ID")
        for hdr in msgids:
            msgid = hdr.value
            refs.append(msgid)
            #As far as I can tell, the email package doesn't handle
            #multiple values for headers automatically, so here's some
            #continuation whitespace.
            m['References'] = u'\n\t'.join(refs)
            m['In-Reply-To'] = msgid
            break
    G.Generator(s).flatten(m)
    s.seek(0)

    if createMessageObject is None:

        def createMessageObject(messageFile):
            return composer.createMessageAndQueueIt(fromAddress.address,
                                                    messageFile, True)

    msg = createMessageObject(s)

    # there is probably a better way than this, but there
    # isn't a way to associate the same file item with multiple
    # messages anyway, so there isn't a need to reflect that here
    for fileItem in fileItems:
        fileItem.message = msg
    return msg