]> code.delx.au - offlineimap/blobdiff - offlineimap/init.py
Bug#502779: Sync accounts in order of general.accounts option
[offlineimap] / offlineimap / init.py
index 9824f055036b629f75d21ed85334c54dfc628ca1..8d888b43d8c0884d80ef22da728be215f065edeb 100644 (file)
@@ -16,8 +16,7 @@
 #    along with this program; if not, write to the Free Software
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 
-import imaplib
-from offlineimap import imapserver, repository, folder, mbnames, threadutil, version, syncmaster, accounts
+from offlineimap import imaplib2, imapserver, repository, folder, mbnames, threadutil, version, syncmaster, accounts
 from offlineimap.localeval import LocalEval
 from offlineimap.threadutil import InstanceLimitedThread, ExitNotifyThread
 from offlineimap.ui import UIBase
@@ -26,6 +25,7 @@ from offlineimap.CustomConfig import CustomConfigParser
 from threading import *
 import threading, socket
 from getopt import getopt
+import signal
 
 try:
     import fcntl
@@ -53,7 +53,7 @@ def startup(versionno):
         sys.stdout.write(version.getcmdhelp() + "\n")
         sys.exit(0)
 
-    for optlist in getopt(sys.argv[1:], 'P:1oqa:c:d:l:u:h')[0]:
+    for optlist in getopt(sys.argv[1:], 'P:1oqa:c:d:l:u:hk:f:')[0]:
         options[optlist[0]] = optlist[1]
 
     if options.has_key('-h'):
@@ -79,6 +79,17 @@ def startup(versionno):
 
     config.read(configfilename)
 
+    # override config values with option '-k'
+    for option in options.keys():
+        if option == '-k':
+            (key, value) = options['-k'].split('=', 1)
+            if ':' in key:
+                (secname, key) = key.split(':', 1)
+                section = secname.replace("_", " ")
+            else:
+                section = "general"
+            config.set(section, key, value)
+
     ui = offlineimap.ui.detector.findUI(config, options.get('-u'))
     UIBase.setglobalui(ui)
 
@@ -91,7 +102,7 @@ def startup(versionno):
         for debugtype in options['-d'].split(','):
             ui.add_debug(debugtype.strip())
             if debugtype == 'imap':
-                imaplib.Debug = 5
+                imaplib2.Debug = 5
             if debugtype == 'thread':
                 threading._VERBOSE = 1
 
@@ -104,11 +115,30 @@ def startup(versionno):
         for section in accounts.getaccountlist(config):
             config.set('Account ' + section, "quick", '-1')
 
+    if options.has_key('-f'):
+        foldernames = options['-f'].replace(" ", "").split(",")
+        folderfilter = "lambda f: f in %s" % foldernames
+        folderincludes = "[]"
+        for accountname in accounts.getaccountlist(config):
+            account_section = 'Account ' + accountname
+            remote_repo_section = 'Repository ' + \
+                                  config.get(account_section, 'remoterepository')
+            local_repo_section = 'Repository ' + \
+                                 config.get(account_section, 'localrepository')
+            for section in [remote_repo_section, local_repo_section]:
+                config.set(section, "folderfilter", folderfilter)
+                config.set(section, "folderincludes", folderincludes)
+
     lock(config, ui)
 
+    def sigterm_handler(signum, frame):
+        # die immediately
+        ui.terminate(errormsg="terminating...")
+    signal.signal(signal.SIGTERM,sigterm_handler)
+
     try:
         pidfd = open(config.getmetadatadir() + "/pid", "w")
-        pidfd.write(os.getpid())
+        pidfd.write(str(os.getpid()) + "\n")
         pidfd.close()
     except:
         pass
@@ -128,7 +158,7 @@ def startup(versionno):
         activeaccounts = activeaccounts.split(",")
         allaccounts = accounts.AccountHashGenerator(config)
 
-        syncaccounts = {}
+        syncaccounts = []
         for account in activeaccounts:
             if account not in allaccounts:
                 if len(allaccounts) == 0:
@@ -138,7 +168,8 @@ def startup(versionno):
                     for name in allaccounts.keys():
                         errormsg += '\n%s'%name
                 ui.terminate(1, errortitle = 'Unknown Account "%s"'%account, errormsg = errormsg)
-            syncaccounts[account] = allaccounts[account]
+            if account not in syncaccounts:
+                syncaccounts.append(account)
 
         server = None
         remoterepos = None
@@ -158,12 +189,31 @@ def startup(versionno):
                 else:
                     threadutil.initInstanceLimit(instancename,
                                                  config.getdefaultint('Repository ' + reposname, "maxconnections", 1))
+        siglisteners = []
+        def sig_handler(signum, frame):
+            if signum == signal.SIGUSR1:
+                # tell each account to do a full sync asap
+                signum = (1,)
+            elif signum == signal.SIGHUP:
+                # tell each account to die asap
+                signum = (2,)
+            elif signum == signal.SIGUSR2:
+                # tell each account to do a full sync asap, then die
+                signum = (1, 2)
+            # one listener per account thread (up to maxsyncaccounts)
+            for listener in siglisteners:
+                for sig in signum:
+                    listener.put_nowait(sig)
+        signal.signal(signal.SIGHUP,sig_handler)
+        signal.signal(signal.SIGUSR1,sig_handler)
+        signal.signal(signal.SIGUSR2,sig_handler)
 
         threadutil.initexitnotify()
         t = ExitNotifyThread(target=syncmaster.syncitall,
                              name='Sync Runner',
                              kwargs = {'accounts': syncaccounts,
-                                       'config': config})
+                                       'config': config,
+                                       'siglisteners': siglisteners})
         t.setDaemon(1)
         t.start()
     except: