[Spambayes-checkins] spambayes/Outlook2000 msgstore.py,1.11,1.12

Tim Peters tim_one@users.sourceforge.net
Mon Oct 28 05:15:53 2002


Update of /cvsroot/spambayes/spambayes/Outlook2000
In directory usw-pr-cvs1:/tmp/cvs-serv15254/Outlook2000

Modified Files:
	msgstore.py 
Log Message:
Split lots of long lines, and added (probably too many!) comments to
_FindDefaultMessageStore().

I'm trying to figure out why something doesn't work:  the folder trees
displayed in the training and classify dialogs allow selecting folders
from any number of .pst files, but selecting one from anything other
than "my main" .pst file doesn't work (a thread dies with an exception
upon hitting the "Train now" or "Classify now" button, and before that
"<unknown folder>" shows up in the display).

I don't really know what "my main .pst file" means at the code level,
but *suspect* it's what _FindDefaultMessageStore() is figuring out, and
that the MAPIMsgStore class is *always* trying to use that .pst file as
a result, and that the folder IDs found for folders in other .pst files
by the dialogs simply don't make any sense when passed to a MAPIMsgStore
instance later.

I'm keen to get this to work for two reasons:

1. So I can move 40MB of old spam out of my main .pst file and into a
   new Training.pst file (I won't have to burn hours transferring that
   one between my desktop and laptop).

2. I have a dozen other .pst files with archives of older email, and I'd
   like to access that for training too.

I suspect this is more difficult than I imagine <wink>.


Index: msgstore.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/Outlook2000/msgstore.py,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** msgstore.py	26 Oct 2002 05:30:39 -0000	1.11
--- msgstore.py	28 Oct 2002 05:15:50 -0000	1.12
***************
*** 92,96 ****
          cwd = os.getcwd()
          mapi.MAPIInitialize(None)
!         logonFlags = mapi.MAPI_NO_MAIL | mapi.MAPI_EXTENDED | mapi.MAPI_USE_DEFAULT
          self.session = mapi.MAPILogonEx(0, None, None, logonFlags)
          self._FindDefaultMessageStore()
--- 92,98 ----
          cwd = os.getcwd()
          mapi.MAPIInitialize(None)
!         logonFlags = (mapi.MAPI_NO_MAIL |
!                       mapi.MAPI_EXTENDED |
!                       mapi.MAPI_USE_DEFAULT)
          self.session = mapi.MAPILogonEx(0, None, None, logonFlags)
          self._FindDefaultMessageStore()
***************
*** 99,103 ****
      def Close(self):
          self.mapi_msgstore = None
!         self.session.Logoff(0,0,0)
          self.session = None
          mapi.MAPIUninitialize()
--- 101,105 ----
      def Close(self):
          self.mapi_msgstore = None
!         self.session.Logoff(0, 0, 0)
          self.session = None
          mapi.MAPIUninitialize()
***************
*** 105,125 ****
      def _FindDefaultMessageStore(self):
          tab = self.session.GetMsgStoresTable(0)
!         # restriction for the table.
!         restriction = mapi.RES_PROPERTY, (mapi.RELOP_EQ, PR_DEFAULT_STORE, (PR_DEFAULT_STORE, True))
!         rows = mapi.HrQueryAllRows(tab, (PR_ENTRYID,), restriction, None, 0)
!         # get first entry
          row = rows[0]
          eid_tag, eid = row[0]
          # Open the store.
!         self.mapi_msgstore = self.session.OpenMsgStore(0, eid, None, mapi.MDB_WRITE | mapi.MDB_NO_MAIL | USE_DEFERRED_ERRORS )
  
      def _GetSubFolderIter(self, folder):
          table = folder.GetHierarchyTable(0)
!         rows = mapi.HrQueryAllRows(table, (PR_ENTRYID,PR_DISPLAY_NAME_A), None, None, 0)
          for (eid_tag, eid),(name_tag, name) in rows:
