[Spambayes-checkins] spambayes/spambayes message.py,1.69,1.70

Tony Meyer anadelonbrin at users.sourceforge.net
Tue Nov 15 01:36:02 CET 2005


Update of /cvsroot/spambayes/spambayes/spambayes
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8563/spambayes

Modified Files:
	message.py 
Log Message:
Add ZODB version for messageinfo class.

Fix up the messed up messageinfo db property of a message business.

Make it a bit easier to subclass SBHeaderMessage to add more headers.

Fix a bug with adding the exception header.

Index: message.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/spambayes/message.py,v
retrieving revision 1.69
retrieving revision 1.70
diff -C2 -d -r1.69 -r1.70
*** message.py	3 Jun 2005 03:34:42 -0000	1.69
--- message.py	15 Nov 2005 00:35:57 -0000	1.70
***************
*** 6,10 ****
      Message - an email.Message.Message, extended with spambayes methods
      SBHeaderMessage - A Message with spambayes header manipulations
!     MessageInfoDB - persistent state storage for Message
  
  Abstract:
--- 6,12 ----
      Message - an email.Message.Message, extended with spambayes methods
      SBHeaderMessage - A Message with spambayes header manipulations
!     MessageInfoDB - persistent state storage for Message, using dbm
!     MessageInfoZODB - persistent state storage for Message, using ZODB
!     MessageInfoPickle - persistent state storage for Message, using pickle
  
  Abstract:
***************
*** 119,123 ****
  
  class MessageInfoBase(object):
!     def __init__(self, db_name):
          self.db_name = db_name
  
--- 121,125 ----
  
  class MessageInfoBase(object):
!     def __init__(self, db_name=None):
          self.db_name = db_name
  
***************
*** 135,148 ****
          self.store()
  
      def load_msg(self, msg):
          if self.db is not None:
              try:
                  try:
!                     attributes = self.db[msg.getDBKey()]
                  except pickle.UnpicklingError:
                      # The old-style Outlook message info db didn't use
                      # shelve, so get it straight from the dbm.
                      if hasattr(self, "dbm"):
!                         attributes = self.dbm[msg.getDBKey()]
                      else:
                          raise
--- 137,158 ----
          self.store()
  
+     def __getstate__(self):
+         return self.db
+ 
+     def __setstate__(self, state):
+         self.db = state
+ 
      def load_msg(self, msg):
          if self.db is not None:
+             key = msg.getDBKey()
+             assert key is not None, "None is not a valid key."
              try:
                  try:
!                     attributes = self.db[key]
                  except pickle.UnpicklingError:
                      # The old-style Outlook message info db didn't use
                      # shelve, so get it straight from the dbm.
                      if hasattr(self, "dbm"):
!                         attributes = self.dbm[key]
                      else:
                          raise
***************
*** 179,183 ****
              for att in msg.stored_attributes:
                  attributes.append((att, getattr(msg, att)))
!             self.db[msg.getDBKey()] = attributes
              self.store()
  
--- 189,195 ----
              for att in msg.stored_attributes:
                  attributes.append((att, getattr(msg, att)))
!             key = msg.getDBKey()
!             assert key is not None, "None is not a valid key."
!             self.db[key] = attributes
              self.store()
  
***************
*** 247,250 ****
--- 259,288 ----
              self.db.sync()
  
+ # If ZODB isn't available, then this class won't be useable, but we
+ # still need to be able to import this module.  So we pretend that all
+ # is ok.
+ try:
+     from persistent import Persistent
+ except ImportError:
+     Persistent = object
+ class _PersistentMessageInfo(MessageInfoBase, Persistent):
+     def __init__(self):
+         import ZODB
+         from BTrees.OOBTree import OOBTree
+ 
+         MessageInfoBase.__init__(self)
+         self.db = OOBTree()
+ 
+ class MessageInfoZODB(storage.ZODBClassifier):
+     ClassifierClass = _PersistentMessageInfo
+     def __init__(self, db_name):
+         self.nham = self.nspam = 0 # Only used for debugging prints
+         storage.ZODBClassifier.__init__(self, db_name)
+         self.classifier.store = self.store
+     def __setattr__(self, att, value):
+         # Override ZODBClassifier.__setattr__
+         object.__setattr__(self, att, value)
+ 
+ 
  # values are classifier class, True if it accepts a mode
  # arg, and True if the argument is a pathname
***************
*** 254,258 ****
  ##                  "mysql" : (MessageInfoMySQL, False, False),
  ##                  "cdb" : (MessageInfoCDB, False, True),
! ##                  "zodb" : (MessageInfoZODB, False, True),
  ##                  "zeo" : (MessageInfoZEO, False, False),
                    }
--- 292,296 ----
  ##                  "mysql" : (MessageInfoMySQL, False, False),
  ##                  "cdb" : (MessageInfoCDB, False, True),
