跳转到主要内容

各种电子邮件实用功能

项目描述

Project Status: Active — The project has reached a stable, usable state and is being actively developed. CI Status https://codecov.io/gh/jwodder/mailbits/branch/master/graph/badge.svg https://img.shields.io/pypi/pyversions/mailbits.svg MIT License

GitHub | PyPI | 问题 | 变更日志

mailbits 提供了一组小功能,用于处理 Python 标准库中的 Message/EmailMessageAddressGroup 类型,以及一些其他功能。它可以解析和重新组装 Content-Type 字符串,将旧 Message 类的实例转换为新的 EmailMessage,将 MessageEmailMessage 实例转换为结构化的 dict,解析地址,格式化地址列表,并从 EmailMessage 中提取收件人的原始电子邮件地址。

安装

mailbits 需要 Python 3.6 或更高版本。只需使用 Python 3 的 pip 安装它(你有 pip 吗?)

python3 -m pip install mailbits

API

ContentType

ContentType 类提供了已解析的 Content-Type 头部值的表示。使用 parse() 类方法解析 Content-Type 字符串,通过 content_typemaintypesubtypeparams 属性(最后三个可以修改)检查各个部分,使用 str() 转换回字符串,并使用编码词将非 ASCII 字符转换为 ASCII 字节使用 bytes()

>>> from mailbits import ContentType
>>> ct = ContentType.parse("text/plain; charset=utf-8; name*=utf-8''r%C3%A9sum%C3%A9.txt")
>>> ct
ContentType(maintype='text', subtype='plain', params={'charset': 'utf-8', 'name': 'résumé.txt'})
>>> ct.content_type
'text/plain'
>>> str(ct)
'text/plain; charset="utf-8"; name="résumé.txt"'
>>> bytes(ct)
b'text/plain; charset="utf-8"; name*=utf-8\'\'r%C3%A9sum%C3%A9.txt'

email2dict()

class MessageDict(TypedDict):
    unixfrom: Optional[str]
    headers: Dict[str, Any]
    preamble: Optional[str]
    content: Any
    epilogue: Optional[str]

mailbits.email2dict(msg: email.message.Message, include_all: bool = False) -> MessageDict

Message 对象转换为 dict。所有编码的文本和字节都解码为其自然值。

需要检查一个 Message 但发现内置的 Python API 太繁琐?需要检查 Message 是否具有你预期的内容与结构?需要比较两个 Message 实例的相等性?需要美化打印 Message 的结构?那么 email2dict() 就是你的救星。

默认情况下,任何特定于消息编码方式的信息(内容类型参数、内容传输编码等)都不会报告,因为重点在于实际内容而不是其表示方式的选择。如果要包括这些信息,请将 include_all 设置为 True

输出结构具有以下字段

unixfrom

如果有,mbox 中标记消息开始的 “From “ 行

headers

将小写字段名映射到值的 dict。以下头具有特殊表示

subject

单个字符串

fromtoccbccresent-fromresent-toresent-ccresent-bccreply-to

地址组或地址列表。地址表示为包含两个字段字符串的 dictdisplay_name(如果没有提供则为空字符串)和 address。组表示为包含一个 group 字段(给出组的名称)和一个 addresses 字段(给出组中的地址列表)的 dict

message-id

单个字符串

content-type

包含一个 content_type 字段(形式为 maintype/subtype 的字符串,例如,"text/plain")和一个 params 字段(字符串键和值的字典)。除非 include_allTrue,否则将丢弃 charsetboundary 参数。

日期

一个 datetime.datetime 实例

原始日期

一个 datetime.datetime 实例

重发日期

一个 datetime.datetime 实例列表

发件人

一个单独的地址 dict

重发发件人

地址 dict 的列表

内容处置

包含一个 disposition 字段(值可以是 "inline""attachment")和一个 params 字段(字符串键和值的字典)的 dict

内容传输编码

一个单独的字符串。除非 include_allTrue,否则将丢弃此标题。

MIME 版本

一个单独的字符串。除非 include_allTrue,否则将丢弃此标题。

所有其他标题都表示为字符串列表。

前导信息

消息的 前导信息

内容

