Esempio n. 1
0
 def _write(self, msg):
     # Just like the original _write in the Generator class except
     # that we do not write the headers if self._headers is false.
     #
     if self._headers:
         Generator._write(self, msg)
     else:
         self._dispatch(msg)
Esempio n. 2
0
 def _write_headers(self, msg):
     sfp = StringIO()
     oldfp = self._fp
     self._fp = Tee(oldfp, sfp)
     try:
         Generator._write_headers(self, msg)
     finally:
         self._fp = oldfp
     self._headertxt = sfp.getvalue()
Esempio n. 3
0
 def _dispatch(self, msg):
     # Get the Content-Type: for the message, then try to dispatch to
     # self._handle_<maintype>_<subtype>().  If there's no handler for the
     # full MIME type, then dispatch to self._handle_<maintype>().  If
     # that's missing too, then dispatch to self._writeBody().
     main = msg.get_content_maintype()
     if msg.is_multipart() and main.lower() != 'multipart':
       self._handle_multipart(msg)
     else:
       Generator._dispatch(self,msg)
Esempio n. 4
0
 def __handlepost(self, record, value, comment, preserve, forward, addr):
     # For backwards compatibility with pre 2.0beta3
     ptime, sender, subject, reason, filename, msgdata = record
     path = os.path.join(mm_cfg.DATA_DIR, filename)
     # Handle message preservation
     if preserve:
         parts = os.path.split(path)[1].split(DASH)
         parts[0] = 'spam'
         spamfile = DASH.join(parts)
         # Preserve the message as plain text, not as a pickle
         try:
             fp = open(path)
         except IOError, e:
             if e.errno <> errno.ENOENT: raise
             return LOST
         try:
             msg = cPickle.load(fp)
         finally:
             fp.close()
         # Save the plain text to a .msg file, not a .pck file
         outpath = os.path.join(mm_cfg.SPAM_DIR, spamfile)
         head, ext = os.path.splitext(outpath)
         outpath = head + '.msg'
         outfp = open(outpath, 'w')
         try:
             g = Generator(outfp)
             g.flatten(msg, 1)
         finally:
             outfp.close()
Esempio n. 5
0
    def post(self, message):
        """Post command. message can be
        -a string
        -a list of string
        -a Message from email package
        """

        import StringIO
        from email.Message import Message

        if type(message) == type(""):
            # tested
            msg = StringIO.StringIO(message)

        elif (type(message) == type([])) or (type(message) == type(())):
            # not yet tested
            msg = StringIO.StringIO(LF.join(message) + CRLF)

        elif isinstance(message, Message):
            # not yet tested
            from email.Generator import Generator
            msg = StringIO.StringIO()
            g = Generator(msg, mangle_from_=False)
            g.flatten(message)
            msg.seek(0)

        # NYI: test format of message instance

        try:
            r = self.__nntp.post(msg)
        except NNTPError, e:
            raise NNTPGeneralError, e.response
Esempio n. 6
0
    def flatten(self, delivered_to, received, mangle_from=False,
                include_from=False):
        '''Return a string with native EOL convention.

        The email module apparently doesn't always use native EOL, so we force
        it by writing out what we need, letting the generator write out the
        message, splitting it into lines, and joining them with the platform
        EOL.
        
        Note on mangle_from: the Python Generator class apparently only
        quotes "From ", not ">From " (i.e. it uses mboxo format instead of
        mboxrd).  So we don't use its mangling, and do it by hand instead.
        '''
        if include_from:
            # Mbox-style From line, not rfc822 From: header field.
            fromline = 'From %s %s' % (mbox_from_escape(self.sender),
                                       time.asctime()) + os.linesep
        else:
            fromline = ''
        # Write the Return-Path: header
        rpline = format_header('Return-Path', '<%s>' % self.sender)
        # Remove previous Return-Path: header fields.
        del self.__msg['Return-Path']
        if delivered_to:
            dtline = format_header('Delivered-To', self.recipient or 'unknown')
        else:
            dtline = ''
        if received:
            content = 'from %s by %s with %s' % (
                self.received_from, self.received_by, self.received_with
            )
            if self.recipient is not None:
                content += ' for <%s>' % self.recipient
            content += '; ' + time.strftime('%d %b %Y %H:%M:%S -0000',
                                            time.gmtime())
            receivedline = format_header('Received', content)
        else:
            receivedline = ''
        # From_ handled above, always tell the generator not to include it
        try:
            tmpf = StringIO()
            gen = Generator(tmpf, False, 0)
            gen.flatten(self.__msg, False)
            strmsg = tmpf.getvalue()
            if mangle_from:
                # do mboxrd-style "From " line quoting
                strmsg = RE_FROMLINE.sub(r'>\1', strmsg)
            return (fromline + rpline + dtline + receivedline 
                    + os.linesep.join(strmsg.splitlines() + ['']))
        except TypeError as o:
            # email module chokes on some badly-misformatted messages, even
            # late during flatten().  Hope this is fixed in Python 2.4.
            if self.__raw is None:
                # Argh -- a filter took a correctly-formatted message
                # and returned a badly-misformatted one?
                raise getmailDeliveryError('failed to parse retrieved message '
                                           'and could not recover (%s)' % o)
            self.__msg = corrupt_message(o, fromstring=self.__raw)
            return self.flatten(delivered_to, received, mangle_from,
                                include_from)
