[Spambayes-checkins] spambayes imapfilter.py,1.14,1.15

Tim Stone timstone4 at users.sourceforge.net
Thu Apr 17 09:47:25 EDT 2003


Update of /cvsroot/spambayes/spambayes
In directory sc8-pr-cvs1:/tmp/cvs-serv8030

Modified Files:
	imapfilter.py 
Log Message:
1. Corrected newline mangling (I hope), variations of which caused problems
    for Oliver Maunder and probably for David Abrahams (see mailing list)
2. Corrected folder comparison operation
3. Refactored functionality into an IMAPSession class, which results in a
    more consistent IMAP semantic
4. Added -p option to prompt for password, negating the necessity of storing the
    imap password in clear text in Options
5. Corrected error in training, which resulted in no training being performed

Index: imapfilter.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/imapfilter.py,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -d -r1.14 -r1.15
*** imapfilter.py	17 Apr 2003 00:08:17 -0000	1.14
--- imapfilter.py	17 Apr 2003 15:47:20 -0000	1.15
***************
*** 20,23 ****
--- 20,25 ----
              -h          : help
              -v          : verbose mode
+             -p          : security option to prompt for imap password,
+                           rather than look in options.imap_password
              -e y/n      : expunge/purge messages on exit (y) or not (n)
              -i debuglvl : a somewhat mysterious imaplib debugging level
***************
*** 78,81 ****
--- 80,84 ----
  import sys
  import getopt
+ from getpass import getpass
  import email.Parser
  from email.Utils import parsedate
***************
*** 85,88 ****
--- 88,92 ----
  
  # global IMAPlib object
+ global imap
  imap = None
  
***************
*** 98,118 ****
  # nicer if we cached this information somewhere.
  # XXX If we wanted to be nice and tidy, this really belongs
! # XXX in an IMAPUtilities class, or something like that.
! current_folder = None
! current_folder_readonly = None
! def Select(folder, readOnly=True, force=False):
!     global current_folder
!     global current_folder_readonly
!     if current_folder != folder or current_folder_readonly != readOnly or force:
!         response = imap.select(folder, readOnly)
!         if response[0] != "OK":
!             print "Invalid response to %s:\n%s" % (command, response)
!             sys.exit(-1)
!         current_folder = folder
!         current_folder_readonly = readOnly
!         return response
  
  class IMAPMessage(message.SBHeaderMessage):
!     def __init__(self, folder, id):        
          message.Message.__init__(self)
  
--- 102,149 ----
  # nicer if we cached this information somewhere.
  # XXX If we wanted to be nice and tidy, this really belongs
! # XXX in an IMAPUtilities class, or something like that,
! # XXX or something like this:
! 
! class IMAPSession(imaplib.IMAP4):
!     '''A class extending the IMAP4 class, with a few optimizations'''
!     
!     def __init__(self, server, port, debug):
!         imaplib.Debug = debug  # this is a global in the imaplib module
!         imaplib.IMAP4.__init__(self, server, port)
!         self.current_folder = None
!         self.current_folder_readonly = None
! 
!     def login(self, uid, pw):
!         try:
!             imaplib.IMAP4.login(self, uid, pw)  # superclass login
!         except imaplib.IMAP4.error, e:
!             if str(e) == "permission denied":
!                 print "There was an error logging in to the IMAP server."
!                 print "The userid and/or password may be incorrect."
!                 sys.exit()
!             else:
!                 raise
!     
!     def logout(self, expunge):
!         # sign off
!         if expunge:
!             self.expunge()
!         imaplib.IMAP4.logout(self)  # superclass logout
!         
!     def SelectFolder(self, folder, readOnly=True, force=False):
!         '''A method to point ensuing imap operations at a target folder'''
!         
!         if self.current_folder != folder or \
!            self.current_folder_readonly != readOnly or force:
!             response = self.select(folder, readOnly)
!             if response[0] != "OK":
!                 print "Invalid response to %s:\n%s" % (command, response)
!                 sys.exit(-1)
!             self.current_folder = folder
!             self.current_folder_readonly = readOnly
!             return response
  
  class IMAPMessage(message.SBHeaderMessage):
