【问题标题】:accessing Exchange calendar items in shared or public folders with Python使用 Python 访问共享或公用文件夹中的 Exchange 日历项目
【发布时间】:2015-01-15 06:52:23
【问题描述】:

我在 Python 2.6 中通过 Outlook 使用 COM 迭代的 Exchange 日历项目返回了一些意外值。 Outlook 2010 32 位正在 Windows 7 上使用。

在查看日历时,无法在 Outlook 中看到脚本找到并记录的 6 个项目。在 2014 年 11 月 17 日下午 2 点之后,脚本只能看到 Outlook 中的 2 个项目。该脚本在下午 2 点运行。

共享或公用文件夹中的事件被用作会议室的日程安排。我不知道这些项目是如何创建或如何共享的,所以我不确定它们是什么对象类型。

这就是我在下面粘贴的脚本以通用方式编写并且缺少使用 .Restrict() 进行任何过滤的原因。我只是想“看到”一切可能。

脚本代码之后是日志输出。很抱歉冗长的输出和冗长的脚本,但我想包括我看过的所有不同的位,以防万一。我在 SO 和其他地方查看了其他一些帖子,并将下面显示的内容放在一起。下面引用了一些链接。也许它会帮助其他人。

我想要达到的最终结果是简单地为“房间 1”到“房间 4”提取当天的所有日历项目/事件。

脚本:

import sys
import datetime
import logging

import win32com.client

log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
log_formatter = logging.Formatter("%(asctime)s [%(levelname)-5.5s] %(message)s")
log_consolehandler = logging.StreamHandler()
log_consolehandler.setFormatter(log_formatter)
log.addHandler(log_consolehandler)
logfname = datetime.datetime.now().strftime('%Y%m%d-%H%M%S')
log_filehandler = logging.FileHandler('cal-%s.txt' % logfname, mode='a', encoding='utf-8')
log_filehandler.setFormatter(log_formatter)
log.addHandler(log_filehandler)


def convert_pytime_to_datetime(pytime):
    # arg is type PyTime, str is "09/10/13 16:00:00"
    return datetime.datetime.strptime(str(pytime), '%m/%d/%y %H:%M:%S')


def print_folders(folders, indent=0):
    prefix = ' ' * (indent*2)
    i = 0
    for folder in folders:
        log.info("{0}{1}. {2} ({3})".format(prefix, i, folder.Name, folder.DefaultItemType))
        print_folders(folder.Folders, indent + 1)
        i += 1


def find_folder(folders, search_path, level=0):
    """
    Outlook = win32com.client.Dispatch("Outlook.Application")
    mapi = Outlook.GetNamespace("MAPI")
    cal = find_folder(mapi.Folders, ['username@domain.com', 'calendar'])
    cal = find_folder(namespace.Folders, ["Internet Calendars", "Norfeld@so.com"])
    """
    for folder in folders:
        name = folder.Name
        if name.lower() == search_path[level].lower():
            if level < len(search_path)-1:
                # search sub folder
                folder = find_folder(folder.folders, search_path, level+1)
            return folder
    return None


Outlook = win32com.client.Dispatch("Outlook.Application")
mapi = Outlook.GetNamespace("MAPI")

print_folders(mapi.Folders)

# filter/restrict items to date range
flt_delta = datetime.timedelta(days=30)
flt_start = datetime.datetime.now()
flt_end = flt_start + flt_delta

# don't use .Restrict() for now until we know we can "see" items properly
#restriction = '[Start] >= "' + flt_start.strftime('%m/%d/%Y') + '" AND [End] <= "' + flt_end.strftime('%m/%d/%Y') + '"'
#restrictedItems = appointments.Restrict(restriction)
# iterate through restricted AppointmentItems
#for appointmentItem in restrictedItems:

#target_folder = ['myacct@mydomain.com', 'calendar']
target_folder = ['Public Folders - myacct@mydomain.com', 'All Public Folders', 'Conference Room Schedule', 'Room 1']
cal = find_folder(mapi.Folders, target_folder)
if cal is None:
    log.error('folder not found: %s' % target_folder)
    sys.exit()

items = cal.Items

# include recurring items
items.IncludeRecurrences = True
log.debug('items.IncludeRecurrences == %s' % items.IncludeRecurrences)

log.debug('date/time range is from "%s" to "%s" (%s)' % (flt_start, flt_end, flt_delta))

found_items = []

# for now iterate over all items and manually filter since .Restrict() is not working
for item in items:
    item_msgcls = item.MessageClass
    log.debug('found item "%s"' % item_msgcls)

    # make sure item is an appointment
    #if item_msgcls.lower() != 'ipm.appointment':
    #    log.debug('skipping non-appointment item "%s"' % item_msgcls)
    #    continue

    # manually filter item
    # "Start" is type PyTime
    if not hasattr(item, 'Start'):
        log.debug('skipping item "%s" which has no "Start" attribute (can\'t check start time)' % item_msgcls)
        continue
    item_start = convert_pytime_to_datetime(item.Start)
    if item_start < flt_start or item_start > flt_end:
        log.debug('skipping item "%s" with start date/time out of range: %s' % (item_msgcls, item_start))
        continue
    found_item = dict(item=item, item_start=item_start)
    found_items.append(found_item)
    log.debug('item "%s" has start date/time in range: %s' % (item_msgcls, item_start))
    log.debug('"%s" from "%s" to "%s"' % (item.Subject, item.Start, item.End))

if not found_items:
    log.debug('no items found in date/time range')
    sys.exit()

log.debug('%d item(s) found in date/time range' % len(found_items))

# sort items by start time
found_items = sorted(found_items, key=lambda  k: k['item_start'])
for item in found_items:
    item_start = item['item_start']
    item = item['item']
    log.debug('"%s" from "%s" to "%s"' % (item.Subject, item.Start, item.End))

日志输出:

