如何获取outlook上的用户列表的空闲/忙碌状态(以及如何获取用户列表)?

时间:2015-11-02 19:45:58

标签: c# python outlook win32com

我正在使用MS Outlook 2010,并且正在努力让HR的生活变得更轻松。

鉴于一个用户列表(所有用户显然都拥有Outlook帐户),我想在将来的某个日期加载他们的空闲/忙碌状态。

如果我可以获得用户列表,那么这也很有用,但不是必需的。

我处理完数据后,我想以编程方式发送预约请求。

由于我使用的是Outlook 2010,显然我不能使用最新服务器中提供的REST接口(据我所知)。我很乐意通过sql访问这些信息,但我认为sql server不允许这样做。

我想避免使用VB。我可以做C#,但更喜欢python。我已安装“win32com.client”,但找不到获取用户列表或获取给定用户列表的空闲/忙碌时间的示例。

会喜欢任何建议。

1 个答案:

答案 0 :(得分:1)

前段时间,我写了一些代码,以便在特定时间获得某人的空闲/忙碌状态。我想你可以使用这段代码作为起点来获得你需要的东西。享受!

# method for communicating with an exchange calendar to see if a person has
# a current appointment marking them as unreachable (i.e. on vacation, out
# sick, attending an all-day offsite meeting, etc).

import datetime
import time
import httplib
import urllib
import base64
import xml.dom.minidom

def is_available(email_address, timestamp):
    '''Query the calendar and see if this person is available at the
    given time.'''

    # assume they are available
    available = True

    # this is a template for the SOAP command which queries the calendar.
    # Address, StartTime and EndTime will be filled in later
    soapTemplate = '''
    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <GetUserAvailabilityRequest xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
          <TimeZone xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
            <Bias>360</Bias>
            <StandardTime>
              <Bias>0</Bias>
              <Time>02:00:00</Time>
              <DayOrder>1</DayOrder>
              <Month>11</Month>
              <DayOfWeek>Sunday</DayOfWeek>
            </StandardTime>
            <DaylightTime>
              <Bias>-60</Bias>
              <Time>02:00:00</Time>
              <DayOrder>2</DayOrder>
              <Month>3</Month>
              <DayOfWeek>Sunday</DayOfWeek>
            </DaylightTime>
          </TimeZone>
          <MailboxDataArray>
            <MailboxData xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
              <Email>
                <Address>%s</Address>
              </Email>
              <AttendeeType>Required</AttendeeType>
            </MailboxData>
          </MailboxDataArray>
          <FreeBusyViewOptions xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
            <TimeWindow>
              <StartTime>%s</StartTime>
              <EndTime>%s</EndTime>
            </TimeWindow>
            <MergedFreeBusyIntervalInMinutes>5</MergedFreeBusyIntervalInMinutes>
            <RequestedView>FreeBusy</RequestedView>
          </FreeBusyViewOptions>
        </GetUserAvailabilityRequest>
      </soap:Body>
    </soap:Envelope>
    '''.strip()

    # get a SOAP-compatible representation of the given timestamp, and
    # another timestamp for five minutes later.  (the Exchange server
    # requires that the two timestamps be at least five minutes apart.)
    startTime = soap_time(timestamp)
    fiveMinuteDelta = datetime.timedelta(minutes=5)
    endTime = soap_time(timestamp + fiveMinuteDelta)

    # fill in the soap template with times and email address
    soapMessage = soapTemplate % (email_address, startTime, endTime)

    # get the server response as a string
    soapResponse = soap_query(soapMessage)

    # parse the string into an xml node tree structure
    xmldoc = xml.dom.minidom.parseString(soapResponse)

    # do we have a root <Envelope> element?
    root = xmldoc.childNodes[0]
    if root.localName.lower() != 'envelope':
        # punt
        return available

    node = root

    # traverse the xml document, looking for this series of nodes
    element_names = ['body', 'GetUserAvailabilityResponse',
        'FreeBusyResponseArray', 'FreeBusyResponse', 'ResponseMessage']

    for element_name in element_names:
        new_node = find_node(node, element_name)
        if not new_node:
            return available
        node = new_node

    # see if we got a 'success' or 'error' response

    successResponse = False
    errorResponse   = False

    attribs = node.attributes
    for i in range(attribs.length):
        if attribs.item(i).name.lower() == 'responseclass':
            if attribs.item(i).value.lower() == 'success':
                successResponse = True
            elif attribs.item(i).value.lower() == 'error':
                errorResponse = True

    if not successResponse:
        return available

    # since we got a success response, keep traversing
    element_names = ['freeBusyView', 'CalendarEventArray']

    for element_name in element_names:
        new_node = find_node(node, element_name)
        if not new_node:
            return available
        node = new_node

    for item in node.childNodes:
        if item.localName and item.localName.lower() == 'calendarevent':
            for child in item.childNodes:
                if child.localName and child.localName.lower() == 'busytype':
                    if child.childNodes[0].nodeValue.lower() == 'oof':
                        # hallelujah!
                        available = False
                        break

    return available


def soap_query(message):
    '''Send the message to the calendar server and return the response.'''

    host = 'exchange.yourcompany.com' # your calendar server host name
    uri = '/EWS/Exchange.asmx' # your calendar uri
    username = 'foobar' # your calendar user name
    password = 'bazbaz' # your calendar password

    auth = base64.encodestring(username + ':' + password).strip()

    headers = { 'Authorization': 'Basic %s' % auth,
                'Content-type' : 'text/xml; charset="utf-8"',
                'User-Agent'   : 'python' }

    # make the connection
    conn = httplib.HTTPSConnection(host)

    # send the request
    conn.request('POST', uri, message, headers)

    # get the response
    resp = conn.getresponse()

    # get the various parts of the response
    body    = resp.read()
    headers = resp.msg
    version = resp.version
    status  = resp.status
    reason  = resp.reason

    conn.close()

    return body


def soap_time(timestamp):
    '''Return the timestamp as a SOAP-compatible time string.'''

    return timestamp.strftime('%Y-%m-%dT%H:%M:%S')


def find_node(node, name):
    '''Return the first child node with the given name, or return None
    if no children exist by that name.'''

    for child in node.childNodes:
        if child.localName:
            if child.localName.lower() == name.lower():
                return child

    return None