!     def __init__(self, folder, id):
          message.Message.__init__(self)
  
***************
*** 128,141 ****
      def extractTime(self):
          # When we create a new copy of a message, we need to specify
!         # a timestamp for the message.  Ideally, this would be the
!         # timestamp from the message itself, but for the moment, we
!         # just use the current time.
          try:
!             return imaplib.Time2Internaldate(time.mktime(parsedate(self["Date"])))
          except KeyError:
              return imaplib.Time2Internaldate(time.time())
  
      def MoveTo(self, dest):
!         # The move just changes where we think we are,
          # and we do an actual move on save (to avoid doing
          # this more than once)
--- 159,172 ----
      def extractTime(self):
          # When we create a new copy of a message, we need to specify
!         # a timestamp for the message.  If the message has a date header
!         # we use that.  Otherwise, we use the current time.
          try:
!             return imaplib.Time2Internaldate(\
!                        time.mktime(parsedate(self["Date"])))
          except KeyError:
              return imaplib.Time2Internaldate(time.time())
  
      def MoveTo(self, dest):
!         # This move operation just changes where we think we are,
          # and we do an actual move on save (to avoid doing
          # this more than once)
***************
*** 148,160 ****
          # so what we do is create a new message and delete the old one
          time_stamp = self.extractTime()
          response = imap.append(self.folder.name, None,
!                                time_stamp, self.as_string())
          self._check(response, 'append')
  
          old_id = self.id
          if self.previous_folder is None:
!             self.folder.Select(False)
          else:
!             self.previous_folder.Select(False)
              self.previous_folder = None
          response = imap.uid("STORE", old_id, "+FLAGS.SILENT", "(\\Deleted)")
--- 179,193 ----
          # so what we do is create a new message and delete the old one
          time_stamp = self.extractTime()
+         msgstr = re.sub('([^\r])\n', r'\1\r\n', self.as_string())
+         
          response = imap.append(self.folder.name, None,
!                                time_stamp, msgstr)
          self._check(response, 'append')
  
          old_id = self.id
          if self.previous_folder is None:
!             imap.SelectFolder(self.folder.name, False)
          else:
!             imap.SelectFolder(self.previous_folder.name, False)
              self.previous_folder = None
          response = imap.uid("STORE", old_id, "+FLAGS.SILENT", "(\\Deleted)")
***************
*** 165,169 ****
          # XXX changed, as the message to be deleted will be found first
          # XXX (if they are in the same folder)
!         self.folder.Select(True)
          #response = imap.uid("SEARCH", "TEXT", self.as_string())
          #self._check(response, 'search')
--- 198,202 ----
          # XXX changed, as the message to be deleted will be found first
          # XXX (if they are in the same folder)
!         imap.SelectFolder(self.folder.name, True)
          #response = imap.uid("SEARCH", "TEXT", self.as_string())
          #self._check(response, 'search')
***************
*** 184,187 ****
--- 217,224 ----
          self.name = folder_name
  
+     def __cmp__(self, obj):
+         '''Two folders are equal if their names are equal'''
+         return cmp(self.name, obj.name)
+ 
      def _check(self, response, command):
          if response[0] != "OK":
***************
*** 200,204 ****
          '''Returns uids for all the messages in the folder'''
          # request message range
!         response = Select(self.name, True, True)
          total_messages = response[1][0]
          if total_messages == '0':
--- 237,241 ----
          '''Returns uids for all the messages in the folder'''
          # request message range
!         response = imap.SelectFolder(self.name, True, True)
          total_messages = response[1][0]
          if total_messages == '0':
***************
*** 216,220 ****
          '''Return message matching the given uid'''
          global rfc822_command