!                   "zodb" : (MessageInfoZODB, False, True),
  ##                  "zeo" : (MessageInfoZEO, False, False),
                    }
***************
*** 280,296 ****
  
  
! class Message(email.Message.Message):
      '''An email.Message.Message extended for SpamBayes'''
  
!     def __init__(self, id=None, message_info_db=None):
          email.Message.Message.__init__(self)
  
          # persistent state
          # (non-persistent state includes all of email.Message.Message state)
-         if message_info_db is not None:
-             self.message_info_db = message_info_db
-         else:
-             nm, typ = database_type()
-             self.message_info_db = open_storage(nm, typ)
          self.stored_attributes = ['c', 't', 'date_modified', ]
          self.getDBKey = self.getId
--- 318,329 ----
  
  
! class Message(object, email.Message.Message):
      '''An email.Message.Message extended for SpamBayes'''
  
!     def __init__(self, id=None):
          email.Message.Message.__init__(self)
  
          # persistent state
          # (non-persistent state includes all of email.Message.Message state)
          self.stored_attributes = ['c', 't', 'date_modified', ]
          self.getDBKey = self.getId
***************
*** 303,306 ****
--- 336,363 ----
              self.setId(id)
  
+     # This whole message info database thing is a real mess.  It really
+     # ought to be a property of the Message class, not each instance.
+     # So we want to access it via classmethods.  However, we have treated
+     # it as a regular attribute, so need to make it a property.  To make
+     # a classmethod property, we have to jump through some hoops, which we
+     # deserver for not doing it right in the first place.
+     _message_info_db = None
+     def _get_class_message_info_db(klass):
+         # If, the first time we access the attribute, it hasn't been
+         # set, then we load up the default one.
+         if klass._message_info_db is None:
+             nm, typ = database_type()
+             klass._message_info_db = open_storage(nm, typ)
+         return klass._message_info_db
+     _get_class_message_info_db = classmethod(_get_class_message_info_db)
+     def _set_class_message_info_db(klass, value):
+         klass._message_info_db = value
+     _set_class_message_info_db = classmethod(_set_class_message_info_db)
+     def _get_message_info_db(self):
+         return self._get_class_message_info_db()
+     def _set_message_info_db(self, value):
+         self._set_class_message_info_db(value)
+     message_info_db = property(_get_message_info_db, _set_message_info_db)
+ 
      # This function (and it's hackishness) can be avoided by using
      # email.message_from_string(text, _class=SBHeaderMessage)
***************
*** 332,336 ****
      def setId(self, id):
          if self.id and self.id != id:
!             raise ValueError, "MsgId has already been set, cannot be changed"
  
          if id is None:
--- 389,393 ----
      def setId(self, id):
          if self.id and self.id != id:
!             raise ValueError, "MsgId has already been set, cannot be changed" + `self.id` + `id`
  
          if id is None:
***************
*** 440,447 ****
          return self.id
  
!     def addSBHeaders(self, prob, clues):
!         """Add hammie header, and remember message's classification.  Also,
!         add optional headers if needed."""
! 
          if prob < options['Categorization','ham_cutoff']:
              disposition = options['Headers','header_ham_string']
--- 497,501 ----
          return self.id
  
!     def setDisposition(self, prob):
          if prob < options['Categorization','ham_cutoff']:
              disposition = options['Headers','header_ham_string']
***************
*** 451,454 ****
--- 505,514 ----
              disposition = options['Headers','header_unsure_string']
          self.RememberClassification(disposition)
+ 
+     def addSBHeaders(self, prob, clues):
+         """Add hammie header, and remember message's classification.  Also,
+         add optional headers if needed."""
+         self.setDisposition(prob)
+         disposition = self.GetClassification()
          self[options['Headers','classification_header_name']] = disposition
  
***************
*** 479,483 ****
                          word = email.Header.Header(word,
                                                     charset='utf-8').encode()
!                     evd.append("%r: %.2f" % (word, score))
  
              # Line-wrap this header, because it can get very long.  We don't
--- 539,546 ----
                          word = email.Header.Header(word,
                                                     charset='utf-8').encode()
!                     try:
!                         evd.append("%r: %.2f" % (word, score))
!                     except TypeError:
!                         evd.append("%r: %s" % (word, score))
  
              # Line-wrap this header, because it can get very long.  We don't
***************
*** 646,648 ****
          headers += "%s: %s\r\n" % \
                     (options["Headers", "mailid_header_name"], msg_id)
!     return (headers + body, details)
--- 709,711 ----
          headers += "%s: %s\r\n" % \
                     (options["Headers", "mailid_header_name"], msg_id)
!     return (headers + '\r\n' + body, details)



More information about the Spambayes-checkins mailing list