Esempio n. 7
0
 def as_string(self, unixfrom = False, **k):
     from email.Generator import Generator
     fp = io.BytesIO()
     if 'maxheaderlen' not in k:
         k['maxheaderlen'] = 0
     g = Generator(fp, **k)
     g.flatten(self, unixfrom=unixfrom)
     return fp.getvalue()
Esempio n. 8
0
def as_bytes(self, unixfrom = False):
    """Return the entire formatted message as bytes.
        Optional `unixfrom' when True, means include the Unix From_ envelope
        header.
    """
    from email.Generator import Generator
    fp = BytesIO()
    g = Generator(fp)
    g.flatten(self, unixfrom = unixfrom)
    return fp.getvalue()
Esempio n. 9
0
    def __init__(self, outfp, headers = [], skip = True):
        """
        A generator that prints out only headers. If 'skip' is true,
        then headers in the list 'headers' are NOT included in the
        output.

        If skip is False then only headers in the list 'headers' are
        included in the output.

        The default of headers = [] and skip = True will cause all
        headers to be printed.

        NOTE: Headers are compared in a case insensitive fashion so
        'bCc' and 'bCC' and 'bcc' are all the same.
        """
        self.log = logging.getLogger("%s.%s" % (__name__, self.__class__.__name__))
        Generator.__init__(self, outfp)
        self._headers = [x.lower() for x in headers]
        self._skip = skip
Esempio n. 10
0
    def test_dont_mangle_from(self):
        s = StringIO()
        g = Generator(s, mangle_from_=0)
        g(self.msg)
        self.assertEqual(
            s.getvalue(), """\
From: [email protected]

From the desk of A.A.A.:
Blah blah blah
""")
Esempio n. 11
0
 def test_header_splitter(self):
     msg = MIMEText('')
     # It'd be great if we could use add_header() here, but that doesn't
     # guarantee an order of the parameters.
     msg['X-Foobar-Spoink-Defrobnit'] = (
         'wasnipoop; giraffes="very-long-necked-animals"; '
         'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"')
     sfp = StringIO()
     g = Generator(sfp)
     g(msg)
     self.assertEqual(sfp.getvalue(), openfile('msg_18.txt').read())
Esempio n. 12
0
 def wrap(self, msg):
     """Can take either a string or an email.Message.Message.
     """
     if isinstance(msg, basestring):
         msg = msg
     elif isinstance(msg, Message):
         fp = StringIO()
         g = Generator(fp, mangle_from_=False, maxheaderlen=0)
         g.flatten(msg)
         msg = fp.getvalue()
     return base64.b64encode(bz2.compress(msg))
Esempio n. 13
0
 def _getStream(self):
     # We write to a TemporayFile instead of a StringIO because we don't
     # want to keep the full file contents around in memory, and because
     # this approach allows us to hand off the stream iterator to the
     # publisher, which will serve it efficiently even after the
     # transaction is closed
     out = tempfile.TemporaryFile(mode='w+b')
     generator = Generator(out, mangle_from_=False)
     generator.flatten(self._getMessage())
     self._size = out.tell()
     out.seek(0)
     return out
