aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatěj Cepl <mcepl@cepl.eu>2018-04-18 22:50:13 +0200
committerMatěj Cepl <mcepl@cepl.eu>2018-04-18 22:50:13 +0200
commit49e281c01b2966609b713fb4a2deda94666fed40 (patch)
treec63b47f06314b467fc98a2b7df1f80ba71a979a0
parent532b4cc2226335d049d1345557b9038d961407e7 (diff)
downloadimapArch-49e281c01b2966609b713fb4a2deda94666fed40.tar.gz
Reorganize files again
-rw-r--r--imapArchive.py205
-rw-r--r--purgeObsolete.py151
-rw-r--r--test/__init__.py0
-rw-r--r--test/test_purge_obsolete.py43
4 files changed, 399 insertions, 0 deletions
diff --git a/imapArchive.py b/imapArchive.py
new file mode 100644
index 0000000..f965c95
--- /dev/null
+++ b/imapArchive.py
@@ -0,0 +1,205 @@
+# -*- coding: utf-8 -*-
+# note http://docs.python.org/lib/module-doctest.html
+# resp. file:///usr/share/doc/python-docs-*/html/lib/module-doctest.html
+# for testing
+from __future__ import division
+from java.util import Properties, Date
+from java.lang import System
+from javax.mail import *
+from jarray import array
+import sys, os
+from datetime import date
+from ConfigParser import ConfigParser
+
+debug=False
+
+def __getMessageDate(msg):
+ """
+ Return the date of the message
+
+ @param msg analyzed message
+ @return GregorianCalendar of the messages date
+ @throws MessagingException
+ """
+ dateMS = msg.getReceivedDate().getTime()//1000
+ dateStruct = date.fromtimestamp(dateMS)
+ return dateStruct
+
+class ArchivableFolder(list):
+ def __init__(self,source,year):
+ """
+ Constructor for the folder.
+
+ @param source folder from the messages should be archived
+ @param year int of the year for which the messages are
+ archived
+ """
+ self.sourceFolder = source
+ targetName = self.__getArchiveFolderName(source.getFullName(), year)
+ self.targetFolder = self.sourceFolder.getFolder(targetName)
+
+ def __getArchiveFolderName(self,srcFldName,year):
+ """
+ @param folder string with the folder name
+ @param year int
+ @return
+ """
+ archFolder = "INBOX/Archiv/"
+ rootLen = len("INBOX/")
+ if not(srcFldName[:rootLen]=="/INBOX/"):
+ raise FolderNotFoundException(\
+ "We expect all folders to be under INBOX folder.")
+ baseName = srcFldName[rootLen:]
+ archFolder = "/" + archFolder + year + "/" + baseName
+ return archFolder
+
+ def add(self,msg):
+ self.append(msg)
+
+ def doArchive(self):
+ if debug:
+ for message in self:
+ print >>sys.stderr, "Moving %s from %s to %s." \
+ % (message,self.sourceFolder.getFullName(),
+ self.targetFolder.getFullName())
+ else:
+ self.sourceFolder.copyMessages(array(self,Message),\
+ self.targetFolder)
+ for message in self:
+ message.setFlag(Flags.Flag.DELETED, true)
+ self.sourceFolder.expunge()
+
+class Archives(dict):
+ """Collects archivable folders indexed by tuple of
+ folderName and year
+ """
+ def __init__(self):
+ pass
+
+ def add(self,msg):
+ """
+ Check whether the ArchivableFolder (@see ArchivableFolder)
+ for the particular year actually exists, and if not then create
+ it. In any event add
+ @param msg
+ """
+ fld = msg.getFolder()
+ msgDate = __getMessageDate(msg)
+ year = msgDate.year
+
+ if not(self.search(fld, year)):
+ archfld = ArchivableFolder(fld,year)
+ self[self.__createKey(fld,year)] = archfld
+
+ def __createKey(self,name,year):
+ """
+ Create a key for the list
+ @param fldName String with the full name of the folder
+ @param year int of the year of the messages to be stored
+ there
+ @return tuple consisting from the both parameters of
+ this function.
+ """
+ return(name,year)
+
+ def search(self,fld,year):
+ """
+ Find out whether the object with the key consisting of
+ the folder name and year exists in this object.
+
+ @param fld Folder where the message is stored
+ @param year int year of the message date
+ @return boolean saying whether the folder for this message
+ has been already added to this object.
+ """
+ key = self.__createKey(fld.getFullName(), year)
+ return self.has_key(key)
+
+ def archive(self):
+ for key in self:
+ self.doArchive()
+
+class ArchivedStore(object):
+ def __init__(self,paramServer="localhost",paramUser="",paramPassword=""):
+ self.props = System.getProperties()
+ self.session = Session.getInstance(self.props,None)
+ self.props.setProperty("javax.net.ssl.keyStore", "/home/matej/.keystore")
+ self.props.setProperty("javax.net.ssl.trustStore", "/home/matej/.keystore")
+ if debug:
+ self.session.setDebug(True)
+ try:
+ self.store = self.session.getStore("imaps")
+ except:
+ print >> sys.stderr, "Cannot get Store"
+ raise
+
+ self._threeMonthAgo = date.today()
+ newmonth = self._threeMonthAgo.month-3
+ self._threeMonthAgo = self._threeMonthAgo.replace(month=newmonth)
+
+ conffile = os.path.expanduser("~/.bugzillarc")
+ confUser = ConfigParser()
+ defSection = "localhost"
+ user,host,port,password = self.props.getProperty("user.name"),\
+ "localhost",993,""
+ if confUser.read(conffile):
+ if confUser.has_section(defSection):
+ if confUser.has_option(defSection, "name"):
+ user = confUser.get(defSection, "name")
+ if confUser.has_option(defSection, "host"):
+ host = confUser.get(defSection, "host")
+ if confUser.has_option(defSection, "port"):
+ port = confUser.get(defSection, "port")
+ if confUser.has_option(defSection, "password"):
+ password = confUser.get(defSection, "password")
+
+ if paramServer:
+ host=paramServer
+ if paramUser:
+ user=paramUser
+ if paramPassword:
+ password=paramPassword
+
+ print >>sys.stderr,"host = %s, user = %s, password = %s" % \
+ (host,user,password)
+
+ self.__login(host,user,password)
+
+ def __login(self,server,user,password):
+ try:
+ self.store.connect(server,user,password)
+ except:
+ print >> sys.stderr, "Cannot connect to %s as %s with password %s" %\
+ (server,user,password)
+ raise
+
+ def archive(self):
+ inboxfolder = self.store.getDefaultFolder().getFolder("INBOX")
+ folderList=inboxfolder.list('*')
+
+ for folder in folderList:
+ if folder.getFullName()[:len("INBOX/Archiv")] != "INBOX/Archiv":
+ archMsgsCnt = self.__archiveFolder(folder)
+ #folder.close(False)
+ print "Processed messages = %d" % archMsgsCnt
+
+ def __archiveFolder(self,fld):
+ fld.open(Folder.READ_WRITE)
+ for msg in fld.getMessages():
+ msgDate = __getMessageDate(msg)
+ print >>sys.stderr,str(msgDate),str(self._threeMonthAgo)
+ if msgDate < self._threeMonthAgo:
+ archFolder = self.__getArchiveFolderName(msg)
+# print >> sys.stderr, archFolder
+# fld.copyMessages(array([msg],type(msg)), archFolder)
+# msg.setFlag(Flags.Flag.DELETED, true)
+ print "%s -> %s : %s" % (fld.getFullName(),
+ archFolder.getFullName(),msgDate)
+ folderLen = len(fld.getMessages())
+ fld.close(False)
+ return(folderLen)
+
+if __name__=='__main__':
+ myStore = ArchivedStore(paramPassword="lubdkc")
+ myStore.archive()
+ myStore.store.close() \ No newline at end of file
diff --git a/purgeObsolete.py b/purgeObsolete.py
new file mode 100644
index 0000000..4491eec
--- /dev/null
+++ b/purgeObsolete.py
@@ -0,0 +1,151 @@
+# -*- coding: utf-8 -*-
+# note http://docs.python.org/lib/module-doctest.html
+# resp. file:///usr/share/doc/python-docs-*/html/lib/module-doctest.html
+# for testing
+from __future__ import division
+from java.util import Properties, Date, GregorianCalendar, Locale
+from java.text import SimpleDateFormat
+from java.lang import System
+from javax.mail import *
+from javax.mail.search import *
+from com.sun.mail.imap import IMAPFolder, IMAPSSLStore
+from jarray import array
+import sys, os
+from datetime import date
+import ConfigParser
+
+debug=False
+
+class SimpleDate(GregorianCalendar):
+ def __init__(self):
+ pass
+
+ def getDate():
+ return self.getTime()
+
+ def decrease(self,howMuch,unit="m"):
+ pass
+
+ def getMessageDate(msg):
+ """
+ Return the date of the message
+
+ @param msg analyzed message
+ @return GregorianCalendar of the messages date
+ @throws MessagingException
+ """
+ dateMS = msg.getReceivedDate().getTime()//1000
+ dateStruct = date.fromtimestamp(dateMS)
+ return dateStruct
+
+class ArchivedFolder(object):
+ def __init__(self,store,name):
+ self.folder = store.store.getDefaultFolder().getFolder(name)
+ self.folder.open(Folder.READ_WRITE)
+
+ def purgeOld(self,dateLimit):
+ toBeDeleted = []
+ for msg in self.folder.getMessages():
+ flags = msg.getFlags()
+ if (__getMessageDate(msg) < dateLimit) and (flags.contains(Flags.Flag.SEEN)):
+ toBeDeleted.append(msg)
+ self.folder.setFlags(toBeDeleted,Flags.Flag.DELETED, true)
+ self.folder.expunge()
+
+class ArchivedStore(object):
+ """
+ >>> myStore = ArchivedStore(paramServer="zimbra")
+ >>> folderList = myStore.store.getDefaultFolder().list("*")
+ >>> len(folderList)>0
+ 1
+ >>> myStore.store.close()
+
+ and
+ >>> myStore = ArchivedStore(paramServer="zimbra")
+ >>> folder = ArchivedFolder(myStore,"INBOX/bugzilla/xgl")
+ >>> folder.folder.getMessageCount() > 0
+ 1
+ >>> myStore.store.close()
+
+ """
+ def __init__(self,paramServer="localhost",paramUser="",paramPassword="",maxageMonth=3):
+ self.props = System.getProperties()
+ self.session = Session.getInstance(self.props,None)
+ self.props.setProperty("javax.net.ssl.keyStore", "/home/matej/.keystore")
+ self.props.setProperty("javax.net.ssl.trustStore", "/home/matej/.keystore")
+ if debug:
+ self.session.setDebug(True)
+ try:
+ self.store = self.session.getStore("imaps")
+ except:
+ print >> sys.stderr, "Cannot get Store"
+ raise
+
+ conffile = os.path.expanduser("~/.bugzillarc")
+ if paramServer:
+ config = ConfigParser.ConfigParser()
+ config.read([conffile])
+ user,host,port,password = self.props.getProperty("user.name"),\
+ "localhost",993,""
+
+ if config:
+ if config.has_section(paramServer):
+ if config.has_option(paramServer, "name"):
+ user = config.get(paramServer, "name")
+ if config.has_option(paramServer, "host"):
+ host = config.get(paramServer, "host")
+ if config.has_option(paramServer, "port"):
+ port = config.get(paramServer, "port")
+ if config.has_option(paramServer, "password"):
+ password = config.get(paramServer, "password")
+
+ if paramUser:
+ user=paramUser
+ if paramPassword:
+ password=paramPassword
+
+ if debug:
+ print >>sys.stderr,"host = %s, user = %s, password = %s" % \
+ (host,user,password)
+
+ self.__login(host,user,password)
+
+ def __login(self,server,user,password):
+ try:
+ self.store.connect(server,user,password)
+ except:
+ print >> sys.stderr, "Cannot connect to %s as %s with password %s" %\
+ (server,user,password)
+ raise
+
+def main():
+ """
+ >>> threeMonthAgo = date.today()
+ >>> JD3MAgo = GregorianCalendar(threeMonthAgo.year,
+ threeMonthAgo.month-1,
+ threeMonthAgo.day,0,0)
+ >>> formatter = SimpleDateFormat("yyyy-MM-dd",Locale.US);
+ >>> JD3MAgoStr = formatter.format(JD3MAgo.getTime())
+ >>> str(threeMonthAgo)==JD3MAgoStr
+ 1
+ """
+ threeMonthAgo = date.today()
+ newmonth = threeMonthAgo.month-3
+ threeMonthAgo = threeMonthAgo.replace(month=newmonth)
+ JD3MAgo = GregorianCalendar(threeMonthAgo.year,
+ threeMonthAgo.month-1,
+ threeMonthAgo.day,0,0).getTime()
+
+ myStore = ArchivedStore(paramServer="zimbra")
+ folder = ArchivedFolder(myStore,"INBOX/bugzilla/xgl")
+
+ unreadTerm = FlagTerm(Flags(Flags.Flag.SEEN),True)
+ dateTerm = ReceivedDateTerm(ComparisonTerm.LT,JD3MAgo)
+ searchTerm = AndTerm(unreadTerm,dateTerm)
+ msgsFound = folder.folder.search(searchTerm)
+
+ print len(msgsFound)
+ myStore.store.close()
+
+if __name__=='__main__':
+ main()
diff --git a/test/__init__.py b/test/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/__init__.py
diff --git a/test/test_purge_obsolete.py b/test/test_purge_obsolete.py
new file mode 100644
index 0000000..c4d1ec9
--- /dev/null
+++ b/test/test_purge_obsolete.py
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+from __future__ import division
+import unittest
+
+class SimpleDateTest(unittest.TestCase):
+ def setUp(self):
+ from purgeObsolete import SimpleDate
+
+ def runInnerTest(self):
+ threeMonthAgo = date.today()
+ JD3MAgo = GregorianCalendar(threeMonthAgo.year,
+ threeMonthAgo.month-1,
+ threeMonthAgo.day,0,0)
+ formatter = SimpleDateFormat("yyyy-MM-dd",Locale.US);
+ JD3MAgoStr = formatter.format(JD3MAgo.getTime())
+ self.assertEqual(str(threeMonthAgo),JD3MAgoStr)
+
+ def runTest(self):
+ pass
+
+class ArchivedStoreTest(unittest.TestCase):
+ def setUp(self):
+ from purgeObsolete import ArchivedStore
+ self.store = ArchivedStore(paramServer="zimbra")
+
+ def tearDown(self):
+ self.store.store.close()
+
+ def testConnect(self):
+ folderList = self.store.store.getDefaultFolder().list("*")
+ self.assertEqual(len(folderList)>0,True)
+
+ def testOpeningFolder(self):
+ from purgeObsolete import ArchivedFolder
+ folder = ArchivedFolder(self.store,"INBOX/bugzilla/xgl")
+ self.assertEqual(folder.folder.getMessageCount() > 0,True)
+
+ def runTest(self):
+ self.testConnect()
+ self.testOpeningFolder()
+
+if __name__=="__main__":
+ unittest.main()