more consistent style

Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Nicolas Sebrecht
2015-01-01 21:41:11 +01:00
parent 11a28fb0cb
commit 61021260cb
20 changed files with 277 additions and 245 deletions

View File

@ -1,5 +1,5 @@
# Curses-based interfaces
# Copyright (C) 2003-2011 John Goerzen & contributors
# Copyright (C) 2003-2015 John Goerzen & contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -22,12 +22,13 @@ import sys
import os
import curses
import logging
from offlineimap.ui.UIBase import UIBase
from offlineimap.threadutil import ExitNotifyThread
import offlineimap
class CursesUtil:
class CursesUtil:
def __init__(self, *args, **kwargs):
# iolock protects access to the
self.iolock = RLock()
@ -322,6 +323,7 @@ class Blinkenlights(UIBase, CursesUtil):
Sets up things and adds them to self.logger.
:returns: The logging.Handler() for console output"""
# create console handler with a higher log level
ch = CursesLogHandler()
#ch.setLevel(logging.DEBUG)
@ -336,6 +338,7 @@ class Blinkenlights(UIBase, CursesUtil):
def isusable(s):
"""Returns true if the backend is usable ie Curses works"""
# Not a terminal? Can't use curses.
if not sys.stdout.isatty() and sys.stdin.isatty():
return False
@ -391,6 +394,7 @@ class Blinkenlights(UIBase, CursesUtil):
def acct(self, *args):
"""Output that we start syncing an account (and start counting)"""
self.gettf().setcolor('purple')
super(Blinkenlights, self).acct(*args)

View File

@ -1,4 +1,4 @@
# Copyright (C) 2007-2011 John Goerzen & contributors
# Copyright (C) 2007-2015 John Goerzen & contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
# TTY UI
# Copyright (C) 2002-2011 John Goerzen & contributors
# Copyright (C) 2002-2015 John Goerzen & contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -24,6 +24,7 @@ from offlineimap.ui.UIBase import UIBase
class TTYFormatter(logging.Formatter):
"""Specific Formatter that adds thread information to the log output"""
def __init__(self, *args, **kwargs):
#super() doesn't work in py2.6 as 'logging' uses old-style class
logging.Formatter.__init__(self, *args, **kwargs)
@ -46,12 +47,14 @@ class TTYFormatter(logging.Formatter):
log_str = " %s" % log_str
return log_str
class TTYUI(UIBase):
def setup_consolehandler(self):
"""Backend specific console handler
Sets up things and adds them to self.logger.
:returns: The logging.Handler() for console output"""
# create console handler with a higher log level
ch = logging.StreamHandler()
#ch.setLevel(logging.DEBUG)
@ -67,10 +70,12 @@ class TTYUI(UIBase):
def isusable(self):
"""TTYUI is reported as usable when invoked on a terminal"""
return sys.stdout.isatty() and sys.stdin.isatty()
def getpass(self, accountname, config, errmsg = None):
def getpass(self, accountname, config, errmsg=None):
"""TTYUI backend is capable of querying the password"""
if errmsg:
self.warn("%s: %s" % (accountname, errmsg))
self._log_con_handler.acquire() # lock the console output
@ -97,6 +102,7 @@ class TTYUI(UIBase):
implementations return 0 for successful sleep and 1 for an
'abort', ie a request to sync immediately.
"""
if sleepsecs > 0:
if remainingsecs//60 != (remainingsecs-sleepsecs)//60:
self.logger.info("Next refresh in %.1f minutes" % (

View File

@ -1,5 +1,5 @@
# UI base class
# Copyright (C) 2002-2011 John Goerzen & contributors
# Copyright (C) 2002-2015 John Goerzen & contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -45,22 +45,22 @@ def getglobalui():
return globalui
class UIBase(object):
def __init__(self, config, loglevel = logging.INFO):
def __init__(self, config, loglevel=logging.INFO):
self.config = config
# Is this a 'dryrun'?
self.dryrun = config.getdefaultboolean('general', 'dry-run', False)
self.debuglist = []
"""list of debugtypes we are supposed to log"""
# list of debugtypes we are supposed to log
self.debugmessages = {}
"""debugmessages in a deque(v) per thread(k)"""
# debugmessages in a deque(v) per thread(k)
self.debugmsglen = 15
self.threadaccounts = {}
"""dict linking active threads (k) to account names (v)"""
# dict linking active threads (k) to account names (v)
self.acct_startimes = {}
"""linking active accounts with the time.time() when sync started"""
# linking active accounts with the time.time() when sync started
self.logfile = None
self.exc_queue = Queue()
"""saves all occuring exceptions, so we can output them at the end"""
# saves all occuring exceptions, so we can output them at the end
# create logger with 'OfflineImap' app
self.logger = logging.getLogger('OfflineImap')
self.logger.setLevel(loglevel)
@ -73,6 +73,7 @@ class UIBase(object):
Sets up things and adds them to self.logger.
:returns: The logging.Handler() for console output"""
# create console handler with a higher log level
ch = logging.StreamHandler(sys.stdout)
#ch.setLevel(logging.DEBUG)
@ -94,12 +95,13 @@ class UIBase(object):
# write out more verbose initial info blurb on the log file
p_ver = ".".join([str(x) for x in sys.version_info[0:3]])
msg = "OfflineImap %s starting...\n Python: %s Platform: %s\n "\
"Args: %s" % (offlineimap.__bigversion__, p_ver, sys.platform,
"Args: %s"% (offlineimap.__bigversion__, p_ver, sys.platform,
" ".join(sys.argv))
self.logger.info(msg)
def _msg(self, msg):
"""Display a message."""
# TODO: legacy function, rip out.
self.info(msg)
@ -149,7 +151,8 @@ class UIBase(object):
self._msg(traceback.format_tb(instant_traceback))
def registerthread(self, account):
"""Register current thread as being associated with an account name"""
"""Register current thread as being associated with an account name."""
cur_thread = threading.currentThread()
if cur_thread in self.threadaccounts:
# was already associated with an old account, update info
@ -162,15 +165,17 @@ class UIBase(object):
self.threadaccounts[cur_thread] = account
def unregisterthread(self, thr):
"""Unregister a thread as being associated with an account name"""
"""Unregister a thread as being associated with an account name."""
if thr in self.threadaccounts:
del self.threadaccounts[thr]
self.debug('thread', "Unregister thread '%s'" % thr.getName())
def getthreadaccount(self, thr = None):
def getthreadaccount(self, thr=None):
"""Get Account() for a thread (current if None)
If no account has been registered with this thread, return 'None'"""
If no account has been registered with this thread, return 'None'."""
if thr == None:
thr = threading.currentThread()
if thr in self.threadaccounts:
@ -214,6 +219,7 @@ class UIBase(object):
"""Return the type of a repository or Folder as string
(IMAP, Gmail, Maildir, etc...)"""
prelimname = object.__class__.__name__.split('.')[-1]
# Strip off extra stuff.
return re.sub('(Folder|Repository)', '', prelimname)
@ -222,6 +228,7 @@ class UIBase(object):
"""Returns true if this UI object is usable in the current
environment. For instance, an X GUI would return true if it's
being run in X with a valid DISPLAY setting, and false otherwise."""
return True
################################################## INPUT
@ -281,7 +288,8 @@ class UIBase(object):
pass
def connecting(self, hostname, port):
"""Log 'Establishing connection to'"""
"""Log 'Establishing connection to'."""
if not self.logger.isEnabledFor(logging.INFO): return
displaystr = ''
hostname = hostname if hostname else ''
@ -291,19 +299,22 @@ class UIBase(object):
self.logger.info("Establishing connection%s" % displaystr)
def acct(self, account):
"""Output that we start syncing an account (and start counting)"""
"""Output that we start syncing an account (and start counting)."""
self.acct_startimes[account] = time.time()
self.logger.info("*** Processing account %s" % account)
def acctdone(self, account):
"""Output that we finished syncing an account (in which time)"""
"""Output that we finished syncing an account (in which time)."""
sec = time.time() - self.acct_startimes[account]
del self.acct_startimes[account]
self.logger.info("*** Finished account '%s' in %d:%02d" %
(account, sec // 60, sec % 60))
def syncfolders(self, src_repo, dst_repo):
"""Log 'Copying folder structure...'"""
"""Log 'Copying folder structure...'."""
if self.logger.isEnabledFor(logging.DEBUG):
self.debug('', "Copying folder structure from %s to %s" %\
(src_repo, dst_repo))
@ -328,12 +339,12 @@ class UIBase(object):
def validityproblem(self, folder):
self.logger.warning("UID validity problem for folder %s (repo %s) "
"(saved %d; got %d); skipping it. Please see FAQ "
"and manual on how to handle this." % \
"and manual on how to handle this."% \
(folder, folder.getrepository(),
folder.get_saveduidvalidity(), folder.get_uidvalidity()))
def loadmessagelist(self, repos, folder):
self.logger.debug("Loading message list for %s[%s]" % (
self.logger.debug(u"Loading message list for %s[%s]"% (
self.getnicename(repos),
folder))
@ -389,7 +400,8 @@ class UIBase(object):
self.logger.info("Collecting data from messages on %s" % source)
def serverdiagnostics(self, repository, type):
"""Connect to repository and output useful information for debugging"""
"""Connect to repository and output useful information for debugging."""
conn = None
self._msg("%s repository '%s': type '%s'" % (type, repository.name,
self.getnicename(repository)))
@ -440,8 +452,9 @@ class UIBase(object):
repository.imapserver.close()
def savemessage(self, debugtype, uid, flags, folder):
"""Output a log line stating that we save a msg"""
self.debug(debugtype, "Write mail '%s:%d' with flags %s" %
"""Output a log line stating that we save a msg."""
self.debug(debugtype, u"Write mail '%s:%d' with flags %s"%
(folder, uid, repr(flags)))
################################################## Threads
@ -461,42 +474,46 @@ class UIBase(object):
del self.debugmessages[thread]
def getThreadExceptionString(self, thread):
message = "Thread '%s' terminated with exception:\n%s" % \
message = u"Thread '%s' terminated with exception:\n%s"% \
(thread.getName(), thread.exit_stacktrace)
message += "\n" + self.getThreadDebugLog(thread)
message += u"\n" + self.getThreadDebugLog(thread)
return message
def threadException(self, thread):
"""Called when a thread has terminated with an exception.
The argument is the ExitNotifyThread that has so terminated."""
self.warn(self.getThreadExceptionString(thread))
self.delThreadDebugLog(thread)
self.terminate(100)
def terminate(self, exitstatus = 0, errortitle = None, errormsg = None):
"""Called to terminate the application."""
#print any exceptions that have occurred over the run
if not self.exc_queue.empty():
self.warn("ERROR: Exceptions occurred during the run!")
self.warn(u"ERROR: Exceptions occurred during the run!")
while not self.exc_queue.empty():
msg, exc, exc_traceback = self.exc_queue.get()
if msg:
self.warn("ERROR: %s\n %s" % (msg, exc))
self.warn(u"ERROR: %s\n %s"% (msg, exc))
else:
self.warn("ERROR: %s" % (exc))
self.warn(u"ERROR: %s"% (exc))
if exc_traceback:
self.warn("\nTraceback:\n%s" %"".join(
self.warn(u"\nTraceback:\n%s"% "".join(
traceback.format_tb(exc_traceback)))
if errormsg and errortitle:
self.warn('ERROR: %s\n\n%s\n'%(errortitle, errormsg))
self.warn(u'ERROR: %s\n\n%s\n'% (errortitle, errormsg))
elif errormsg:
self.warn('%s\n' % errormsg)
self.warn(u'%s\n' % errormsg)
sys.exit(exitstatus)
def threadExited(self, thread):
"""Called when a thread has exited normally. Many UIs will
just ignore this."""
"""Called when a thread has exited normally.
Many UIs will just ignore this."""
self.delThreadDebugLog(thread)
self.unregisterthread(thread)
@ -518,6 +535,7 @@ class UIBase(object):
:returns: 0/False if timeout expired, 1/2/True if there is a
request to cancel the timer.
"""
abortsleep = False
while sleepsecs > 0 and not abortsleep:
if account.get_abort_event():
@ -538,6 +556,7 @@ class UIBase(object):
implementations return 0 for successful sleep and 1 for an
'abort', ie a request to sync immediately.
"""
if sleepsecs > 0:
if remainingsecs//60 != (remainingsecs-sleepsecs)//60:
self.logger.debug("Next refresh in %.1f minutes" % (

View File

@ -1,6 +1,5 @@
# Locking debugging code -- temporary
# Copyright (C) 2003 John Goerzen
# <jgoerzen@complete.org>
# Copyright (C) 2003-2015 John Goerzen & contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by