python邮件脚本-添加zip

Posted

技术标签:

【中文标题】python邮件脚本-添加zip【英文标题】:python mailing script - adding zip 【发布时间】:2021-12-31 12:10:08 【问题描述】:

我想就在我用于发送报告的邮件脚本中添加 zip 选项征求意见。

我将电子邮件附件限制设置为 25MB,因此邮件程序脚本会删除一些超过 25MB 的 json 格式的报告。我想添加一个 zip 支持,如果附件比 ex 大,它将压缩附件。 15MB。

以下代码仅是邮件部分。

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
from email.utils import COMMASPACE
import sys
from os.path import basename
import argparse
import conf
import os
import zipfile
import zlib

###############################################################################
# Mailer function for server running environment

def send_mail(recipients, cc=None, subject=None, attachment=None, body=None, send_from=None): 
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['From'] = send_from
    msg['To'] = ','.join(recipients)
    if cc:
        msg['CC'] = ','.join(cc)
        recipients.extend(cc)
    if body:
        text = MIMEText(body, 'html')
        msg.attach(text)
    if attachment:
        with open(attachment, 'rb') as fp:
            att = MIMEApplication(fp.read(), Name=basename(attachment))
        att['Content-Disposition'] = f'attachment; filename="basename(attachment)"'
        msg.attach(att)

    smtp = smtplib.SMTP(conf.RELAY)
    smtp.sendmail(send_from, recipients, msg.as_string())
    smtp.quit()

【问题讨论】:

【参考方案1】:

假设您已经拥有的代码正确地附加了任意附件,包括二进制附件,那么下面应该压缩一个大于 15M 的附件。例如,如果原始文件的基本名称为 test.dat,则附件存档名称将为 test.dat.zip 并包含 test.dat 作为单个压缩文件隐式使用zlib。由于使用了内存缓冲区,因此不需要临时文件。因此,如果附件不是特别大,这应该是非常有效的:

    if attachment:
        MAX_ATTACHMENT_SIZE = 15 * 1024 * 1024
        with open(attachment, 'rb') as fp:
            bytes = fp.read()
        attachment_name = basename(attachment)
        if len(bytes) > MAX_ATTACHMENT_SIZE:
            from io import BytesIO
            buffer = BytesIO()
            with zipfile.ZipFile(buffer, 'w', compression=zipfile.ZIP_DEFLATED) as zip_file:
                zip_file.writestr(attachment_name, bytes)
            # New attachment name and new data:
            attachment_name += '.zip'
            bytes = buffer.getvalue()            
        att = MIMEApplication(bytes, Name=attachment_name)
        att['Content-Disposition'] = f'attachment; filename="attachment_name"'
        msg.attach(att)

【讨论】:

非常感谢 - 这就是我想要的。让我仔细检查一下明天是否会表现良好。 似乎已触发压缩过程,但出现错误“NameError: name 'ZipFile' is not defined”。你能帮我在代码中定义它吗? 我修改了代码。我正在使用与您不同的导入语句进行测试。它应该现在可以工作了。对此我很抱歉。 非常感谢@Booboo - 明天早上测试。 一切都很好!非常感谢!【参考方案2】:

如果要压缩附件,可以使用zipfile模块压缩文件。

import zipfile
import tempfile
from email import encoders
from email.message import Message
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart 

...
if attachment:
    zf = tempfile.TemporaryFile(prefix='mail', suffix='.zip')
    zip = zipfile.ZipFile(zf, 'w')
    zip.write(attachment)
    zip.close()
    zf.seek(0)
    att = MIMEBase('application', 'zip')
    att.set_payload(zf.read())
    encoders.encode_base64(att)
    att.add_header('Content-Disposition', 'attachment', filename=the_file + '.zip')
    msg.attach(att)
...

【讨论】:

以上是关于python邮件脚本-添加zip的主要内容,如果未能解决你的问题,请参考以下文章

将python脚本添加到c ++项目

将 zip 文件添加到电子邮件中

使用Python将文件列表添加到zip文件中

Python用20行代码实现完整邮件功能 [完整代码+建议收藏]

python实现发送邮件功能

Python用20行代码实现完整邮件功能 [完整代码+建议收藏]