Exchangelib是一个强大的操作Exchange的python库,可以搜索、创建、更新、删除、导出和上传日历、邮箱、任务、联系人和通讯组。
安装
# 支持Kerberos、SSPI特性
pip install exchangelib[complete]
建立连接
from exchangelib import DELEGATE, IMPERSONATION, Account, Credentials
# 用户名格式为“域名\用户名形式”
credentials = Credentials(username='MYWINDOMAIN\\myusername', password='topsecret')
# 启用自动发现
my_account = Account(primary_smtp_address='myusername@example.com', credentials=credentials, autodiscover=True, access_type=DELEGATE)
访问文件夹
各种文件夹都是Account类的属性,例如account.root,account.calendar,account.trash,account.inbox,account.outbox,account.sent,account.junk,account.tasks和account.contacts。
from exchangelib import Account, Folder
some_folder = a.root / 'Some Folder'
some_folder.parent
some_folder.children # 子文件夹生成器
some_folder.walk() # 返回当前文件夹的所有子文件夹
some_folder.glob('foo*') # 返回匹配的子文件夹
# tree() 以字符串形式返回给定路径下的子文件夹结构树
print(a.root.tree())
# 可以创建、编辑、删除文件夹
f = Folder(parent=a.inbox, name='My New Folder')
f.save()
f.name = 'My New Subfolder'
f.save()
f.delete()
# 清空文件夹
f.empty()
# 清空并删除子文件夹
f.empty(delete_sub_folders=True)
时间,日期和时区
EWS对日期、时间和时区有一些特殊要求,因此需要使用EWSDate
,EWSDateTime
和EWSTimeZone
三个特殊类。
from datetime import datetime, timedelta
import pytz
from exchangelib import EWSTimeZone, EWSDateTime, EWSDate
# 可以使用本地计算机时区
tz = EWSTimeZone.localzone()
# EWSDate、EWSDateTime和datetime.datetime、datetime.date类似。要始终使用EWSTimeZone.localize()函数创建与时区关联的日期时间:
localized_dt = tz.localize(EWSDateTime(2017, 9, 5, 8, 30))
right_now = tz.localize(EWSDateTime.now())
# 日期时间可以加减
two_hours_later = localized_dt + timedelta(hours=2)
two_hours = two_hours_later - localized_dt
two_hours_later += timedelta(hours=2)
新建、更新、删除、发送、移动邮件
from exchangelib import Account, CalendarItem, Message, Mailbox, FileAttachment, HTMLBody
from exchangelib.items import SEND_ONLY_TO_ALL, SEND_ONLY_TO_CHANGED
from exchangelib.properties import DistinguishedFolderId
a = Account(...)
item = CalendarItem(folder=a.calendar, subject='foo')
# 注意:在实际操作时要求指定'start'、'end'属性
item.save() # 保存操作将给日程实例的'id'和'changekey'赋值
item.move(a.trash) # 移到垃圾邮件文件夹
# 或者在已发送文件保存一个副本:
m = Message(
account=a,
folder=a.sent,
subject='Daily motivation',
body='All bodies are beautiful',
to_recipients=[Mailbox(email_address='anne@example.com')]
)
m.send_and_save()
# 同样,您可以回复和转发存储在邮箱中的邮件(即邮件具有项目ID)。
m = a.sent.get(subject='Daily motivation')
m.reply(
subject='Re: Daily motivation',
body='I agree',
to_recipients=['carl@example.com', 'denice@example.com']
)
m.reply_all(subject='Re: Daily motivation', body='I agree')
m.forward(
subject='Fwd: Daily motivation',
body='Hey, look at this!',
to_recipients=['carl@example.com', 'denice@example.com']
)
使用附件
可以创建、删除和获取任何项目类型的附件,其中FileAttachment类为文件附件,'content’属性包含文件二进制内容;ItemAttachment类为各种项的附件,'item’属性为邮件的任意对象实例,该实例可以是Message, CalendarItem, Task等类型附件。
import os.path
from exchangelib import Account, FileAttachment, ItemAttachment, Message, CalendarItem, HTMLBody
a = Account
# 保存文件附件,打印项内容
for item in a.inbox.all():
for attachment in item.attachments:
if isinstance(attachment, FileAttachment):
local_path = os.path.join('/tmp', attachment.name)
with open(local_path, 'wb') as f:
f.write(attachment.content)
print('Saved attachment to', local_path)
elif isinstance(attachment, ItemAttachment):
if isinstance(attachment.item, Message):
print(attachment.item.subject, attachment.item.body)
# 创建带附件的项
item = Message(...)
binary_file_content = 'Hello from unicode æøå'.encode('utf-8') # Or read from file, BytesIO etc.
my_file = FileAttachment(name='my_file.txt', content=binary_file_content)
item.attach(my_file)
my_calendar_item = CalendarItem(...)
my_appointment = ItemAttachment(name='my_appointment', item=my_calendar_item)
item.attach(my_appointment)
item.save()
# 附件附加到现有项
my_other_file = FileAttachment(name='my_other_file.txt', content=binary_file_content)
item.attach(my_other_file)
# 删除附件
item.detach(my_file)
创建重复日历项
from datetime import timedelta
from exchangelib import Account, CalendarItem, EWSDateTime
from exchangelib.fields import MONDAY, WEDNESDAY
from exchangelib.recurrence import Recurrence, WeeklyPattern
a = Account(...)
start = a.default_timezone.localize(EWSDateTime(2017, 9, 1, 11))
end = start + timedelta(hours=2)
master_recurrence = CalendarItem(
folder=a.calendar,
start=start,
end=end,
subject='Hello Recurrence',
recurrence=Recurrence(
pattern=WeeklyPattern(interval=3, weekdays=[MONDAY, WEDNESDAY]),
start=start.date(),
number=7
),
)