我正在使用MS Outlook 2010,并且正在努力让HR的生活变得更轻松。
鉴于一个用户列表(所有用户显然都拥有Outlook帐户),我想在将来的某个日期加载他们的空闲/忙碌状态。
如果我可以获得用户列表,那么这也很有用,但不是必需的。
我处理完数据后,我想以编程方式发送预约请求。
由于我使用的是Outlook 2010,显然我不能使用最新服务器中提供的REST接口(据我所知)。我很乐意通过sql访问这些信息,但我认为sql server不允许这样做。
我想避免使用VB。我可以做C#,但更喜欢python。我已安装“win32com.client”,但找不到获取用户列表或获取给定用户列表的空闲/忙碌时间的示例。
会喜欢任何建议。
答案 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