Advertisement
kapildd

pywin32 MAPI

Jan 16th, 2015
384
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.43 KB | None | 0 0
  1. import gc
  2. import os
  3. import time
  4. import pythoncom
  5. import pywintypes
  6. import exceptions
  7. import types
  8. import base64
  9. import collections
  10.  
  11. from win32com import storagecon
  12. from win32com.mapi import mapi, mapiutil
  13. from win32com.mapi.mapitags import *
  14.  
  15. class MAPIReadTest:
  16. '''
  17.    After instantiating object, call initialize_test function and then run_test function.
  18.    Call closeMAPI() for cleanup
  19. '''
  20.     def __init__(self, profile = None, read_attachments = True):
  21.         print 'interface count:', pythoncom._GetInterfaceCount()
  22.         # mapi initialize
  23.         try:
  24.             mapi.MAPIInitialize(None)
  25.         except Exception, fault:
  26.             raise
  27.         self.profile = profile
  28.         self.read_attachments = read_attachments
  29.         self.email_count = 0
  30.  
  31.     def closeMAPI(self):
  32.         # cleanup
  33.         print 'interface count:', pythoncom._GetInterfaceCount()
  34.         print self.email_count
  35.         self.stores = {}
  36.         gc.collect()
  37.         self.session.Logoff(0,0,0)
  38.         self.session = None
  39.         try:
  40.             mapi.MAPIUninitialize()
  41.         except Exception, fault:
  42.             raise
  43.         print 'interface count:', pythoncom._GetInterfaceCount()
  44.  
  45.     def initialize_test(self):
  46.         # flags for mapi logon
  47.         logon_flags = (mapi.MAPI_NO_MAIL | mapi.MAPI_EXTENDED)
  48.         if not self.profile:
  49.             logon_flags |= mapi.MAPI_USE_DEFAULT
  50.         else:
  51.             logon_flags |= mapi.MAPI_NEW_SESSION
  52.  
  53.         # start session
  54.         self.session = mapi.MAPILogonEx(0, self.profile, None, logon_flags)
  55.  
  56.         # get stores
  57.         self.stores = {}
  58.         msg_store_table = self.session.GetMsgStoresTable(0)
  59.         rows = mapi.HrQueryAllRows(msg_store_table, (PR_ENTRYID,), None, None, 0)
  60.         for row in rows:
  61.             (eid_tag, eid) = row[0]
  62.             storeobj = self.session.OpenMsgStore(0, eid, None, mapi.MAPI_DEFERRED_ERRORS | mapi.MDB_NO_DIALOG)
  63.             hr, props = storeobj.GetProps([PR_DISPLAY_NAME], 0)
  64.             name = props[0][1]
  65.             self.stores[eid] = [name, storeobj, []]
  66.  
  67.         # traverse hierarchy, and store all PyIMAPIFolders in list(self.stores[eid][2])
  68.         for eid in self.stores:
  69.             self.traverse_hierarchy(self.stores[eid][1], '', self.stores[eid][0], self.stores[eid][2])
  70.         print 'interface count:', pythoncom._GetInterfaceCount()
  71.  
  72.     def traverse_hierarchy(self, store, path, dpath, flist):
  73.         if len(path.split('/')) == 1:
  74.             eid, dfolder = self.openFolder(store)
  75.             eid = base64.b16encode(eid)
  76.             name = dpath
  77.             path = eid
  78.         else:
  79.             name = dpath.rsplit('/', 1)[1]
  80.             eid = path.rsplit('/', 1)[1]
  81.             dfolder = store.OpenEntry(base64.b16decode(eid), None, mapi.MAPI_DEFERRED_ERRORS)
  82.         info = {'eid' : eid, 'name' : name, 'path' : path, 'dpath' : dpath}
  83.         ifolder = IterateFolder(dfolder)
  84.         flist.append([info, dfolder, ifolder])
  85.         table = dfolder.GetHierarchyTable(mapi.MAPI_UNICODE)
  86.         rows = mapi.HrQueryAllRows(table, (PR_ENTRYID, PR_DISPLAY_NAME), None, None, 0)
  87.         flags = mapi.MAPI_DEFERRED_ERRORS
  88.         for (eid_tag, seid), (name_tag, sname), in rows:
  89.             seid = base64.b16encode(seid)
  90.             spath = path + '/' + seid
  91.             sdpath = dpath + '/' + sname
  92.             try:
  93.                 self.traverse_hierarchy(store, spath, sdpath, flist)
  94.             except Exception, fault:
  95.                 print 'error in traverse_hierarchy for %s' % sdpath
  96.  
  97.     def openFolder(self, store, rw = False):
  98.         hr, data = store.GetProps((PR_IPM_SUBTREE_ENTRYID,), mapi.MAPI_UNICODE)
  99.         subtree_eid = data[0][1]
  100.         flags = mapi.MAPI_DEFERRED_ERRORS
  101.         if rw:
  102.             flags |= mapi.MAPI_MODIFY
  103.         return subtree_eid, store.OpenEntry(subtree_eid, None, flags)
  104.  
  105.     def run_test(self):
  106.         for eid in self.stores: # traverse stores
  107.             for folder in self.stores[eid][2]: # traverse list of all folders in store
  108.                 for email_entryid in folder[2].GetAllEids(): # traverse all entry ids in folder
  109.                     try:#open email from store
  110.                         email_obj = self.stores[eid][1].OpenEntry(email_entryid[1], None, mapi.MAPI_DEFERRED_ERRORS)
  111.                         self.email_count += 1
  112.                     except:
  113.                         print 'error while opening email ' + repr(fault)
  114.                     try:
  115.                         self.read_email(email_obj)
  116.                     except Exception, fault:
  117.                         print 'error in read_email ' + repr(fault)
  118.                     finally:
  119.                         print 'interface count: ', pythoncom._GetInterfaceCount()
  120.  
  121.     def read_email(self, email_obj):
  122.         #read email data
  123.         dump = email_obj.GetProps(email_obj.GetPropList(mapi.MAPI_UNICODE), mapi.MAPI_UNICODE)
  124.         dump = None
  125.         #read attachments
  126.         if self.read_attachments:
  127.             try:
  128.                 self.read_attachment(email_obj)
  129.             except Exception, fault:
  130.                 print 'error in read_attachment ' + repr(fault)
  131.  
  132.     def read_attachment(self, email_obj):
  133.         hr, hasattach = email_obj.GetProps([PR_HASATTACH,])
  134.         if not hasattach:
  135.             return
  136.         attach_table = email_obj.GetAttachmentTable(mapi.MAPI_UNICODE)
  137.         aidlist = mapi.HrQueryAllRows(attach_table, (PR_ATTACH_NUM), None, None, 0) # get all attachment ids
  138.         for aid in aidlist:
  139.             atch = email_obj.OpenAttach(aid[0][1], None, 0)
  140.             hr, atch_method = atch.GetProps((PR_ATTACH_METHOD,))
  141.             if atch_method[0][1] == mapi.ATTACH_BY_VALUE:
  142.                 data = self.readstream(atch, PR_ATTACH_DATA_BIN)
  143.                 del data
  144.             elif atch_method[0][1] == mapi.ATTACH_EMBEDDED_MSG:
  145.                 msg = atch.OpenProperty(PR_ATTACH_DATA_OBJ, mapi.IID_IMessage, 0, 0)
  146.                 try:
  147.                     self.read_email(msg)
  148.                 except Exception, fault:
  149.                     print repr(fault)
  150.             else:
  151.                 print 'Another method:%s'%atch_method[0][1]
  152.  
  153.  
  154.     def readstream(self, obj, prop):
  155.         stream = obj.OpenProperty(prop, pythoncom.IID_IStream, 0, 0)
  156.         stream.Seek(0, storagecon.STREAM_SEEK_SET)
  157.         size = stream.Stat()[2]
  158.         data = ''
  159.         while True:
  160.             buf = stream.Read(4<<20)
  161.             if not buf:
  162.                 break
  163.             data += buf
  164.             buf = None
  165.         del stream
  166.         return data
  167.  
  168. class IterateFolder:
  169.  
  170.     def __init__(self, folder):
  171.         self.folder = folder
  172.         self.done = False
  173.         self.ique = collections.deque()
  174.         table = self.folder.GetContentsTable(mapi.MAPI_UNICODE)
  175.         table.SetColumns((PR_ENTRYID, PR_RECORD_KEY), 0)
  176.         table.SortTable((((PR_RECORD_KEY, mapi.TABLE_SORT_ASCEND), ), 0, 0), mapi.TBL_BATCH)
  177.         self.table = table
  178.  
  179.     def __fetch(self):
  180.         if self.done:
  181.             return
  182.         rows = self.table.QueryRows(70, 0)
  183.         if len(rows) == 0:
  184.             self.done = True
  185.             return
  186.         for row in rows:
  187.             (tag, eid), (tag, rk) = row
  188.             self.ique.append((rk, eid))
  189.  
  190.     def GetAllEids(self):
  191.         while True:
  192.             if len(self.ique) == 0 and self.done:
  193.                 break
  194.             if len(self.ique) == 0:
  195.                 self.__fetch()
  196.                 continue
  197.             yield self.ique.popleft()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement