# Extract a property from a message to a file. This is about the only
# way to extract huge properties such that the original data is available.
import sys, os
import mapi_driver
from win32com.mapi import mapitags, mapi
import pythoncom
def DumpItemProp(item, prop, outfile):
if type(prop)!=type(0):
# see if a mapitags contant
try:
prop = mapitags.__dict__[prop]
except KeyError:
# resolve as a name
props = ( (mapi.PS_PUBLIC_STRINGS, prop), )
propIds = obj.GetIDsFromNames(props, 0)
prop = mapitags.PROP_TAG( mapitags.PT_UNSPECIFIED, mapitags.PROP_ID(propIds[0]))
hr, data = item.GetProps((prop,), 0)
prop_tag, prop_val = data[0]
# Do some magic rtf conversion
if mapitags.PROP_ID(prop_tag) == mapitags.PROP_ID(mapitags.PR_RTF_COMPRESSED):
rtf_stream = item.OpenProperty(mapitags.PR_RTF_COMPRESSED, pythoncom.IID_IStream,
0, 0)
html_stream = mapi.WrapCompressedRTFStream(rtf_stream, 0)
chunks = []
while 1:
chunk = html_stream.Read(4096)
if not chunk:
break
chunks.append(chunk)
prop_val = "".join(chunks)
elif mapitags.PROP_TYPE(prop_tag)==mapitags.PT_ERROR and \
prop_val in [mapi.MAPI_E_NOT_ENOUGH_MEMORY,'MAPI_E_NOT_ENOUGH_MEMORY']:
prop_tag = mapitags.PROP_TAG(mapitags.PT_BINARY, mapitags.PROP_ID(prop_tag))
stream = item.OpenProperty(prop_tag,
pythoncom.IID_IStream,
0, 0)
chunks = []
while 1:
chunk = stream.Read(4096)
if not chunk:
break
chunks.append(chunk)
prop_val = "".join(chunks)
outfile.write(prop_val)
def DumpProp(driver, mapi_folder, subject, prop_tag, outfile):
hr, data = mapi_folder.GetProps( (mapitags.PR_DISPLAY_NAME_A,), 0)
name = data[0][1]
items = driver.GetItemsWithValue(mapi_folder, mapitags.PR_SUBJECT_A, subject)
num = 0
for item in items:
if num > 1:
print >> sys.stderr, "Warning: More than one matching item - ignoring"
break
DumpItemProp(item, prop_tag, outfile)
num += 1
if num==0:
print >> sys.stderr, "Error: No matching items"
def usage(driver):
folder_doc = driver.GetFolderNameDoc()
msg = """\
Usage: %s [-f foldername] [-o output_file] -p property_name subject of the message
-f - Search for the message in the specified folder (default = Inbox)
-p - Name of the property to dump
-o - Output file to be created - default - stdout.
Dumps all properties for all messages that match the subject. Subject
matching is substring and ignore-case.
%s
Use the -n option to see all top-level folder names from all stores.""" \
% (os.path.basename(sys.argv[0]),folder_doc)
print msg
def main():
driver = mapi_driver.MAPIDriver()
import getopt
try:
opts, args = getopt.getopt(sys.argv[1:], "np:f:o:")
except getopt.error, e:
print e
print
usage(driver)
sys.exit(1)
folder_name = prop_name = output_name = ""
for opt, opt_val in opts:
if opt == "-p":
prop_name = opt_val
elif opt == "-f":
folder_name = opt_val
elif opt == '-o':
output_name = os.path.abspath(opt_val)
elif opt == "-n":
driver.DumpTopLevelFolders()
sys.exit(1)
else:
print "Invalid arg"
return
if not folder_name:
folder_name = "Inbox" # Assume this exists!
subject = " ".join(args)
if not subject:
print "You must specify a subject"
print
usage(driver)
sys.exit(1)
if not prop_name:
print "You must specify a property"
print
usage(driver)
sys.exit(1)
if output_name:
output_file = file(output_name, "wb")
else:
output_file = sys.stdout
try:
folder = driver.FindFolder(folder_name)
except ValueError, details:
print details
sys.exit(1)
DumpProp(driver, folder, subject, prop_name, output_file)
if __name__=='__main__':
main()
syntax highlighted by Code2HTML, v. 0.9.1