[Spambayes-checkins] spambayes/Outlook2000 addin.py,1.21,1.22 manager.py,1.28,1.29 msgstore.py,1.14,1.15

Mark Hammond mhammond@users.sourceforge.net
Fri Nov 1 05:48:01 2002


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

Modified Files:
	addin.py manager.py msgstore.py 
Log Message:
All items are now identified by a (store_id, entry_id) tuple.  This was
done in such a way that old config files should be fully supported - no
need to reconfigure.

Not much should look different, except mutiple stores should be *fully*
supported - you should be able to train and filter across stores to your
hearts content.


Index: addin.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/Outlook2000/addin.py,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -d -r1.21 -r1.22
*** addin.py	1 Nov 2002 02:03:39 -0000	1.21
--- addin.py	1 Nov 2002 05:47:59 -0000	1.22
***************
*** 308,312 ****
              existing = self.folder_hooks.get(eid)
              if existing is None or existing.__class__ != HandlerClass:
!                 folder = self.application.Session.GetFolderFromID(eid)
                  name = folder.Name.encode("mbcs", "replace")
                  try:
--- 308,312 ----
              existing = self.folder_hooks.get(eid)
              if existing is None or existing.__class__ != HandlerClass:
!                 folder = self.application.Session.GetFolderFromID(*eid)
                  name = folder.Name.encode("mbcs", "replace")
                  try:

Index: manager.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/Outlook2000/manager.py,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** manager.py	1 Nov 2002 02:03:43 -0000	1.28
--- manager.py	1 Nov 2002 05:47:59 -0000	1.29
***************
*** 92,96 ****
          assert self.outlook is not None, "I need outlook :("
          ol = self.outlook
!         folder = ol.Session.GetFolderFromID(folder_id)
          if self.verbose > 1:
              print "Checking folder '%s' for our field '%s'" \
--- 92,96 ----
          assert self.outlook is not None, "I need outlook :("
          ol = self.outlook
!         folder = ol.Session.GetFolderFromID(*folder_id)
          if self.verbose > 1:
              print "Checking folder '%s' for our field '%s'" \

Index: msgstore.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/Outlook2000/msgstore.py,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** msgstore.py	1 Nov 2002 02:03:45 -0000	1.14
--- msgstore.py	1 Nov 2002 05:47:59 -0000	1.15
***************
*** 91,123 ****
                        mapi.MAPI_USE_DEFAULT)
          self.session = mapi.MAPILogonEx(0, None, None, logonFlags)
!         self._FindDefaultMessageStore()
          os.chdir(cwd)
  
      def Close(self):
!         self.mapi_msgstore = None
          self.session.Logoff(0, 0, 0)
          self.session = None
          mapi.MAPIUninitialize()
  
!     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
--- 91,135 ----
                        mapi.MAPI_USE_DEFAULT)
          self.session = mapi.MAPILogonEx(0, None, None, logonFlags)
!         self.mapi_msg_stores = {}
!         self.default_store_bin_eid = None
!         self._GetMessageStore(None)
          os.chdir(cwd)
  
      def Close(self):
!         self.mapi_msg_stores = None
          self.session.Logoff(0, 0, 0)
          self.session = None
          mapi.MAPIUninitialize()
  
!     def _GetMessageStore(self, store_eid): # bin eid.
!         try:
!             # Will usually be pre-fetched, so fast-path out
!             return self.mapi_msg_stores[store_eid]
!         except KeyError:
!             pass
!         given_store_eid = store_eid
!         if store_eid is None:
!             # Find the EID for the default store.
!             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, store_eid = row[0]
!             self.default_store_bin_eid = store_eid
! 
!         # Open it.
!         store = self.session.OpenMsgStore(
                                  0,      # no parent window
!                                 store_eid,    # msg store to open
                                  None,   # IID; accept default IMsgStore
                                  # need write access to add score fields
***************
*** 126,158 ****
                                      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
  
      def GetFolderGenerator(self, folder_ids, include_sub):
          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)
--- 138,191 ----
                                      mapi.MDB_NO_MAIL |
                                      USE_DEFERRED_ERRORS)
