def extract_body(mail, types=None, field_key='copiousoutput'):
    """Returns a string view of a Message.

    If the `types` argument is set then any encoding types there will be used
    as the prefered encoding to extract. If `types` is None then
    :ref:`prefer_plaintext <prefer-plaintext>` will be consulted; if it is True
    then text/plain parts will be returned, if it is false then text/html will
    be returned if present or text/plain if there are no text/html parts.

    :param mail: the mail to use
    :type mail: :class:`email.Message`
    :param types: mime content types to use for body string
    :type types: list[str]
    :returns: The combined text of any parts to be used
    :rtype: str
    """

    preferred = 'text/plain' if settings.get(
        'prefer_plaintext') else 'text/html'
    has_preferred = False

    # see if the mail has our preferred type
    if types is None:
        has_preferred = list(typed_subpart_iterator(
            mail, *preferred.split('/')))

    body_parts = []
    for part in mail.walk():
        # skip non-leaf nodes in the mail tree
        if part.is_multipart():
            continue

        ctype = part.get_content_type()

        if types is not None:
            if ctype not in types:
                continue
        cd = part.get('Content-Disposition', '')
        if cd.startswith('attachment'):
            continue
        # if the mail has our preferred type, we only keep this type
        # note that if types != None, has_preferred always stays False
        if has_preferred and ctype != preferred:
            continue

        if ctype == 'text/plain':
            body_parts.append(string_sanitize(remove_cte(part, as_string=True)))
        else:
            rendered_payload = render_part(part)
            if rendered_payload:  # handler had output
                body_parts.append(string_sanitize(rendered_payload))
            # mark as attachment
            elif cd:
                part.replace_header('Content-Disposition', 'attachment; ' + cd)
            else:
                part.add_header('Content-Disposition', 'attachment;')
    return u'\n\n'.join(body_parts)
def extract_body ( mail , types = None , field_key = 'copiousoutput' ) : preferred = 'text/plain' if settings . get ( 'prefer_plaintext' ) else 'text/html' has_preferred = False if types is None : has_preferred = list ( typed_subpart_iterator ( mail , * preferred . split ( '/' ) ) ) body_parts = [ ] for part in mail . walk ( ) : if part . is_multipart ( ) : continue ctype = part . get_content_type ( ) if types is not None : if ctype not in types : continue cd = part . get ( 'Content-Disposition' , '' ) if cd . startswith ( 'attachment' ) : continue if has_preferred and ctype != preferred : continue if ctype == 'text/plain' : body_parts . append ( string_sanitize ( remove_cte ( part , as_string = True ) ) ) else : rendered_payload = render_part ( part ) if rendered_payload : body_parts . append ( string_sanitize ( rendered_payload ) ) elif cd : part . replace_header ( 'Content-Disposition' , 'attachment; ' + cd ) else : part . add_header ( 'Content-Disposition' , 'attachment;' ) return u'\n\n' . join ( body_parts )
Returns a string view of a Message.

    If the `types` argument is set then any encoding types there will be used
    as the prefered encoding to extract. If `types` is None then
    :ref:`prefer_plaintext <prefer-plaintext>` will be consulted; if it is True
    then text/plain parts will be returned, if it is false then text/html will
    be returned if present or text/plain if there are no text/html parts.

    :param mail: the mail to use
    :type mail: :class:`email.Message`
    :param types: mime content types to use for body string
    :type types: list[str]
    :returns: The combined text of any parts to be used
    :rtype: str