views:

2073

answers:

2

I am using Microsoft's CDO (Collaboration Data Objects) to programatically read mail from an Outlook mailbox and save embedded image attachments. I'm trying to do this from Python using the Win32 extensions, but samples in any language that uses CDO would be helpful.

So far, I am here...

The following Python code will read the last email in my mailbox, print the names of the attachments, and print the message body:

from win32com.client import Dispatch

session = Dispatch('MAPI.session')
session.Logon('','',0,1,0,0,'exchange.foo.com\nbar');
inbox = session.Inbox
message = inbox.Messages.Item(inbox.Messages.Count)

for attachment in message.Attachments:
    print attachment

print message.Text

session.Logoff()

However, the attachment names are things like: "zesjvqeqcb_chart_0". Inside the email source, I see image source links like this: <IMG src="cid:zesjvqeqcb_chart_0">

So.. is it possible to use this CID URL (or anything else) to extract the actual image and save it locally?

+4  A: 

Difference in versions of OS/Outlook/CDO is what might be the source of confusion, so here are the steps to get it working on WinXP/Outlook 2007/CDO 1.21:

  • install CDO 1.21
  • install win32com.client
  • goto C:\Python25\Lib\site-packages\win32com\client\ directory run the following:
python makepy.py
  • from the list select "Microsoft CDO 1.21 Library (1.21)", click ok
C:\Python25\Lib\site-packages\win32com\client>python makepy.py
Generating to C:\Python25\lib\site-packages\win32com\gen_py\3FA7DEA7-6438-101B-ACC1-00AA00423326x0x1x33.py
Building definitions from type library...
Generating...
Importing module
  • Examining file 3FA7DEA7-6438-101B-ACC1-00AA00423326x0x1x33.py that's just been generated, will give you an idea of what classes, methods, properties and constants are available.

Now that we are done with the boring steps, here is the fun part:

import win32com.client
from win32com.client import Dispatch

session = Dispatch('MAPI.session')
session.Logon ('Outlook') # this is profile name
inbox = session.Inbox
messages = session.Inbox.Messages 
message = inbox.Messages.GetFirst()

if(message):
    attachments = message.Attachments
    for i in range(attachments.Count):
        attachment = attachments.Item(i + 1) # yep, indexes are 1 based

        filename = "c:\\tmpfile" + str(i)
        attachment.WriteToFile(FileName=filename)
session.Logoff()

Same general approach will also work if you have older version of CDO (CDO for win2k)

I'm trying those in code above and it isn't working. I don't see that method and property in my attachment object. ideas?
Corey Goldberg
need to use GetDecodedContentStream I've edited the answer
in the code abocve, i still get "AttributeError: <unknown>.GetDecodedContentStream" when trying to call that method. It also can't see the FileName property. Any tip on how to use that interface from my Python code above?
Corey Goldberg
more detailed, completely revamped answer - hopefully it would help
it works now! answer accepted. thanks!
Corey Goldberg
A: 

Hi, I have done as you suggest, but I get an error when I try to do attachment.WriteToFile (error generated in wincom32\client\dynamic.py Line 512 Any idea why? Sca

Sca