13.3 mailbox:管理email归档
mailbox模块定义了一个同样API,用来访问采用本地磁盘格式存储的邮件消息,包括:
maildir
mbox
MH
Baby1
MMDF
mailbox模块提供了Mailbox和Message基类,每个邮箱格式分布包含相应的一对子类,以实现相应格式的有关细节。
13.3.1 mbox
mbox格式是文档中展示的最简单的格式,因为它完全是纯文本的。每个邮箱都被存储为一个文件,并且所有消息都联接在一起。每次遇到一个以"From"开头的行时(“From"后面有一个空格),就会将其处理为一个新消息的开始。只要这些字符出现在消息体中某一行的开头,就会将其转义,在这一行前面增加”>"前缀。
13.3.1.1 创建mbox邮箱
将文件名传递到构造函数来实例化mbox类。如果该文件不存在,那么在使用add()追加消息时会创建这个文件。
import mailbox
import email.utils
from_addr = email.utils.formataddr(('Author','author@example.com'))
to_addr = email.utils.formataddr(('Recipient','recipient@example.com'))
payload = '''This is the body.
From (will not bve escaped).
There are 3 lines.
'''
mbox = mailbox.mbox('example.mbox')
mbox.lock()
try:
msg = mailbox.mboxMessage()
msg.set_unixfrom('author Sat Feb 7 01:05:34 2018')
msg['From'] = from_addr
msg['To'] = to_addr
msg['Subject'] = 'Sample message 1'
msg.set_payload(payload)
mbox.add(msg)
mbox.flush()
msg = mailbox.mboxMessage()
msg.set_unixfrom('author')
msg['From'] = from_addr
msg['To'] = to_addr
msg['Subject'] = 'Sample message 2'
msg.set_payload('This is the second body.\n')
mbox.add(msg)
mbox.flush()
finally:
mbox.unlock()
print(open('example.mbox','r').read())
这个脚本的结果是一个新的邮箱文件,其中包含两个邮件消息。
13.3.1.2 读取mbox邮箱
要读取一个已有的邮箱,需要打开这个邮箱,像字典一样处理这个mbox对象。键是邮箱实例定义的任意值,它们只作为消息对象的内部标识符,并不一定有实际意义。
import mailbox
mbox = mailbox.mbox('example.mbox')
for message in mbox:
print(message['subject'])
打开的邮箱支持迭代器协议,不过真正的字典对象不同,邮箱的默认迭代器会处理值(values)而不是键(keys)。
13.3.1.3 从mbox邮箱删除消息
import mailbox
mbox = mailbox.mbox('example.mbox')
mbox.lock()
try:
to_remove = []
for key,msg in mbox.iteritems():
if '2' in msg['subject']:
print('Removing:',key)
to_remove.append(key)
for key in to_remove:
mbox.remove(key)
finally:
mbox.flush()
mbox.close()
print(open('example.mbox','r').read())
可以使用lock()和unlock()方法来避免同时访问文件可能导致的问题,flush()强制将修改写入磁盘。