使用Python访问共享或公用文件夹中的Exchange日历项

时间:2014-11-18 06:51:28

标签: python calendar outlook win32com

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

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

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

这就是为什么我在下面粘贴的脚本以通用的方式编写并且没有使用.Restrict()进行任何过滤。我只是想"看到"一切皆有可能。

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

我试图实现的最终结果是简单地将当天的所有日历项目/事件拉到"房间1"通过" Room 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"

1 个答案:

答案 0 :(得分: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()成功过滤了事件,如上面的链接所示。