2014-11-17 14:00:56,181 [INFO ] 0. Public Folders - myacct@mydomain.com (6)
2014-11-17 14:00:56,226 [INFO ]   0. Favorites (6)
2014-11-17 14:00:56,263 [INFO ]   1. All Public Folders (6)
2014-11-17 14:00:56,322 [INFO ]     0. Sales Calendar (1)
2014-11-17 14:00:56,375 [INFO ]     1. Conference Room Schedule (6)
2014-11-17 14:00:56,434 [INFO ]       0. Room 1 (1)
2014-11-17 14:00:56,476 [INFO ]       1. Room 2 (1)
2014-11-17 14:00:56,535 [INFO ]       2. Room 3 (1)
2014-11-17 14:00:56,588 [INFO ]       3. Room 4 (1)
2014-11-17 14:00:56,644 [INFO ]     2. ... (2)
2014-11-17 14:00:56,697 [INFO ]       0. ... (2)
2014-11-17 14:00:56,752 [INFO ]       1. ... (2)
2014-11-17 14:00:58,388 [INFO ] 1. myacct@mydomain.com (0)
2014-11-17 14:00:58,421 [INFO ]   0. Deleted Items (0)
2014-11-17 14:00:58,454 [INFO ]   1. Inbox (0)
2014-11-17 14:00:58,489 [INFO ]   2. Outbox (0)
2014-11-17 14:00:58,523 [INFO ]   3. Sent Items (0)
2014-11-17 14:00:58,558 [INFO ]   4. Calendar (1)
2014-11-17 14:00:58,592 [INFO ]   5. Contacts (2)
2014-11-17 14:00:58,664 [INFO ]   6. ... (0)
...
2014-11-17 14:00:59,296 [DEBUG] items.IncludeRecurrences == True
2014-11-17 14:00:59,315 [DEBUG] date/time range is from "2014-11-17 14:00:59.122000" to "2014-12-17 14:00:59.122000" (30 days, 0:00:00)
...
2014-11-17 14:00:59,358 [DEBUG] found item "IPM.Appointment"
2014-11-17 14:00:59,387 [DEBUG] skipping item "IPM.Appointment" with start date/time out of range: 2014-09-19 11:00:00
...
2014-11-17 14:01:30,595 [DEBUG] found item "IPM.Appointment"
2014-11-17 14:01:30,624 [DEBUG] skipping item "IPM.Appointment" with start date/time out of range: 2012-01-25 10:30:00
...
2014-11-17 14:01:38,961 [DEBUG] found item "IPM.Schedule.Meeting.Canceled"
2014-11-17 14:01:38,982 [DEBUG] skipping item "IPM.Schedule.Meeting.Canceled" which has no "Start" attribute (can't check start time)
...
2014-11-17 14:01:39,056 [DEBUG] found item "IPM.Schedule.Meeting.Request"
2014-11-17 14:01:39,079 [DEBUG] skipping item "IPM.Schedule.Meeting.Request" which has no "Start" attribute (can't check start time)
...
2014-11-17 14:01:50,782 [DEBUG] found item "IPM.Appointment"
2014-11-17 14:01:50,862 [DEBUG] item "IPM.Appointment" has start date/time in range: 2014-11-17 14:30:00
2014-11-17 14:01:50,888 [DEBUG] "ABC - meeting with Len Jones & John Li" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
...
2014-11-17 14:01:53,326 [DEBUG] found item "IPM.Appointment"
2014-11-17 14:01:53,375 [DEBUG] item "IPM.Appointment" has start date/time in range: 2014-11-17 14:30:00
2014-11-17 14:01:53,408 [DEBUG] "Don - Interview" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
2014-11-17 14:01:53,440 [DEBUG] found item "IPM.Appointment"
2014-11-17 14:01:53,487 [DEBUG] item "IPM.Appointment" has start date/time in range: 2014-11-17 14:30:00
2014-11-17 14:01:53,523 [DEBUG] "Don - Interview" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
...
2014-11-17 14:01:53,681 [DEBUG] found item "IPM.Appointment"
2014-11-17 14:01:53,732 [DEBUG] item "IPM.Appointment" has start date/time in range: 2014-11-17 14:30:00
2014-11-17 14:01:53,762 [DEBUG] "Weekly Conference Call" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
...
2014-11-17 14:01:58,049 [DEBUG] found item "IPM.Appointment"
2014-11-17 14:01:58,111 [DEBUG] item "IPM.Appointment" has start date/time in range: 2014-11-17 14:30:00
2014-11-17 14:01:58,151 [DEBUG] "Ben Connors - GHS" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
...
2014-11-17 14:01:58,326 [DEBUG] found item "IPM.Appointment"
2014-11-17 14:01:58,380 [DEBUG] item "IPM.Appointment" has start date/time in range: 2014-11-17 14:30:00
2014-11-17 14:01:58,414 [DEBUG] "Joe Dietz" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
...
2014-11-17 14:02:00,302 [DEBUG] 6 item(s) found in date/time range
2014-11-17 14:02:00,329 [DEBUG] "ABC - meeting with Len Jones & John Li" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
2014-11-17 14:02:00,365 [DEBUG] "Don - Interview" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
2014-11-17 14:02:00,403 [DEBUG] "Don - Interview" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
2014-11-17 14:02:00,434 [DEBUG] "Weekly Conference Call" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
2014-11-17 14:02:00,474 [DEBUG] "Ben Connors - GHS" from "11/17/14 14:30:00" to "11/17/14 14:30:00"
2014-11-17 14:02:00,510 [DEBUG] "Joe Dietz" from "11/17/14 14:30:00" to "11/17/14 14:30:00"

【问题讨论】:

    标签: python calendar outlook win32com


    【解决方案1】:

    让这个对我有用的关键是使用namespace.createRecipient("User Name") API 来引用共享日历。使用共享日历的用户的用户名。

    我在 SO 答案 https://stackoverflow.com/a/21532251/3476174 中找到了代码。

    recipient = namespace.createRecipient("User Name")
    resolved = recipient.Resolve()
    sharedCalendar = namespace.GetSharedDefaultFolder(recipient, 9)
    

    然后我能够按预期迭代sharedCalendar.Items。我还使用sharedCalendar.Items.Restrict() 成功过滤了上面链接中显示的事件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      • 2016-10-15
      • 2019-07-10
      • 2017-02-16
      • 2015-03-18
      • 2019-08-26
      相关资源
      最近更新 更多