доступ к элементам календаря Exchange в общих или общедоступных папках с помощью Python

Я получаю некоторые неожиданные значения, возвращаемые из элементов календаря Exchange, которые я повторяю в Python 2.6 через Outlook с использованием COM. 32-разрядная версия Outlook 2010 используется в Windows 7.

6 элементов, которые были найдены и зарегистрированы сценарием, не отображаются в Outlook при просмотре календаря. В Outlook есть только 2 элемента, которые должен видеть скрипт на 17.11.2014 после 14:00. Сценарий был запущен в 14:00.

В общих или общедоступных папках есть события, которые используются в качестве расписаний для конференц-залов. Я не знаю, как создаются элементы или как они распределяются, поэтому я не уверен, какие это типы объектов.

Вот почему сценарий, который я вставляю ниже, я написал в общем виде и не имеет никакой фильтрации с использованием .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, ['[email protected]', 'calendar'])
    cal = find_folder(namespace.Folders, ["Internet Calendars", "[email protected]"])
    """
    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 = ['[email protected]', 'calendar']
target_folder = ['Public Folders - [email protected]', '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 - [email protected] (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. [email protected] (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"

person nils    schedule 18.11.2014    source источник


Ответы (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() для успешной фильтрации событий, как показано в ссылке выше.

person nils    schedule 21.11.2014