2015-11-02 80 views
2

我在MS Outlook 2010上試圖讓HR的生活更輕鬆。如何獲取Outlook用戶列表的空閒/忙碌狀態(以及如何獲取用戶列表)?

鑑於用戶列表(所有用戶顯然都擁有Outlook帳戶),我希望在未來的某個日期加載其空閒/忙碌狀態。

如果我可以得到一個用戶列表,那也是有用的,但不是必需的。

一旦我處理了數據,我想以編程方式發送預約請求。

由於我在Outlook 2010中,顯然我不能使用最新服務器中提供的REST接口(據我所知)。我很想通過sql訪問這些信息,但我不認爲sql服務器允許這樣做。

我想避免VB。我可以做C#,但寧願Python。我已安裝「win32com.client」,但無法找到獲取用戶列表或獲取給定用戶列表的空閒/忙碌時間的示例。

想了解任何建議。

回答

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 
+0

此風格的查詢是否支持2010?這看起來不像REST,所以不知道該怎麼去google。 – Shahbaz

+0

我不記得我寫的時候我們的服務器是否在運行2010年。看看http://stackoverflow.com/questions/20222941/retrieving-free-busy-status-from-microsoft-outlook-using-python –

相關問題