Esempio n. 14
0
    def as_string(self, unixfrom=0):
        """Return the entire formatted message as a string.
        Optional `unixfrom' when true, means include the Unix From_ envelope
        header.

        Overridden from email.Message in order to turn off
        mangle_from_.
        """
        from email.Generator import Generator
        fp = StringIO()
        g = Generator(fp, mangle_from_=False)
        g.flatten(self, unixfrom=unixfrom)
        return fp.getvalue()
Esempio n. 15
0
 def test_message_from_string(self):
     fp = openfile('msg_01.txt')
     try:
         text = fp.read()
     finally:
         fp.close()
     msg = email.message_from_string(text)
     s = StringIO()
     # Don't wrap/continue long headers since we're trying to test
     # idempotency.
     g = Generator(s, maxheaderlen=0)
     g(msg)
     self.assertEqual(text, s.getvalue())
Esempio n. 16
0
def get_mail_contents(msg):
    """split an email in a list of attachments"""

    attachments = []

    # retrieve messages of the email
    bodies = search_message_bodies(msg)
    # reverse bodies dict
    parts = dict((m, k) for k, m in bodies.iteritems())

    # organize the stack to handle deep first search
    stack = [msg, ]
    while stack:
        part = stack.pop(0)
        type = part.get_content_type()
        if type.startswith('message/'):
            # ('message/delivery-status', 'message/rfc822', 'message/disposition-notification'):
            # I don't want to explore the tree deeper here and just save source using msg.as_string()
            # but I don't use msg.as_string() because I want to use mangle_from_=False
            from email.Generator import Generator

            fp = StringIO.StringIO()
            g = Generator(fp, mangle_from_=False)
            g.flatten(part, unixfrom=False)
            payload = fp.getvalue()
            filename = 'mail.eml'
            attachments.append(Attachment(part,
                                          filename=filename, type=type,
                                          payload=payload,
                                          charset=part.get_param('charset'),
                                          description=part.get('Content-Description')))
        elif part.is_multipart():
            # insert new parts at the beginning of the stack (deep first search)
            stack[:0] = part.get_payload()
        else:
            payload = part.get_payload(decode=True)
            charset = part.get_param('charset')
            filename = get_filename(part)

            disposition = None
            if part.get_param('inline', None, 'content-disposition') == '':
                disposition = 'inline'
            elif part.get_param('attachment', None, 'content-disposition') == '':
                disposition = 'attachment'

            attachments.append(Attachment(part, filename=filename,
                                          type=type, payload=payload,
                                          charset=charset, content_id=part.get('Content-Id'),
                                          description=part.get('Content-Description'),
                                          disposition=disposition, is_body=parts.get(part)))
    return attachments
Esempio n. 17
0
    def flatten(self,
                delivered_to,
                received,
                mangle_from=False,
                include_from=False):
        '''Return a string with native EOL convention.

        The email module apparently doesn't always use native EOL, so we force
        it by writing out what we need, letting the generator write out the
        message, splitting it into lines, and joining them with the platform
        EOL.
        '''
        f = cStringIO.StringIO()
        if include_from:
            # This needs to be written out first, so we can't rely on the
            # generator
            f.write('From %s %s' %
                    (mbox_from_escape(self.sender), time.asctime()) +
                    os.linesep)
        # Write the Return-Path: header
        f.write(format_header('Return-Path', '<%s>' % self.sender))
        # Remove previous Return-Path: header fields.
        del self.__msg['Return-Path']
        if delivered_to:
            f.write(format_header('Delivered-To', self.recipient or 'unknown'))
        if received:
            content = 'from %s by %s with %s' % (
                self.received_from, self.received_by, self.received_with)
            if self.recipient is not None:
                content += ' for <%s>' % self.recipient
            content += '; ' + time.strftime('%d %b %Y %H:%M:%S -0000',
                                            time.gmtime())
            f.write(format_header('Received', content))
        gen = Generator(f, mangle_from, 0)
        # From_ handled above, always tell the generator not to include it
        try:
            gen.flatten(self.__msg, False)
            f.seek(0)
            return os.linesep.join(f.read().splitlines() + [''])
        except TypeError, o:
            # email module chokes on some badly-misformatted messages, even
            # late during flatten().  Hope this is fixed in Python 2.4.
            if self.__raw == None:
                # Argh -- a filter took a correctly-formatted message
                # and returned a badly-misformatted one?
                raise getmailDeliveryError('failed to parse retrieved message '
                                           'and could not recover (%s)' % o)
            self.__msg = corrupt_message(o, fromstring=self.__raw)
            return self.flatten(delivered_to, received, mangle_from,
                                include_from)
