Mailbox cleaner on an IMAP basis?

F. GEIGER fgeiger at datec.at
Tue Sep 23 20:09:41 CEST 2003


Ok, I came up with this so far, many thanks to all who contributed!

Best regards
Franz GEIGER


import os.path, re
from imaplib import *


class Finder:
   def __init__(self, text):
      self._value = None
      results = self._rex.findall(text)
      if results:
         self._value = results[0]
      return

   def value(self):
      return self._value


class UIDfinder(Finder):

   _rex = re.compile(r'UID (\d+)')


class FileNameFinder(Finder):

   _rex = re.compile(r'\("application" ".+?" \("name" "(.+?)"\)')

   def ft(self):
      if not self._value:
         return None

      root, ft = os.path.splitext(self._value)
      return ft


class SenderFinder(Finder):

   _rex = re.compile(r'From\: (.+)\r', re.M | re.I)



class SubjectFinder(Finder):

   _rex = re.compile(r'Subject\: (.+)\r', re.M | re.I)


class DateFinder(Finder):

   _rex = re.compile(r'Date\: (.+)\r', re.M | re.I)


class MessageSummary:
   def __init__(self, uid, fileName, text):
      if not fileName:
         fileName = ''

      self._uid = uid
      self._fileName = fileName

      self._sender = ''
      self._subject = ''
      self._date = ''

      f = SenderFinder(text)
      if f.value():
         self._sender = f.value()

      f = SubjectFinder(text)
      if f.value():
         self._subject = f.value()

      f = DateFinder(text)
      if f.value():
         self._date = f.value()

      return

   def __str__(self):
      return self.formatted()

   def formatted(self):
      return "From      : %s\nSubject   : %s\nAttachment: %s\nFile-Name :
%s" % (self._sender, self._subject, self._date, self._fileName)

   def uid(self):
      return self._uid


class Deleter:
   def __init__(self, server, messageSummaries):
      self._server = server
      self._messageSummaries = messageSummaries
      self._uids = [ms.uid() for ms in self._messageSummaries]
      return

   def run(self):
      uids = ','.join(self._uids)
      r = self._server.uid("STORE", uids, "+FLAGS.SILENT", "(\Deleted)")[0]
      if r in ("OK", "Ok", "ok"):
  return ''
      else:
  return "Error - Could Not Delete Messages"


class Expunger:
   def __init__(self, server):
      self._server = server
      return

   def run(self):
      self._server.expunge()
      return


print "Logging in."
server = IMAP4("<myDomain>")
server.login("<myUserName>", "<myPassword>")
server.select()


print "Begin to cleanup mailbox."
messagesToDelete = []
i = 0
while (1):
   i += 1

   r, d = server.fetch(i, "(UID BODY)")
   if r == 'NO' or d[0] is None:
      break
   uid = UIDfinder(d[0]).value()
   fnf = FileNameFinder(d[0])
   fn = fnf.value()
   if not fn:
      print '.',
      continue

   ft = fnf.ft()

   r, d = server.fetch(i, "(BODY.PEEK[HEADER.FIELDS (Date From Subject)])")

   ms = MessageSummary(uid, fn, d[0][1])

   if ft.lower() == ".exe":
      print '*',
      messagesToDelete.append(ms)
   else:
      print '.',


if messagesToDelete:
   print "\n" * 4
   print "%d messages are tagged to be deleted: " % len(messagesToDelete)
   for ms in messagesToDelete:
      print ms.formatted()
      print
   print
   if raw_input("Shall I delete them now (y/n)? ") == 'y':
      print 'Working...'
      d = Deleter(server, messagesToDelete)
      d.run()
      e = Expunger(server)
      e.run()
      print "Done. "
else:
   print
   print "No messages to delete. "


raw_input("Press any key to exit...")




"Donn Cave" <donn at drizzle.com> schrieb im Newsbeitrag
news:1064298380.225028 at yasure...
> Quoth "F. GEIGER" <fgeiger at datec.at>:
>
> | I've stopped here, because I could not figure out how to get at the ids
of
> | mails with attachments. And if I had that missing link, I'd run into the
> | next hindrance: How can I delete a single message? IMAP4::delete()
deletes a
> | whole mailbox, not just a single mail.
> |
> | So my code really is only a few lines so far:
> |
> | i = IMAP4(myDomain)
> | i.login(myUser, myPassword)
> | i.select() # Select INBOX
> | r, d = i.fetch(1, "(BODY.PEEK[HEADER.FIELDS])") # Check 1st mail
> |
> | Seems I have to get a book about IMAP and how to use it...
>
> The IMAP4rev1 RFC of course covers these things, with examples.
> 2060, I think it is.  A message takes two steps to delete:  first,
> set a \Deleted flag on it, and then invoke expunge on the folder,
> which will remove all delete-flagged messages in the folder.
>
> Donn Cave, donn at drizzle.com






More information about the Python-list mailing list