!         Select(self.name, True)
          # We really want to use RFC822.PEEK here, as that doesn't effect
          # the status of the message.  Unfortunately, it appears that not
--- 253,257 ----
          '''Return message matching the given uid'''
          global rfc822_command
!         imap.SelectFolder(self.name, True)
          # We really want to use RFC822.PEEK here, as that doesn't effect
          # the status of the message.  Unfortunately, it appears that not
***************
*** 233,240 ****
          
          return msg
! 
!     def Select(self, readOnly):
!         return Select(self.name, readOnly)
! 
      def Train(self, classifier, isSpam):
          '''Train folder as spam/ham'''
--- 270,274 ----
          
          return msg
!    
      def Train(self, classifier, isSpam):
          '''Train folder as spam/ham'''
***************
*** 249,253 ****
                  msg.RememberTrained(None)
  
!             if msg.GetTrained() is not None:
                  classifier.learn(msg.asTokens(), isSpam)
                  num_trained += 1
--- 283,287 ----
                  msg.RememberTrained(None)
  
!             if msg.GetTrained() is None:
                  classifier.learn(msg.asTokens(), isSpam)
                  num_trained += 1
***************
*** 276,285 ****
  class IMAPFilter(object):
      def __init__(self, classifier, debug):
-         global imap
-         imap = imaplib.IMAP4(options.imap_server, options.imap_port)
-         imap.debug = imapDebug
- 
-         self.Login(options.imap_username, options.imap_password)
-         
          self.spam_folder = IMAPFolder(options.imap_spam_folder)
          self.unsure_folder = IMAPFolder(options.imap_unsure_folder)
--- 310,313 ----
***************
*** 320,340 ****
          if options.verbose:
              print "Filtering took", time.time() - t, "seconds."
! 
!     def Login(self, uid, pw):
!         try:
!             lgn = imap.login(uid, pw)
!         except imaplib.IMAP4.error, e:
!             if str(e) == "permission denied":
!                 print "There was an error logging in to the IMAP server."
!                 print "The userid and/or password may be incorrect."
!                 sys.exit()
!             else:
!                 raise
!     
!     def Logout(self, expunge):
!         # sign off
!         if expunge:
!             imap.expunge()
!         imap.logout()
  
   
--- 348,352 ----
          if options.verbose:
              print "Filtering took", time.time() - t, "seconds."
!             
  
   
***************
*** 342,346 ****
  
      try:
!         opts, args = getopt.getopt(sys.argv[1:], 'htcvl:e:i:d:D:')
      except getopt.error, msg:
          print >>sys.stderr, str(msg) + '\n\n' + __doc__
--- 354,358 ----
  
      try:
!         opts, args = getopt.getopt(sys.argv[1:], 'htcvpl:e:i:d:D:')
      except getopt.error, msg:
          print >>sys.stderr, str(msg) + '\n\n' + __doc__
***************
*** 354,357 ****
--- 366,370 ----
      imapDebug = 0
      sleepTime = 0
+     promptForPass = 0
  
      for opt, arg in opts:
***************
*** 367,370 ****
--- 380,385 ----
          elif opt == '-t':
              doTrain = True
+         elif opt == '-p':
+             promptForPass = 1
          elif opt == '-c':
              doClassify = True
***************
*** 385,388 ****
--- 400,413 ----
          sys.exit()
  
+     imap = IMAPSession(options.imap_server, options.imap_port, \
+                        imapDebug)
+ 
+     if promptForPass:
+         pwd = getpass()
+     else:
+         pwd = options.imap_password
+ 
+     imap.login(options.imap_username, pwd)
+     
      bdbname = os.path.expanduser(bdbname)
      
***************
*** 415,417 ****
              break
          
!     imap_filter.Logout(doExpunge)
--- 440,442 ----
              break
          
!     imap.logout(doExpunge)





More information about the Spambayes-checkins mailing list