Esempio n. 18
0
    def __init__(self, outfp, headers=False):
        """
        This is a special purpose message generator.

        We need a generator that can be used to represent the 'TEXT'
        fetch attribute. When used on a multipart message it does not
        render the headers of the message, but renders the headers of
        every sub-part.

        When used on a message that is not a multipart it just renders
        the body.

        We do this by having the 'clone()' method basically reverse
        whether or not we should print the headers, and the _write()
        method looks at that instance variable to decide if it should
        print the headers or not.

        outfp is the output file-like object for writing the message to.  It
        must have a write() method.

        """
        Generator.__init__(self, outfp)
        self._headers = headers
Esempio n. 19
0
    def as_string(self, unixfrom=False):
        """Return the entire formatted message as a string.
        Optional `unixfrom' when True, means include the Unix From_ envelope
        header.

        This is a convenience method and may not generate the message exactly
        as you intend.  For more flexibility, use the flatten() method of a
        Generator instance.
        """
        from email.Generator import Generator
        fp = StringIO()
        g = Generator(fp)
        g.flatten(self, unixfrom=unixfrom)
        return fp.getvalue()
Esempio n. 20
0
 def HoldMessage(self, msg, reason, msgdata={}):
     # Make a copy of msgdata so that subsequent changes won't corrupt the
     # request database.  TBD: remove the `filebase' key since this will
     # not be relevant when the message is resurrected.
     msgdata = msgdata.copy()
     # assure that the database is open for writing
     self.__opendb()
     # get the next unique id
     id = self.__nextid()
     # get the message sender
     sender = msg.get_sender()
     # calculate the file name for the message text and write it to disk
     if mm_cfg.HOLD_MESSAGES_AS_PICKLES:
         ext = 'pck'
     else:
         ext = 'txt'
     filename = 'heldmsg-%s-%d.%s' % (self.internal_name(), id, ext)
     omask = os.umask(007)
     try:
         fp = open(os.path.join(mm_cfg.DATA_DIR, filename), 'w')
         try:
             if mm_cfg.HOLD_MESSAGES_AS_PICKLES:
                 cPickle.dump(msg, fp, 1)
             else:
                 g = Generator(fp)
                 g.flatten(msg, 1)
             fp.flush()
             os.fsync(fp.fileno())
         finally:
             fp.close()
     finally:
         os.umask(omask)
     # save the information to the request database.  for held message
     # entries, each record in the database will be of the following
     # format:
     #
     # the time the message was received
     # the sender of the message
     # the message's subject
     # a string description of the problem
     # name of the file in $PREFIX/data containing the msg text
     # an additional dictionary of message metadata
     #
     msgsubject = msg.get('subject', _('(no subject)'))
     if not sender:
         sender = _('<missing>')
     data = time.time(), sender, msgsubject, reason, filename, msgdata
     self.__db[id] = (HELDMSG, data)
     return id
Esempio n. 21
0
    def test_no_split_long_header(self):
        msg = Message()
        msg['From'] = '*****@*****.**'
        refparts = []
        msg['References'] = 'x' * 80
        msg.set_payload('Test')
        sfp = StringIO()
        g = Generator(sfp)
        g(msg)
        self.assertEqual(
            sfp.getvalue(), """\
From: [email protected]
References: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Test""")
Esempio n. 22
0
    def as_string(self, unixfrom=False):
        """Return the entire formatted message as a string.
        Optional `unixfrom' when True, means include the Unix From_ envelope
        header.

        This is a convenience method and may not generate the message exactly
        as you intend because by default it mangles lines that begin with
        "From ".  For more flexibility, use the flatten() method of a
        Generator instance.
        """
        from email.Generator import Generator
        from cStringIO import StringIO
        fp = StringIO()
        g = Generator(fp, maxheaderlen=0)
        g.flatten(self, unixfrom=unixfrom)
        return fp.getvalue()
