Split offlineimap.run()

Was getting too large, split into an parse_cmd_options and a sync()
function. Moving config and ui to self.config and self.ui to make them
available through the OfflineImap instance.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
Sebastian Spaeth 2011-06-30 14:04:18 +02:00
parent a5eebd4b6b
commit 6b3f429c81

View File

@ -44,7 +44,11 @@ class OfflineImap:
""" """
def run(self): def run(self):
"""Parse the commandline and invoke everything""" """Parse the commandline and invoke everything"""
# next line also sets self.config
options = self.parse_cmd_options()
self.sync(options)
def parse_cmd_options(self):
parser = OptionParser(version=offlineimap.__version__, parser = OptionParser(version=offlineimap.__version__,
description="%s.\n\n%s" % description="%s.\n\n%s" %
(offlineimap.__copyright__, (offlineimap.__copyright__,
@ -187,19 +191,19 @@ class OfflineImap:
'of %s' % ', '.join(UI_LIST.keys())) 'of %s' % ', '.join(UI_LIST.keys()))
try: try:
# create the ui class # create the ui class
ui = UI_LIST[ui_type.lower()](config) self.ui = UI_LIST[ui_type.lower()](config)
except KeyError: except KeyError:
logging.error("UI '%s' does not exist, choose one of: %s" % \ logging.error("UI '%s' does not exist, choose one of: %s" % \
(ui_type,', '.join(UI_LIST.keys()))) (ui_type,', '.join(UI_LIST.keys())))
sys.exit(1) sys.exit(1)
setglobalui(ui) setglobalui(self.ui)
#set up additional log files #set up additional log files
if options.logfile: if options.logfile:
ui.setlogfd(open(options.logfile, 'wt')) self.ui.setlogfd(open(options.logfile, 'wt'))
#welcome blurb #welcome blurb
ui.init_banner() self.ui.init_banner()
if options.debugtype: if options.debugtype:
if options.debugtype.lower() == 'all': if options.debugtype.lower() == 'all':
@ -207,13 +211,13 @@ class OfflineImap:
#force single threading? #force single threading?
if not ('thread' in options.debugtype.split(',') \ if not ('thread' in options.debugtype.split(',') \
and not options.singlethreading): and not options.singlethreading):
ui._msg("Debug mode: Forcing to singlethreaded.") self.ui._msg("Debug mode: Forcing to singlethreaded.")
options.singlethreading = True options.singlethreading = True
debugtypes = options.debugtype.split(',') + [''] debugtypes = options.debugtype.split(',') + ['']
for type in debugtypes: for type in debugtypes:
type = type.strip() type = type.strip()
ui.add_debug(type) self.ui.add_debug(type)
if type.lower() == 'imap': if type.lower() == 'imap':
imaplib.Debug = 5 imaplib.Debug = 5
@ -241,57 +245,15 @@ class OfflineImap:
config.set(section, "folderfilter", folderfilter) config.set(section, "folderfilter", folderfilter)
config.set(section, "folderincludes", folderincludes) config.set(section, "folderincludes", folderincludes)
self.config = config
def sigterm_handler(signum, frame):
# die immediately
ui = getglobalui()
ui.terminate(errormsg="terminating...")
signal.signal(signal.SIGTERM,sigterm_handler)
try:
pidfd = open(config.getmetadatadir() + "/pid", "w")
pidfd.write(str(os.getpid()) + "\n")
pidfd.close()
except:
pass
try:
if options.logfile: if options.logfile:
sys.stderr = ui.logfile sys.stderr = self.ui.logfile
socktimeout = config.getdefaultint("general", "socktimeout", 0) socktimeout = config.getdefaultint("general", "socktimeout", 0)
if socktimeout > 0: if socktimeout > 0:
socket.setdefaulttimeout(socktimeout) socket.setdefaulttimeout(socktimeout)
activeaccounts = config.get("general", "accounts")
if options.accounts:
activeaccounts = options.accounts
activeaccounts = activeaccounts.replace(" ", "")
activeaccounts = activeaccounts.split(",")
allaccounts = accounts.AccountHashGenerator(config)
syncaccounts = []
for account in activeaccounts:
if account not in allaccounts:
if len(allaccounts) == 0:
errormsg = 'The account "%s" does not exist because no accounts are defined!'%account
else:
errormsg = 'The account "%s" does not exist. Valid accounts are:'%account
for name in allaccounts.keys():
errormsg += '\n%s'%name
ui.terminate(1, errortitle = 'Unknown Account "%s"'%account, errormsg = errormsg)
if account not in syncaccounts:
syncaccounts.append(account)
server = None
remoterepos = None
localrepos = None
threadutil.initInstanceLimit('ACCOUNTLIMIT', threadutil.initInstanceLimit('ACCOUNTLIMIT',
config.getdefaultint('general', config.getdefaultint('general', 'maxsyncaccounts', 1))
'maxsyncaccounts', 1))
for reposname in config.getsectionlist('Repository'): for reposname in config.getsectionlist('Repository'):
for instancename in ["FOLDER_" + reposname, for instancename in ["FOLDER_" + reposname,
@ -302,6 +264,52 @@ class OfflineImap:
threadutil.initInstanceLimit(instancename, threadutil.initInstanceLimit(instancename,
config.getdefaultint('Repository ' + reposname, config.getdefaultint('Repository ' + reposname,
'maxconnections', 2)) 'maxconnections', 2))
self.config = config
return options
def sync(self, options):
"""Invoke the correct single/multithread syncing
self.config is supposed to have been correctly initialized
already."""
def sigterm_handler(signum, frame):
# die immediately
self.ui.terminate(errormsg="terminating...")
signal.signal(signal.SIGTERM, sigterm_handler)
try:
pidfd = open(self.config.getmetadatadir() + "/pid", "w")
pidfd.write(str(os.getpid()) + "\n")
pidfd.close()
except:
pass
try:
activeaccounts = self.config.get("general", "accounts")
if options.accounts:
activeaccounts = options.accounts
activeaccounts = activeaccounts.replace(" ", "")
activeaccounts = activeaccounts.split(",")
allaccounts = accounts.AccountHashGenerator(self.config)
syncaccounts = []
for account in activeaccounts:
if account not in allaccounts:
if len(allaccounts) == 0:
errormsg = "The account '%s' does not exist because no"\
" accounts are defined!" % account
else:
errormsg = "The account '%s' does not exist. Valid ac"\
"counts are: " % account
errormsg += ", ".join(allaccounts.keys())
self.ui.terminate(1, errormsg = errormsg)
if account not in syncaccounts:
syncaccounts.append(account)
server = None
remoterepos = None
localrepos = None
def sig_handler(sig, frame): def sig_handler(sig, frame):
if sig == signal.SIGUSR1 or sig == signal.SIGHUP: if sig == signal.SIGUSR1 or sig == signal.SIGHUP:
# tell each account to stop sleeping # tell each account to stop sleeping
@ -315,7 +323,7 @@ class OfflineImap:
signal.signal(signal.SIGUSR2,sig_handler) signal.signal(signal.SIGUSR2,sig_handler)
#various initializations that need to be performed: #various initializations that need to be performed:
offlineimap.mbnames.init(config, syncaccounts) offlineimap.mbnames.init(self.config, syncaccounts)
#TODO: keep legacy lock for a few versions, then remove. #TODO: keep legacy lock for a few versions, then remove.
self._legacy_lock = open(self.config.getmetadatadir() + "/lock", self._legacy_lock = open(self.config.getmetadatadir() + "/lock",
@ -331,20 +339,20 @@ class OfflineImap:
if options.singlethreading: if options.singlethreading:
#singlethreaded #singlethreaded
self.sync_singlethreaded(syncaccounts, config) self.sync_singlethreaded(syncaccounts)
else: else:
# multithreaded # multithreaded
t = threadutil.ExitNotifyThread(target=syncmaster.syncitall, t = threadutil.ExitNotifyThread(target=syncmaster.syncitall,
name='Sync Runner', name='Sync Runner',
kwargs = {'accounts': syncaccounts, kwargs = {'accounts': syncaccounts,
'config': config}) 'config': self.config})
t.setDaemon(1) t.setDaemon(1)
t.start() t.start()
threadutil.exitnotifymonitorloop(threadutil.threadexited) threadutil.exitnotifymonitorloop(threadutil.threadexited)
ui.terminate() self.ui.terminate()
except KeyboardInterrupt: except KeyboardInterrupt:
ui.terminate(1, errormsg = 'CTRL-C pressed, aborting...') self.ui.terminate(1, errormsg = 'CTRL-C pressed, aborting...')
return return
except (SystemExit): except (SystemExit):
raise raise
@ -352,13 +360,13 @@ class OfflineImap:
ui.error(e) ui.error(e)
ui.terminate() ui.terminate()
def sync_singlethreaded(self, accs, config): def sync_singlethreaded(self, accs):
"""Executed if we do not want a separate syncmaster thread """Executed if we do not want a separate syncmaster thread
:param accs: A list of accounts that should be synced :param accs: A list of accounts that should be synced
:param config: The CustomConfig object
""" """
for accountname in accs: for accountname in accs:
account = offlineimap.accounts.SyncableAccount(config, accountname) account = offlineimap.accounts.SyncableAccount(self.config,
accountname)
threading.currentThread().name = "Account sync %s" % accountname threading.currentThread().name = "Account sync %s" % accountname
account.syncrunner() account.syncrunner()