+         # cache it
+         self.mapi_msg_stores[store_eid] = store
+         if given_store_eid is None: # The default store
+             self.mapi_msg_stores[None] = store
+         return store
+ 
+     def _OpenEntry(self, id, iid = None, flags = None):
+         # id is already normalized.
+         store_id, item_id = id
+         store = self._GetMessageStore(store_id)
+         if flags is None:
+             flags = mapi.MAPI_MODIFY | USE_DEFERRED_ERRORS
+         return store.OpenEntry(item_id, iid, flags)
+ 
+     # Given an ID, normalize it into a (store_id, item_id) binary tuple.
+     # item_id may be:
+     # - Simple hex EID, in wich case default store ID is assumed.
+     # - Tuple of (None, hex_eid), in which case default store assumed.
+     # - Tuple of (hex_store_id, hex_id)
+     def NormalizeID(self, item_id):
+         if type(item_id)==type(()):
+             store_id, item_id = item_id
+             item_id = mapi.BinFromHex(item_id)
+             if store_id is None:
+                 store_id = self.default_store_bin_eid
+             else:
+                 store_id = mapi.BinFromHex(store_id)
+             return store_id, item_id
+         assert type(item_id) in [type(''), type(u'')], "What kind of ID is '%r'?" % (item_id,)
+         return self.default_store_bin_eid, mapi.BinFromHex(item_id)
  
      def _GetSubFolderIter(self, folder):
          table = folder.GetHierarchyTable(0)
          rows = mapi.HrQueryAllRows(table,
!                                    (PR_ENTRYID, PR_STORE_ENTRYID, PR_DISPLAY_NAME_A),
                                     None,
                                     None,
                                     0)
!         for (eid_tag, eid), (store_eid_tag, store_eid), (name_tag, name) in rows:
!             item_id = store_eid, eid
!             sub = self._OpenEntry(item_id)
              table = sub.GetContentsTable(0)
!             yield MAPIMsgStoreFolder(self, item_id, name, table.GetRowCount(0))
!             for store_folder in self._GetSubFolderIter(sub):
                  yield store_folder
  
      def GetFolderGenerator(self, folder_ids, include_sub):
          for folder_id in folder_ids:
!             folder_id = self.NormalizeID(folder_id)
!             folder = self._OpenEntry(folder_id)
              table = folder.GetContentsTable(0)
              rc, props = folder.GetProps( (PR_DISPLAY_NAME_A,), 0)
***************
*** 165,173 ****
      def GetFolder(self, folder_id):
          # 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)
--- 198,203 ----
      def GetFolder(self, folder_id):
          # Return a single folder given the ID.
!         folder_id = self.NormalizeID(folder_id)
!         folder = self._OpenEntry(folder_id)
          table = folder.GetContentsTable(0)
          rc, props = folder.GetProps( (PR_DISPLAY_NAME_A,), 0)
***************
*** 177,191 ****
      def GetMessage(self, message_id):
          # Return a single message given the ID.
!         message_id = mapi.BinFromHex(message_id)
          prop_ids = PR_PARENT_ENTRYID, PR_SEARCH_KEY, 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]
          searchkey = data[1][1]
          unread = data[2][1]
!         folder = MAPIMsgStoreFolder(self, folder_eid,
                                      "Unknown - temp message", -1)
          return  MAPIMsgStoreMsg(self, folder, message_id, searchkey, unread)
--- 207,219 ----
      def GetMessage(self, message_id):
          # Return a single message given the ID.
!         message_id = self.NormalizeID(message_id)
          prop_ids = PR_PARENT_ENTRYID, PR_SEARCH_KEY, PR_CONTENT_UNREAD
!         mapi_object = self._OpenEntry(message_id)
          hr, data = mapi_object.GetProps(prop_ids,0)
          folder_eid = data[0][1]
          searchkey = data[1][1]
          unread = data[2][1]
!         folder_id = message_id[0], folder_eid
!         folder = MAPIMsgStoreFolder(self, folder_id,
                                      "Unknown - temp message", -1)
          return  MAPIMsgStoreMsg(self, folder, message_id, searchkey, unread)
***************
*** 216,232 ****
  
      def __repr__(self):