Esempio n. 23
0
    def test_no_semis_header_splitter(self):
        msg = Message()
        msg['From'] = '*****@*****.**'
        refparts = []
        for i in range(10):
            refparts.append('<*****@*****.**>' % i)
        msg['References'] = SPACE.join(refparts)
        msg.set_payload('Test')
        sfp = StringIO()
        g = Generator(sfp)
        g(msg)
        self.assertEqual(
            sfp.getvalue(), """\
From: [email protected]
References: <*****@*****.**> <*****@*****.**> <*****@*****.**> <*****@*****.**> <*****@*****.**>
\t<*****@*****.**> <*****@*****.**> <*****@*****.**> <*****@*****.**> <*****@*****.**>

Test""")
Esempio n. 24
0
    def notifyModerators(self, moderators, article):
        """
        Send an article to a list of group moderators to be moderated.

        @param moderators: A C{list} of C{str} giving RFC 2821 addresses of
            group moderators to notify.

        @param article: The article requiring moderation.
        @type article: L{Article}

        @return: A L{Deferred} which fires with the result of sending the email.
        """
        # Moderated postings go through as long as they have an Approved
        # header, regardless of what the value is
        group = article.getHeader('Newsgroups')
        subject = article.getHeader('Subject')

        if self._sender is None:
            # This case should really go away.  This isn't a good default.
            sender = 'twisted-news@' + socket.gethostname()
        else:
            sender = self._sender

        msg = Message()
        msg['Message-ID'] = smtp.messageid()
        msg['From'] = sender
        msg['To'] = ', '.join(moderators)
        msg['Subject'] = 'Moderate new %s message: %s' % (group, subject)
        msg['Content-Type'] = 'message/rfc822'

        payload = Message()
        for header, value in article.headers.values():
            payload.add_header(header, value)
        payload.set_payload(article.body)

        msg.attach(payload)

        out = StringIO.StringIO()
        gen = Generator(out, False)
        gen.flatten(msg)
        msg = out.getvalue()

        return self.sendmail(self._mailhost, sender, moderators, msg)
Esempio n. 25
0
    def test_generate(self):
        # First craft the message to be encapsulated
        m = Message()
        m['Subject'] = 'An enclosed message'
        m.add_payload('Here is the body of the message.\n')
        r = MIMEMessage(m)
        r['Subject'] = 'The enclosing message'
        s = StringIO()
        g = Generator(s)
        g(r)
        self.assertEqual(
            s.getvalue(), """\
Content-Type: message/rfc822
MIME-Version: 1.0
Subject: The enclosing message

Subject: An enclosed message

Here is the body of the message.
""")
Esempio n. 26
0
    def fetch(self, ctx):
        """
        This method applies fetch criteria that this object represents
        to the message and message entry being passed in.

        It returns the part of the message wanted as a string ready to
        be sent right back to the client that asked for it.

        NOTE: In case you are wondering a FETCH of a message can cause
        it to gain a '\Seen' flag.
        """
        self.ctx = ctx

        # Based on the operation figure out what subroutine does the rest
        # of the work.
        #
        if self.attribute == "body":
            result = self.body(self.ctx.msg, self.section)
        elif self.attribute == "bodystructure":
            result = self.bodystructure(self.ctx.msg)
        elif self.attribute == "envelope":
            result = self.envelope(self.ctx.msg)
        elif self.attribute == "flags":
            result = '(%s)' % ' '.join(
                [asimap.constants.seq_to_flag(x) for x in self.ctx.sequences])
        elif self.attribute == "internaldate":
            result = '"%s"' % \
                self.ctx.internal_date.strftime("%d-%b-%Y %H:%m:%S %z")
        elif self.attribute == "rfc822.size":
            # result = str(len(self.ctx.mailbox.mailbox.get_string(
            #     self.ctx.msg_key)))
            fp = StringIO()
            g = Generator(fp, mangle_from_=False)
            g.flatten(self.ctx.msg)
            result = str(len(email.utils.fix_eols(fp.getvalue())))
        elif self.attribute == "uid":
            result = str(self.ctx.uid)
        else:
            raise NotImplemented

        return "%s %s" % (str(self), result)
Esempio n. 27
0
 def test_epilogue(self):
     fp = openfile('msg_21.txt')
     try:
         text = fp.read()
     finally:
         fp.close()
     msg = Message()
     msg['From'] = '*****@*****.**'
     msg['To'] = '*****@*****.**'
     msg['Subject'] = 'Test'
     msg.preamble = 'MIME message\n'
     msg.epilogue = 'End of MIME message\n'
     msg1 = MIMEText('One')
     msg2 = MIMEText('Two')
     msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY')
     msg.add_payload(msg1)
     msg.add_payload(msg2)
     sfp = StringIO()
     g = Generator(sfp)
     g(msg)
     self.assertEqual(sfp.getvalue(), text)
Esempio n. 28
0
    def STOR(self, msg):
        """Given a message, STORe it.

        Takes a string or an email.Message.Message object. Returns a message ID.

        """

        # Flatten a possible Message object.
        # ==================================

        if isinstance(msg, basestring):
            msg = msg
        elif isinstance(msg, Message):
            fp = StringIO()
            g = Generator(fp, mangle_from_=False, maxheaderlen=0)
            g.flatten(msg)
            msg = fp.getvalue()

        # Store it and verify the hash.
        # =============================

        c, remote_msg_id = self.hit('STOR %s' % self.wrapper.wrap(msg))

        msg = self.padder.pad(msg)
        msg = self.crypter.encrypt(msg)
        msg_id = sha.new(msg).hexdigest()

        if remote_msg_id == msg_id:
            return remote_msg_id
        else:
            raise SMAPError('Message storage failed! (client)')

        # Decide how to respond.
        # ======================

        if c == 1:
            raise AlreadyStored
        assert c == 0
Esempio n. 29
0
def renderMessage(message, mangleFromHeader=False):
    out = StringIO()
    generator = Generator(out, mangle_from_=mangleFromHeader)
    generator.flatten(message)
    return out.getvalue()
Esempio n. 30
0
 def __init__(self, outfp, mangle_from_=True, maxheaderlen=78):
     Generator.__init__(self, outfp, mangle_from_, maxheaderlen)
     self._headertxt = ''
Esempio n. 31
0
 def _write_headers(self, msg):
     if self.write_headers:
         Generator._write_headers(self, msg)
Esempio n. 32
0
 def __init__(self, outfp, mangle_from_=True, maxheaderlen=78, write_headers=True):
     self.write_headers = write_headers
     Generator.__init__(self, outfp, mangle_from_, maxheaderlen)