!             sub = self.mapi_msgstore.OpenEntry(eid, None, mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
              table = sub.GetContentsTable(0)
              yield MAPIMsgStoreFolder(self, eid, name, table.GetRowCount(0))
!             folder = self.mapi_msgstore.OpenEntry(eid, None, mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
              for store_folder in self._GetSubFolderIter(folder):
                  yield store_folder
--- 107,153 ----
      def _FindDefaultMessageStore(self):
          tab = self.session.GetMsgStoresTable(0)
!         # Restriction for the table:  get rows where PR_DEFAULT_STORE is true.
!         # There should be only one.
!         restriction = (mapi.RES_PROPERTY,   # a property restriction
!                        (mapi.RELOP_EQ,      # check for equality
!                         PR_DEFAULT_STORE,   # of the PR_DEFAULT_STORE prop
!                         (PR_DEFAULT_STORE, True))) # with True
!         rows = mapi.HrQueryAllRows(tab,
!                                    (PR_ENTRYID,),   # columns to retrieve
!                                    restriction,     # only these rows
!                                    None,            # any sort order is fine
!                                    0)               # any # of results is fine
!         # get first entry, a (property_tag, value) pair, for PR_ENTRYID
          row = rows[0]
          eid_tag, eid = row[0]
          # Open the store.
!         self.mapi_msgstore = self.session.OpenMsgStore(
!                                 0,      # no parent window
!                                 eid,    # msg store to open
!                                 None,   # IID; accept default IMsgStore
!                                 # need write access to add score fields
!                                 mapi.MDB_WRITE |
!                                     # we won't send or receive email
!                                     mapi.MDB_NO_MAIL |
!                                     USE_DEFERRED_ERRORS)
  
      def _GetSubFolderIter(self, folder):
          table = folder.GetHierarchyTable(0)
!         rows = mapi.HrQueryAllRows(table,
!                                    (PR_ENTRYID, PR_DISPLAY_NAME_A),
!                                    None,
!                                    None,
!                                    0)
          for (eid_tag, eid),(name_tag, name) in rows:
!             sub = self.mapi_msgstore.OpenEntry(eid,
!                                                None,
!                                                mapi.MAPI_MODIFY |
!                                                    USE_DEFERRED_ERRORS)
              table = sub.GetContentsTable(0)
              yield MAPIMsgStoreFolder(self, eid, name, table.GetRowCount(0))
!             folder = self.mapi_msgstore.OpenEntry(eid,
!                                                   None,
!                                                   mapi.MAPI_MODIFY |
!                                                       USE_DEFERRED_ERRORS)
              for store_folder in self._GetSubFolderIter(folder):
                  yield store_folder
***************
*** 128,135 ****
          for folder_id in folder_ids:
              folder_id = mapi.BinFromHex(folder_id)
!             folder = self.mapi_msgstore.OpenEntry(folder_id, None, mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
              table = folder.GetContentsTable(0)
              rc, props = folder.GetProps( (PR_DISPLAY_NAME_A,), 0)
!             yield MAPIMsgStoreFolder(self, folder_id, props[0][1], table.GetRowCount(0))
              if include_sub:
                  for f in self._GetSubFolderIter(folder):
--- 156,167 ----
          for folder_id in folder_ids:
              folder_id = mapi.BinFromHex(folder_id)
!             folder = self.mapi_msgstore.OpenEntry(folder_id,
!                                                   None,
!                                                   mapi.MAPI_MODIFY |
!                                                       USE_DEFERRED_ERRORS)
              table = folder.GetContentsTable(0)
              rc, props = folder.GetProps( (PR_DISPLAY_NAME_A,), 0)
!             yield MAPIMsgStoreFolder(self, folder_id, props[0][1],
!                                      table.GetRowCount(0))
              if include_sub:
                  for f in self._GetSubFolderIter(folder):
***************
*** 139,146 ****
          # Return a single folder given the ID.
          folder_id = mapi.BinFromHex(folder_id)
!         folder = self.mapi_msgstore.OpenEntry(folder_id, None, mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
          table = folder.GetContentsTable(0)
          rc, props = folder.GetProps( (PR_DISPLAY_NAME_A,), 0)
!         return MAPIMsgStoreFolder(self, folder_id, props[0][1], table.GetRowCount(0))
  
      def GetMessage(self, message_id):
--- 171,182 ----
          # Return a single folder given the ID.
          folder_id = mapi.BinFromHex(folder_id)
!         folder = self.mapi_msgstore.OpenEntry(folder_id,
!                                               None,
!                                               mapi.MAPI_MODIFY |
!                                                   USE_DEFERRED_ERRORS)
          table = folder.GetContentsTable(0)
          rc, props = folder.GetProps( (PR_DISPLAY_NAME_A,), 0)
!         return MAPIMsgStoreFolder(self, folder_id, props[0][1],
!                                   table.GetRowCount(0))
  
      def GetMessage(self, message_id):
***************
*** 148,156 ****
          message_id = mapi.BinFromHex(message_id)
          prop_ids = PR_PARENT_ENTRYID, PR_CONTENT_UNREAD
!         mapi_object = self.mapi_msgstore.OpenEntry(message_id, None, mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
          hr, data = mapi_object.GetProps(prop_ids,0)
          folder_eid = data[0][1]
          unread = data[1][1]
!         folder = MAPIMsgStoreFolder(self, folder_eid, "Unknown - temp message", -1)
          return  MAPIMsgStoreMsg(self, folder, message_id, unread)
  
--- 184,196 ----
          message_id = mapi.BinFromHex(message_id)
          prop_ids = PR_PARENT_ENTRYID, PR_CONTENT_UNREAD
!         mapi_object = self.mapi_msgstore.OpenEntry(message_id,
!                                                    None,
!                                                    mapi.MAPI_MODIFY |
!                                                        USE_DEFERRED_ERRORS)
          hr, data = mapi_object.GetProps(prop_ids,0)
          folder_eid = data[0][1]
          unread = data[1][1]
!         folder = MAPIMsgStoreFolder(self, folder_eid,
!                                     "Unknown - temp message", -1)
          return  MAPIMsgStoreMsg(self, folder, message_id, unread)
  
***************
*** 180,184 ****
  
      def __repr__(self):
!         return "<%s '%s' (%d items), id=%s>" % (self.__class__.__name__, self.name, self.count, mapi.HexFromBin(self.id))
  
      def GetOutlookEntryID(self):
--- 220,227 ----
  
      def __repr__(self):
!         return "<%s '%s' (%d items), id=%s>" % (self.__class__.__name__,
!                                                 self.name,
!                                                 self.count,
!                                                 mapi.HexFromBin(self.id))
  
      def GetOutlookEntryID(self):
***************
*** 186,200 ****
  
      def GetMessageGenerator(self):
!         folder = self.msgstore.mapi_msgstore.OpenEntry(self.id, None, mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
          table = folder.GetContentsTable(0)
          prop_ids = PR_ENTRYID, PR_CONTENT_UNREAD
          table.SetColumns(prop_ids, 0)
          while 1:
!             # Getting 70 at a time was the random number that gave best perf for me ;)
              rows = table.QueryRows(70, 0)
!             if len(rows)==0:
                  break
              for row in rows:
!                 yield MAPIMsgStoreMsg(self.msgstore, self, row[0][1], row[1][1])
  
  
--- 229,248 ----
  
      def GetMessageGenerator(self):
!         folder = self.msgstore.mapi_msgstore.OpenEntry(self.id,
!                                                        None,
!                                                        mapi.MAPI_MODIFY |
!                                                            USE_DEFERRED_ERRORS)
          table = folder.GetContentsTable(0)
          prop_ids = PR_ENTRYID, PR_CONTENT_UNREAD
          table.SetColumns(prop_ids, 0)
          while 1:
!             # Getting 70 at a time was the random number that gave best
!             # perf for me ;)
              rows = table.QueryRows(70, 0)
!             if len(rows) == 0:
                  break
              for row in rows:
!                 yield MAPIMsgStoreMsg(self.msgstore, self,
!                                       row[0][1], row[1][1])
  
  
***************
*** 213,217 ****
          else:
              urs = "unread"
!         return "<%s, (%s) id=%s>" % (self.__class__.__name__, urs, mapi.HexFromBin(self.id))
  
      def GetOutlookEntryID(self):
--- 261,267 ----
          else:
              urs = "unread"
!         return "<%s, (%s) id=%s>" % (self.__class__.__name__,
!                                      urs,
!                                      mapi.HexFromBin(self.id))
  
      def GetOutlookEntryID(self):
***************
*** 220,228 ****
      def _GetPropFromStream(self, prop_id):
          try:
!             stream = self.mapi_object.OpenProperty(prop_id, pythoncom.IID_IStream, 0, 0)
              chunks = []
              while 1:
                  chunk = stream.Read(1024)
!                 if not chunk: break
                  chunks.append(chunk)
              return "".join(chunks)
--- 270,281 ----
      def _GetPropFromStream(self, prop_id):
          try:
!             stream = self.mapi_object.OpenProperty(prop_id,
!                                                    pythoncom.IID_IStream,
!                                                    0, 0)
              chunks = []
              while 1:
                  chunk = stream.Read(1024)
!                 if not chunk:
!                     break
                  chunks.append(chunk)
              return "".join(chunks)
***************
*** 233,241 ****
      def _GetPotentiallyLargeStringProp(self, prop_id, row):
          got_tag, got_val = row
!         if PROP_TYPE(got_tag)==PT_ERROR:
              ret = ""
!             if got_val==mapi.MAPI_E_NOT_FOUND:
                  pass # No body for this message.
!             elif got_val==mapi.MAPI_E_NOT_ENOUGH_MEMORY:
                  # Too big for simple properties - get via a stream
                  ret = self._GetPropFromStream(prop_id)
--- 286,294 ----
      def _GetPotentiallyLargeStringProp(self, prop_id, row):
          got_tag, got_val = row
!         if PROP_TYPE(got_tag) == PT_ERROR:
              ret = ""
!             if got_val == mapi.MAPI_E_NOT_FOUND:
                  pass # No body for this message.
!             elif got_val == mapi.MAPI_E_NOT_ENOUGH_MEMORY:
                  # Too big for simple properties - get via a stream
                  ret = self._GetPropFromStream(prop_id)
***************
*** 243,247 ****
                  tag_name = mapiutil.GetPropTagName(prop_id)
                  err_string = mapiutil.GetScodeString(got_val)
!                 print "Warning - failed to get property %s: %s" % (tag_name, err_string)
          else:
              ret = got_val
--- 296,301 ----
                  tag_name = mapiutil.GetPropTagName(prop_id)
                  err_string = mapiutil.GetScodeString(got_val)
!                 print "Warning - failed to get property %s: %s" % (tag_name,
!                                                                    err_string)
          else:
              ret = got_val
***************
*** 274,278 ****
      def _EnsureObject(self):
          if self.mapi_object is None:
!             self.mapi_object = self.msgstore.mapi_msgstore.OpenEntry(self.id, None, mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
  
      def GetEmailPackageObject(self, strip_mime_headers=True):
--- 328,335 ----
      def _EnsureObject(self):
          if self.mapi_object is None:
!             self.mapi_object = self.msgstore.mapi_msgstore.OpenEntry(
!                                    self.id,
!                                    None,
!                                    mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
  
      def GetEmailPackageObject(self, strip_mime_headers=True):
***************
*** 324,329 ****
              type_tag = _MapiTypeMap.get(type(val))
              if type_tag is None:
!                 raise ValueError, "Dont know what to do with '%r' ('%s')" % (val, type(val))
!             prop = PROP_TAG( type_tag, PROP_ID(propIds[0]))
          if val is None:
              # Delete the property
--- 381,387 ----
              type_tag = _MapiTypeMap.get(type(val))
              if type_tag is None:
!                 raise ValueError, "Don't know what to do with '%r' ('%s')" % (
!                                      val, type(val))
!             prop = PROP_TAG(type_tag, PROP_ID(propIds[0]))
          if val is None:
              # Delete the property
***************
*** 340,349 ****
      def _DoCopyMode(self, folder, isMove):
  ##        self.mapi_object = None # release the COM pointer
!         assert not self.dirty, "asking me to move a dirty message - later saves will fail!"
!         dest_folder = self.msgstore.mapi_msgstore.OpenEntry(folder.id, None, mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
!         source_folder = self.msgstore.mapi_msgstore.OpenEntry(self.folder.id, None, mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
          flags = 0
          if isMove: flags |= MESSAGE_MOVE
!         source_folder.CopyMessages( (self.id,), None, dest_folder, 0, None, flags)
          self.folder = self.msgstore.GetFolder(mapi.HexFromBin(folder.id))
  
--- 398,419 ----
      def _DoCopyMode(self, folder, isMove):
  ##        self.mapi_object = None # release the COM pointer
!         assert not self.dirty, \
!                "asking me to move a dirty message - later saves will fail!"
!         dest_folder = self.msgstore.mapi_msgstore.OpenEntry(
!                           folder.id,
!                           None,
!                           mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
!         source_folder = self.msgstore.mapi_msgstore.OpenEntry(
!                             self.folder.id,
!                             None,
!                             mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS)
          flags = 0
          if isMove: flags |= MESSAGE_MOVE
!         source_folder.CopyMessages((self.id,),
!                                    None,
!                                    dest_folder,
!                                    0,
!                                    None,
!                                    flags)
          self.folder = self.msgstore.GetFolder(mapi.HexFromBin(folder.id))