!         return "<%s '%s' (%d items), id=%s>" % (self.__class__.__name__,
                                                  self.name,
                                                  self.count,
!                                                 mapi.HexFromBin(self.id))
  
      def GetOutlookEntryID(self):
!         return mapi.HexFromBin(self.id)
  
      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_SEARCH_KEY, PR_CONTENT_UNREAD
--- 244,263 ----
  
      def __repr__(self):
!         return "<%s '%s' (%d items), id=%s/%s>" % (self.__class__.__name__,
                                                  self.name,
                                                  self.count,
!                                                 mapi.HexFromBin(self.id[0]),
!                                                 mapi.HexFromBin(self.id[1]))
  
      def GetOutlookEntryID(self):
!         # Return EntryID, StoreID - we use this order as it is the same as
!         # Session.GetItemFromID() uses - thus:
!         # ids = me.GetOutlookEntryID()
!         # session.GetItemFromID(*ids)
!         # should work.
!         return mapi.HexFromBin(self.id[1]), mapi.HexFromBin(self.id[0])
  
      def GetMessageGenerator(self):
!         folder = self.msgstore._OpenEntry(self.id)
          table = folder.GetContentsTable(0)
          prop_ids = PR_ENTRYID, PR_SEARCH_KEY, PR_CONTENT_UNREAD
***************
*** 239,244 ****
                  break
              for row in rows:
                  yield MAPIMsgStoreMsg(self.msgstore, self,
!                                       row[0][1], row[1][1], row[2][1])
  
  
--- 270,276 ----
                  break
              for row in rows:
+                 item_id = self.id[0], row[0][1] # assume in same store as folder!
                  yield MAPIMsgStoreMsg(self.msgstore, self,
!                                       item_id, row[1][1], row[2][1])
  
  
***************
*** 263,272 ****
          else:
              urs = "unread"
!         return "<%s, (%s) id=%s>" % (self.__class__.__name__,
                                       urs,
!                                      mapi.HexFromBin(self.id))
  
      def GetOutlookEntryID(self):
!         return mapi.HexFromBin(self.id)
  
      def _GetPropFromStream(self, prop_id):
--- 295,310 ----
          else:
              urs = "unread"
!         return "<%s, (%s) id=%s/%s>" % (self.__class__.__name__,
                                       urs,
!                                      mapi.HexFromBin(self.id[0]),
!                                      mapi.HexFromBin(self.id[1]))
  
      def GetOutlookEntryID(self):
!         # Return EntryID, StoreID - we use this order as it is the same as
!         # Session.GetItemFromID() uses - thus:
!         # ids = me.GetOutlookEntryID()
!         # session.GetItemFromID(*ids)
!         # should work.
!         return mapi.HexFromBin(self.id[1]), mapi.HexFromBin(self.id[0])
  
      def _GetPropFromStream(self, prop_id):
***************
*** 319,326 ****
      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):
--- 357,361 ----
      def _EnsureObject(self):
          if self.mapi_object is None:
!             self.mapi_object = self.msgstore._OpenEntry(self.id)
  
      def GetEmailPackageObject(self, strip_mime_headers=True):
***************
*** 418,432 ****
          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,
--- 453,462 ----
          assert not self.dirty, \
                 "asking me to move a dirty message - later saves will fail!"
!         dest_folder = self.msgstore._OpenEntry(folder.id)
!         source_folder = self.msgstore._OpenEntry(self.folder.id)
          flags = 0
          if isMove: flags |= MESSAGE_MOVE
!         eid = self.id[1]
!         source_folder.CopyMessages((eid,),
                                     None,
                                     dest_folder,
***************
*** 434,438 ****
                                     None,
                                     flags)
!         self.folder = self.msgstore.GetFolder(mapi.HexFromBin(folder.id))
  
      def MoveTo(self, folder):
--- 464,473 ----
                                     None,
                                     flags)
!         # At this stage, I think we have lost meaningful ID etc values
!         # Set everything to None to make it clearer what is wrong should
!         # this become an issue.  We would need to re-fetch the eid of
!         # the item, and set the store_id to the dest folder.
!         self.id = None
!         self.folder = None
  
      def MoveTo(self, folder):
***************
*** 453,457 ****
              print msg
      store.Close()
- 
  
  if __name__=='__main__':
--- 488,491 ----