Welcome, guest | Sign In | My Account | Store | Cart

If you want to talk to a MS exchange server, webdav offers a convenient way to do so. The code below shows the very basics for searching, deleting, and creating.

Python, 63 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import win32com
import win32com.client

#depth: 0=immediate depth,1=w/children,infinity=all the way down

def return_dav(dav,dav_response=''):
    if dav.status > 299:
        raise 'webdav error',str(dav.status)+':'+dav.statusText
    if dav_response=='dav': return dav
    elif dav_response=='xml': return dav.responseXML
    #by default return text
    return dav.responseText    

def search_request(url,request,logon='',passwd='',depth=1):
   dav = win32com.client.Dispatch('Microsoft.XMLHTTP')
   dav.open('SEARCH',url, 0,logon, passwd)
   dav.setRequestHeader("Content-type:", "text/xml")
   dav.setRequestHeader("depth", depth)    
   dav.setRequestHeader("Translate", "f")
   dav.send(request)
   return return_dav(dav)  
   
def propfind(url,request,logon='',passwd='',depth=1):
   dav = win32com.client.Dispatch('Microsoft.XMLHTTP')
   dav.open('PROPFIND',url, 0,logon, passwd)
   dav.setRequestHeader("Content-type:", "text/xml")
   dav.setRequestHeader("depth", depth)   
   dav.setRequestHeader("Translate", "f")
   dav.send(request)
   return return_dav(dav)   

def delete(url='',logon='',passwd=''):
    dav = win32com.client.Dispatch('Microsoft.XMLHTTP')
    dav.open('DELETE',url, 0,logon, passwd)
    dav.send()
    return return_dav(dav)  

#create a collection
def mkcol(url='',logon='',passwd=''):
    dav = win32com.client.Dispatch('Microsoft.XMLHTTP')
    dav.open('MKCOL',url,0)
    dav.setRequestHeader('Content-Type:','text/xml')
    dav.send()
    return return_dav(dav)  

url='http://server/exchange/username/inbox/test'

pfind='''<?xml version="1.0" ?>
<D:propfind xmlns:D='DAV:' xmlns:m='urn:schemas:httpmail:'>
  <D:prop> <m:from/> <m:to/> <m:subject/> </D:prop>
</D:propfind>'''

search='''<?xml version="1.0"?>
<D:searchrequest xmlns:D = "DAV:" >
    <D:sql>SELECT "DAV:displayname"  FROM "%s"</D:sql>
</D:searchrequest>
'''%(url)

#may need to provide username and password
print propfind(url,pfind)
print search_request(url,search)
mkcol(url+'/test3') #make a folder
delete(url+'/test3') #remove a folder

This simple code assumes that you have a folder named test in the inbox for the account used. It also assumes the account has permission to do the operations for that account. If it does not you will need to provide a username and password for an account that does.

Part 2 will show some more sophisticated used of webdav and exchange.

You can reach me at pyguy2 on yahoo

2 comments

Stuart Turner 18 years, 6 months ago  # | flag

xmlhttp without using win32 com wrappers. Hi,

This code really helped me get started with webdav. I also wrote a small python class to give the same functionality as the xmlhttp com object. Have tested the code on Windows XP Service Pack 2 and also Red Hat Linux. Both seem to work fine. Let me know if you encounter any issues!

Class File

# Create a class with the same functionality
# as XMLHTTP

import httplib, base64, urlparse

class xmlhttp:

    def __init__ (self):
        self.__headers = {}

    def addHeader (self, name, content):
        self.__headers[name] = content

    def sendRequest (self, verb, url, request, username, password):

        # Encode the username and password as base 64.  Remove the newline
        # which base64 puts at the end of the string
        upB64 = base64.encodestring('%s:%s' % (username, password))[:-1]

        # Add the Authorisation header
        self.__headers['Authorization'] = 'Basic %s' % upB64

        # Parse out the URL in to components
        (scheme, netloc, path, params, query) = \
            urlparse.urlsplit (url)

        con = httplib.HTTPConnection(netloc)
        con.request(verb, path, request, self.__headers)

        response = con.getresponse()

        return (response.status, response.reason, response.read())

Example Usage

import ... xmlhttp ...

...

        dav = xmlhttp.xmlhttp()
        dav.addHeader("Content-type", "text/xml")
        status, statustext, responseText = \
            dav.sendRequest('SEARCH', url, req, user, pwd)
Jeff Rebeiro 16 years, 8 months ago  # | flag

non-COM xmlhttp class not working. The code given to make this work in Linux is not working. How can I get in contact with you?