[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 ----