Esempio n. 33
0
    def body(self, msg, section):
        """
        Fetch the appropriate part of the message and return it to the
        user.
        """

        msg_text = None
        g = None
        if len(section) == 0:
            # They want the entire message.
            #
            # This really only ever is the case as our first invocation of the
            # body() method. All further recursive calls will always have at
            # least one element in the section list when they are called.
            #
            fp = StringIO()
            g = Generator(fp, mangle_from_=False)
            g.flatten(msg)
            msg_text = email.utils.fix_eols(fp.getvalue())
        else:
            if len(section) == 1:
                fp = StringIO()
                if isinstance(section[0], int):
                    # The want a sub-part. Get that sub-part. Watch
                    # out for messages that are not multipart. You can
                    # get a sub-part of these as long as it is only
                    # sub-part #1.
                    #
                    g = TextGenerator(fp, headers=False)

                    if section[0] == 1 and not msg.is_multipart():
                        # The logic is simpler to read this way.. if
                        # they want section 1 and this message is NOT
                        # a multipart message, then do the same as
                        # 'TEXT' ie: We will fall through to the end of this
                        # function where we will take the generator
                        # already created above and use it.
                        #
                        pass
                    else:
                        # Otherwise, get the sub-part they are after
                        # as the message to pass to the generator.
                        #
                        if section[0] != 1 and not msg.is_multipart():
                            raise BadSection("Trying to retrieve section %d "
                                             "and this message is not "
                                             "multipart" % section[0])
                        try:
                            msg = msg.get_payload(section[0]-1)
                        except IndexError:
                            raise BadSection("Section %d does not exist in "
                                             "this message sub-part" %
                                             section[0])
                elif (isinstance(section[0], str) and
                      section[0].upper() == 'TEXT'):
                    g = TextGenerator(fp, headers=False)
                elif isinstance(section[0], (list, tuple)):
                    if section[0][0].upper() == "HEADER.FIELDS":
                        g = HeaderGenerator(fp, headers=section[0][1],
                                            skip=False)
                    elif section[0][0].upper() == "HEADER.FIELDS.NOT":
                        g = HeaderGenerator(fp, headers=section[0][1],
                                            skip=True)
                    else:
                        raise BadSection("Section value must be either "
                                         "HEADER.FIELDS or HEADER.FIELDS.NOT, "
                                         "not: %s" % section[0][0])
                else:
                    g = HeaderGenerator(fp)
                    if (isinstance(section[0], str) and
                            section[0].upper() == 'MIME'):
                        # XXX just use the generator as it is for MIME.. I know
                        # this is not quite right in that it will accept more
                        # then it should, but it will otherwise work.
                        #
                        pass
                    elif (isinstance(section[0], str) and
                          section[0].upper() == 'HEADER'):
                        # if the content type is message/rfc822 then to
                        # get the headers we need to use the first
                        # sub-part of this message.
                        #
                        if msg.is_multipart() and \
                           msg.get_content_type() == 'message/rfc822':
                            msg = msg.get_payload(0)
                    else:
                        self.log.warn("body: Unexpected section[0] value: %s" %
                                      repr(section))
                        raise BadSection("%s: Unexpected section value: %s" %
                                         (str(self), repr(section[0])))
            elif isinstance(section[0], int):
                # We have an integer sub-section. This means that we
                # need to pull apart the message (it MUST be a
                # multi-part message) and pass to a recursive
                # invocation of this function the sub-part and the
                # section list (with the top element of the section
                # list removed.)
                #
                if not msg.is_multipart():
                    raise BadSection("Message does not contain subsection %d "
                                     "(section list: %s" % section[0],
                                     section)
                try:
                    msg = msg.get_payload(section[0]-1)
                except TypeError:
                    raise BadSection("Message does not contain subsection %d "
                                     "(section list: %s)" % section[0],
                                     section)
                return self.body(msg, section[1:])

            # We should have a generator that will give us the text
            # that we want. If we do not then we were not able to find
            # an appropriate section to parse.
            #
            if g is None:
                raise BadSection("Section selector '%s' can not be parsed" %
                                 section)
            g.flatten(msg)
            msg_text = fp.getvalue()

        # We have our message text we need to return to our caller.
        # truncate if it we also have a 'partial' defined.
        #
        # Convert \n in to \r\n
        #
        msg_text = email.utils.fix_eols(msg_text)
        if self.partial:
            msg_text = msg_text[self.partial[0]:self.partial[1]]

        # We return all of these body sections as a length prefixed
        # IMAP string. Also run the message text through the wringer
        # converter it through unicode via utf8 back in to bytes
        # (since we are sending messages over the network we want
        # stuff a bytes as much as possible.)
        #
        msg_text = to_bytes(msg_text.decode('utf8', 'replace'))
        return "{%d}\r\n%s" % (len(msg_text), msg_text)
Esempio n. 34
0
 def _write_headers(self, msg):
     if not self.__skipheaders:
         Generator._write_headers(self, msg)
Esempio n. 35
0
# Copyright (C) 2001 Python Software Foundation
Esempio n. 36
0
 def __init__(self, outfp, headers=[], skip=True):
     self.log = logging.getLogger("%s.%s" % (__name__,
                                             self.__class__.__name__))
     Generator.__init__(self, outfp)
     self._headers = [x.lower() for x in headers]
     self._skip = skip
Esempio n. 37
0
 def __init__(self, outfp, mangle_from_=True,
              maxheaderlen=78, skipheaders=True):
     Generator.__init__(self, outfp, mangle_from_=False)
     self.__skipheaders = skipheaders