我是python的新手。以下是我们用于发送邮件的代码。
import smtplib
import shutil
import os
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
To="maniram.220@gmailcom"
Subject="mail through code"
Text="Hai!"
mail_sender="pull@gmail.com"
mail_passwd="ZSDCXFF"
server = smtplib.SMTP('smtp.gmail.com', 587)
server.ehlo()
server.starttls()
server.ehlo
server.login(mail_sender,mail_passwd)
BODY='\r\n' .join(['To: %s' % To,'From: %s' % mail_sender,'Subject: %s' % Subject,'',Text])
try:
server.sendmail(mail_sender,[To],BODY)
print("email sent")
except:
print("error sending email")
server.quit()
我需要压缩文件夹中的文件(用户指定的路径),然后将其作为附件邮寄 我怎样才能达到这个目标?
答案 0 :(得分:0)
以下显示可能没有必要压缩整个目录以将其附加到电子邮件中。相反,只需根据需要调整FILE_PATHS
变量即可考虑所有文件。或者,您可以自由使用create_attachment
自动识别目录,将其压缩,并创建一个名称相同的附件以包含在电子邮件中。
#! /usr/bin/env python3
import collections
import contextlib
import email.encoders
import email.mime.application
import email.mime.audio
import email.mime.base
import email.mime.image
# import email.mime.message
import email.mime.multipart
import email.mime.text
import email.utils
import getpass
import mimetypes
import pathlib
import smtplib
import string
import tempfile
import uuid
import zipfile
FROM = 'John Doe', 'john.doe@gmail.com'
SUBJECT = 'Email Demonstration'
TO = [
('Jane Doe', 'jane.doe@gmail.com'),
('Mary Doe', 'mary.doe@gmail.com')
]
FILE_PATHS = [
pathlib.Path(r'C:\path\to\my\file'),
pathlib.Path(r'C:\path\to\another\file'),
pathlib.Path(r'C:\path to\yet\another\file'),
pathlib.Path(r'C:\why\are\there\so\many\paths')
]
PLAIN_MESSAGE = '''\
Hello, Jane and Mary!
How are you doing?
Hope you like the email.'''
HTML_TEMPLATE = r'''<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="${content_type}">
<title>${title}</title>
<style type="text/css" media="all">
.key {
color: #0066AA;
font-family: sans-serif;
font-size: 14px;
font-weight: bold;
}
.value {
color: #000000;
font-family: monospace;
font-size: 12px;
font-weight: normal;
}
</style>
</head>
<body>
<div class="value">
<span class="key">${header}</span>
${message}
</div>
<div class="value">
<span class="key">File Manifest</span>
${manifest}
</div>
</body>
</html>'''
HTML_MESSAGE = [
'When will the event start, and how much time do ushers need to show up '
'before the event?',
'Who will be admitted to the event, will they require tickets, and what '
'is to be done if we run out of room?',
'Where will the event be taking place, and will ushers need to enter '
'through a different way than everyone else?',
'How do you want your ushers to act, and will you have a rehearsal or '
'practice session explaining your expectations?',
'What clothing do you want ushers to where; and do you want the standard '
'black suit, white shirt, and red tie ushers usually where around here?'
]
def main():
message = create_multipart()
for path in FILE_PATHS:
mime, handle = create_attachment(path)
message.attach(mime)
message.attach(email.mime.text.MIMEText(PLAIN_MESSAGE, 'plain'))
attach_html_text(message)
with smtplib.SMTP('smtp.gmail.com', 587) as server:
server.starttls()
server.login(input('Username: '), getpass.getpass())
server.send_message(message)
def create_multipart():
message = email.mime.multipart.MIMEMultipart('alternative')
message['Message-ID'] = make_message_id()
message['From'] = email.utils.formataddr(FROM)
message['Date'] = email.utils.formatdate(localtime=True)
message['Subject'] = SUBJECT
message['To'] = email.utils.COMMASPACE.join(map(
email.utils.formataddr, TO
))
return message
def make_message_id():
return email.utils.make_msgid(str(uuid.uuid4()))
@contextlib.contextmanager
def create_temp_zip_file(directory):
paths_to_zip = collections.deque([directory])
with tempfile.TemporaryDirectory() as root:
handle = pathlib.Path(root) / f'{directory.name}.zip'
with zipfile.ZipFile(handle, 'x') as file:
while paths_to_zip:
path = paths_to_zip.popleft()
if path.is_dir():
paths_to_zip.extend(path.iterdir())
elif path.is_file():
file.write(path, path.relative_to(directory))
yield handle
def create_attachment(path):
if path.is_dir():
with create_temp_zip_file(path) as handle:
return create_attachment(handle)
kind, encoding = mimetypes.guess_type(str(path))
if kind is None:
kind = 'application/octet-stream'
main_type, sub_type = kind.split('/')
if main_type == 'application':
with path.open('rb') as file:
mime = email.mime.application.MIMEApplication(
file.read(),
sub_type
)
elif main_type == 'audio':
with path.open('rb') as file:
audio_data = file.read()
try:
mime = email.mime.audio.MIMEAudio(audio_data)
except TypeError:
mime = email.mime.audio.MIMEAudio(audio_data, sub_type)
elif main_type == 'image':
with path.open('rb') as file:
image_data = file.read()
try:
mime = email.mime.image.MIMEImage(image_data)
except TypeError:
mime = email.mime.image.MIMEImage(image_data, sub_type)
# elif main_type == 'message':
# attachment = email.mime.message.MIMEMessage()
elif main_type == 'text':
with path.open('rt') as file:
mime = email.mime.text.MIMEText(file.read(), sub_type)
else:
mime = email.mime.base.MIMEBase(main_type, sub_type)
with path.open('rb') as file:
mime.set_payload(file.read())
email.encoders.encode_base64(mime)
mime.add_header('Content-Disposition', 'attachment', filename=path.name)
content_id = make_message_id()
mime.add_header('Content-ID', content_id)
handle = f'"cid:{content_id.strip("<>")}"'
return mime, handle
def attach_html_text(message):
mapping = dict(
content_type='',
title=message['Subject'],
header=message['Subject'],
message=make_html_list(HTML_MESSAGE, 'o', 1),
manifest=make_html_list(FILE_PATHS, 'u', 1)
)
template = string.Template(HTML_TEMPLATE)
mime = email.mime.text.MIMEText(template.substitute(mapping), 'html')
mapping['content_type'] = mime['Content-Type'].replace('"', '')
mime = email.mime.text.MIMEText(template.substitute(mapping), 'html')
message.attach(mime)
def make_html_list(iterable, kind, indent=0, space=' ' * 4):
prefix = space * indent
elements = [f'{prefix}<{kind}l>']
elements.extend(f'{prefix}{space}<li>{item}</li>' for item in iterable)
elements.append(f'{prefix}</{kind}l>')
return '\n'.join(elements)
if __name__ == '__main__':
main()