如果消息是多部分,则这是一个消息 dict 列表,结构与顶层 dict 相同。如果消息的 Content-Type 是 message/rfc822message/external-body,则这是一个单个消息 dict。如果消息的 Content-Type 是 text/*,则这是一个给出消息内容的 str。否则,这是一个给出消息内容的 bytes

后缀信息

消息的 后缀信息

示例:Python 文档中的 email 示例页面 包含了一个构建带有替代纯文本版本的 HTML 电子邮件的示例(主题为“让我们吃芦笋作为午餐”)。将生成的 EmailMessage 对象传递给 email2dict() 将产生以下输出结构

{
    "unixfrom": None,
    "headers": {
        "subject": "Ayons asperges pour le déjeuner",
        "from": [
            {
                "display_name": "Pepé Le Pew",
                "address": "pepe@example.com",
            },
        ],
        "to": [
            {
                "display_name": "Penelope Pussycat",
                "address": "penelope@example.com",
            },
            {
                "display_name": "Fabrette Pussycat",
                "address": "fabrette@example.com",
            },
        ],
        "content-type": {
            "content_type": "multipart/alternative",
            "params": {},
        },
    },
    "preamble": None,
    "content": [
        {
            "unixfrom": None,
            "headers": {
                "content-type": {
                    "content_type": "text/plain",
                    "params": {},
                },
            },
            "preamble": None,
            "content": (
                "Salut!\n"
                "\n"
                "Cela ressemble à un excellent recipie[1] déjeuner.\n"
                "\n"
                "[1] http://www.yummly.com/recipe/Roasted-Asparagus-Epicurious-203718\n"
                "\n"
                "--Pepé\n"
            ),
            "epilogue": None,
        },
        {
            "unixfrom": None,
            "headers": {
                "content-type": {
                    "content_type": "multipart/related",
                    "params": {},
                },
            },
            "preamble": None,
            "content": [
                {
                    "unixfrom": None,
                    "headers": {
                        "content-type": {
                            "content_type": "text/html",
                            "params": {},
                        },
                    },
                    "preamble": None,
                    "content": (
                        "<html>\n"
                        "  <head></head>\n"
                        "  <body>\n"
                        "    <p>Salut!</p>\n"
                        "    <p>Cela ressemble à un excellent\n"
                        "        <a href=\"http://www.yummly.com/recipe/Roasted-Asparagus-"
                        "Epicurious-203718\">\n"
                        "            recipie\n"
                        "        </a> déjeuner.\n"
                        "    </p>\n"
                        "    <img src=\"cid:RANDOM_MESSAGE_ID\" />\n"
                        "  </body>\n"
                        "</html>\n"
                    ),
                    "epilogue": None,
                },
                {
                    "unixfrom": None,
                    "headers": {
                        "content-type": {
                            "content_type": "image/png",
                            "params": {},
                        },
                        "content-disposition": {
                            "disposition": "inline",
                            "params": {},
                        },
                        "content-id": ["<RANDOM_MESSAGE_ID>"],
                    },
                    "preamble": None,
                    "content": b'IMAGE BLOB',
                    "epilogue": None,
                },
            ],
            "epilogue": None,
        },
    ],
    "epilogue": None,
}

format_addresses()

mailbits.format_addresses(addresses: Iterable[Union[str, Address, Group]], encode: bool = False) -> str

将电子邮件地址字符串的迭代器(形式为“foo@example.com”,没有尖括号或显示名称),email.headerregistry.Address 对象和/或 email.headerregistry.Group 对象转换为格式化的字符串。如果 encodeFalse(默认值),则非 ASCII 字符保持不变。如果为 True,则非 ASCII 显示名称转换为 RFC 2047 编码单词,非 ASCII 域名使用 Punycode 编码。

message2email()

mailbits.message2email(msg: email.message.Message) -> email.message.EmailMessage

将旧 Message 类(或其子类,如 mailbox 消息类)的实例转换为具有默认策略的新 EmailMessage 类的实例。如果 msg 已经是 EmailMessage,则返回不变。

parse_address()

mailbits.parse_address(s: str) -> email.headerregistry.Address

解析单个电子邮件地址——可以是原始地址,如“foo@example.com”,或者显示名称和地址的组合,如“Fabian Oh <foo@example.com>”,并将其解析为 Address 对象。

parse_addresses()

mailbits.parse_addresses(s: Union[str, email.headerregistry.AddressHeader]) \
    -> List[Union[email.headerregistry.Address, email.headerregistry.Group]]

解析格式化的电子邮件地址列表或EmailMessage的“收件人”、“抄送”、“密送”等头信息的内文,将其解析为Address和/或Group对象列表。

recipient_addresses()

mailbits.recipient_addresses(msg: email.message.EmailMessage) -> List[str]

返回一个排序后的列表,包含EmailMessage的“收件人”、“抄送”和“密送”等组合头信息中所有不同的电子邮件地址(不包括显示名称)。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分发

mailbits-0.2.1.tar.gz (35.3 kB 查看哈希值)

上传时间 源代码

构建分发

mailbits-0.2.1-py3-none-any.whl (11.7 kB 查看哈希值)

上传时间 Python 3

支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页