minor code enhancements

- More class inherit from object.
- Initialize all attributes.
- Code style.

Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
Nicolas Sebrecht 2016-07-28 00:42:35 +02:00
parent 7fe90b8e0d
commit 88e8a4895e
3 changed files with 43 additions and 39 deletions

View File

@ -1,6 +1,6 @@
"""Eval python code with global namespace of a python source file.""" """Eval python code with global namespace of a python source file."""
# Copyright (C) 2002-2014 John Goerzen & contributors # Copyright (C) 2002-2016 John Goerzen & contributors
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@ -22,7 +22,7 @@ try:
except: except:
pass pass
class LocalEval: class LocalEval(object):
"""Here is a powerfull but very dangerous option, of course.""" """Here is a powerfull but very dangerous option, of course."""
def __init__(self, path=None): def __init__(self, path=None):

View File

@ -1,4 +1,5 @@
# Base repository support """ Base repository support """
# Copyright (C) 2002-2016 John Goerzen & contributors # Copyright (C) 2002-2016 John Goerzen & contributors
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -23,8 +24,8 @@ from offlineimap import CustomConfig
from offlineimap.ui import getglobalui from offlineimap.ui import getglobalui
from offlineimap.error import OfflineImapError from offlineimap.error import OfflineImapError
class BaseRepository(CustomConfig.ConfigHelperMixin, object):
class BaseRepository(CustomConfig.ConfigHelperMixin):
def __init__(self, reposname, account): def __init__(self, reposname, account):
self.ui = getglobalui() self.ui = getglobalui()
self.account = account self.account = account
@ -178,16 +179,16 @@ class BaseRepository(CustomConfig.ConfigHelperMixin, object):
dst_folders = dst_repo.getfolders() dst_folders = dst_repo.getfolders()
# Do we need to refresh the folder list afterwards? # Do we need to refresh the folder list afterwards?
src_haschanged, dst_haschanged = False, False src_haschanged, dst_haschanged = False, False
# Create hashes with the names, but convert the source folders. # Create hashes with the names, but convert the source folders
# to the dest folder's sep. # to the dest folder's sep.
src_hash = {} src_hash = {}
for folder in src_folders: for folder in src_folders:
src_hash[folder.getvisiblename().replace( src_hash[folder.getvisiblename().replace(
src_repo.getsep(), dst_repo.getsep())] = folder src_repo.getsep(), dst_repo.getsep())] = folder
dst_hash = {} dst_hash = {}
for folder in dst_folders: for folder in dst_folders:
dst_hash[folder.getvisiblename().replace( dst_hash[folder.getvisiblename().replace(
dst_repo.getsep(), src_repo.getsep())] = folder dst_repo.getsep(), src_repo.getsep())] = folder
# Find and create new folders on src_repo. # Find and create new folders on src_repo.
for src_name_t, src_folder in src_hash.items(): for src_name_t, src_folder in src_hash.items():
@ -250,10 +251,10 @@ class BaseRepository(CustomConfig.ConfigHelperMixin, object):
src_haschanged = True # Need to refresh list. src_haschanged = True # Need to refresh list.
except OfflineImapError as e: except OfflineImapError as e:
self.ui.error(e, exc_info()[2], "Creating folder %s on " self.ui.error(e, exc_info()[2], "Creating folder %s on "
"repository %s" % (dst_name_t, src_repo)) "repository %s"% (dst_name_t, src_repo))
raise raise
status_repo.makefolder(dst_name_t.replace( status_repo.makefolder(dst_name_t.replace(
src_repo.getsep(), status_repo.getsep())) src_repo.getsep(), status_repo.getsep()))
# Find deleted folders. # Find deleted folders.
# TODO: We don't delete folders right now. # TODO: We don't delete folders right now.

View File

@ -1,4 +1,5 @@
# IMAP repository support """ IMAP repository support """
# Copyright (C) 2002-2016 John Goerzen & contributors # Copyright (C) 2002-2016 John Goerzen & contributors
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -21,6 +22,7 @@ import errno
import codecs import codecs
from sys import exc_info from sys import exc_info
from threading import Event from threading import Event
import six import six
from offlineimap import folder, imaputil, imapserver, OfflineImapError from offlineimap import folder, imaputil, imapserver, OfflineImapError
@ -31,8 +33,6 @@ from offlineimap.utils.distro import get_os_sslcertfile, get_os_sslcertfile_sear
class IMAPRepository(BaseRepository): class IMAPRepository(BaseRepository):
def __init__(self, reposname, account): def __init__(self, reposname, account):
"""Initialize an IMAPRepository object."""
BaseRepository.__init__(self, reposname, account) BaseRepository.__init__(self, reposname, account)
# self.ui is being set by the BaseRepository # self.ui is being set by the BaseRepository
self._host = None self._host = None
@ -40,6 +40,10 @@ class IMAPRepository(BaseRepository):
self.imapserver = imapserver.IMAPServer(self) self.imapserver = imapserver.IMAPServer(self)
self.folders = None self.folders = None
self.copy_ignore_eval = None self.copy_ignore_eval = None
self.oauth2_request_url = None
# Keep alive.
self.kaevent = None
self.kathread = None
# Only set the newmail_hook in an IMAP repository. # Only set the newmail_hook in an IMAP repository.
if self.config.has_option(self.getsection(), 'newmail_hook'): if self.config.has_option(self.getsection(), 'newmail_hook'):
@ -52,11 +56,12 @@ class IMAPRepository(BaseRepository):
def startkeepalive(self): def startkeepalive(self):
keepalivetime = self.getkeepalive() keepalivetime = self.getkeepalive()
if not keepalivetime: return if not keepalivetime:
return
self.kaevent = Event() self.kaevent = Event()
self.kathread = ExitNotifyThread(target = self.imapserver.keepalive, self.kathread = ExitNotifyThread(target=self.imapserver.keepalive,
name = "Keep alive " + self.getname(), name="Keep alive " + self.getname(),
args = (keepalivetime, self.kaevent)) args=(keepalivetime, self.kaevent))
self.kathread.setDaemon(1) self.kathread.setDaemon(1)
self.kathread.start() self.kathread.start()
@ -83,7 +88,7 @@ class IMAPRepository(BaseRepository):
if self.config.has_option(self.getsection(), if self.config.has_option(self.getsection(),
'copy_ignore_eval'): 'copy_ignore_eval'):
self.copy_ignore_eval = self.localeval.eval( self.copy_ignore_eval = self.localeval.eval(
self.getconf('copy_ignore_eval')) self.getconf('copy_ignore_eval'))
else: else:
self.copy_ignore_eval = lambda x: None self.copy_ignore_eval = lambda x: None
@ -115,10 +120,10 @@ class IMAPRepository(BaseRepository):
"""Return the configured hostname to connect to """Return the configured hostname to connect to
:returns: hostname as string or throws Exception""" :returns: hostname as string or throws Exception"""
if self._host: # use cached value if possible if self._host: # Use cached value if possible.
return self._host return self._host
# 1) check for remotehosteval setting # 1) Check for remotehosteval setting.
if self.config.has_option(self.getsection(), 'remotehosteval'): if self.config.has_option(self.getsection(), 'remotehosteval'):
host = self.getconf('remotehosteval') host = self.getconf('remotehosteval')
try: try:
@ -133,13 +138,13 @@ class IMAPRepository(BaseRepository):
if host: if host:
self._host = host self._host = host
return self._host return self._host
# 2) check for plain remotehost setting # 2) Check for plain remotehost setting.
host = self.getconf('remotehost', None) host = self.getconf('remotehost', None)
if host != None: if host != None:
self._host = host self._host = host
return self._host return self._host
# no success # No success.
raise OfflineImapError("No remote host for repository " raise OfflineImapError("No remote host for repository "
"'%s' specified."% self, OfflineImapError.ERROR.REPO) "'%s' specified."% self, OfflineImapError.ERROR.REPO)
@ -158,7 +163,7 @@ class IMAPRepository(BaseRepository):
# Mechanisms are ranged from the strongest to the # Mechanisms are ranged from the strongest to the
# weakest ones. # weakest ones.
# TODO: we need DIGEST-MD5, it must come before CRAM-MD5 # TODO: we need DIGEST-MD5, it must come before CRAM-MD5
# TODO: due to the chosen-plaintext resistance. # due to the chosen-plaintext resistance.
default = ["GSSAPI", "XOAUTH2", "CRAM-MD5", "PLAIN", "LOGIN"] default = ["GSSAPI", "XOAUTH2", "CRAM-MD5", "PLAIN", "LOGIN"]
mechs = self.getconflist('auth_mechanisms', r',\s*', mechs = self.getconflist('auth_mechanisms', r',\s*',
@ -173,7 +178,6 @@ class IMAPRepository(BaseRepository):
self.ui.debug('imap', "Using authentication mechanisms %s" % mechs) self.ui.debug('imap', "Using authentication mechanisms %s" % mechs)
return mechs return mechs
def getuser(self): def getuser(self):
user = None user = None
localeval = self.localeval localeval = self.localeval
@ -208,7 +212,6 @@ class IMAPRepository(BaseRepository):
if netrcentry: if netrcentry:
return netrcentry[0] return netrcentry[0]
def getport(self): def getport(self):
port = None port = None
@ -365,24 +368,24 @@ class IMAPRepository(BaseRepository):
On success we return the password. On success we return the password.
If all strategies fail we return None.""" If all strategies fail we return None."""
# 1. evaluate Repository 'remotepasseval' # 1. Evaluate Repository 'remotepasseval'.
passwd = self.getconf('remotepasseval', None) passwd = self.getconf('remotepasseval', None)
if passwd != None: if passwd is not None:
return self.localeval.eval(passwd).encode('UTF-8') return self.localeval.eval(passwd).encode('UTF-8')
# 2. read password from Repository 'remotepass' # 2. Read password from Repository 'remotepass'.
password = self.getconf('remotepass', None) password = self.getconf('remotepass', None)
if password != None: if password is not None:
# Assume the configuration file to be UTF-8 encoded so we must not # Assume the configuration file to be UTF-8 encoded so we must not
# encode this string again. # encode this string again.
return password return password
# 3. read password from file specified in Repository 'remotepassfile' # 3. Read password from file specified in Repository 'remotepassfile'.
passfile = self.getconf('remotepassfile', None) passfile = self.getconf('remotepassfile', None)
if passfile != None: if passfile is not None:
fd = codecs.open(os.path.expanduser(passfile), 'r', 'UTF-8') fd = codecs.open(os.path.expanduser(passfile), 'r', 'UTF-8')
password = fd.readline().strip() password = fd.readline().strip()
fd.close() fd.close()
return password.encode('UTF-8') return password.encode('UTF-8')
# 4. read password from ~/.netrc # 4. Read password from ~/.netrc.
try: try:
netrcentry = netrc.netrc().authenticators(self.gethost()) netrcentry = netrc.netrc().authenticators(self.gethost())
except IOError as inst: except IOError as inst:
@ -391,9 +394,9 @@ class IMAPRepository(BaseRepository):
else: else:
if netrcentry: if netrcentry:
user = self.getuser() user = self.getuser()
if user == None or user == netrcentry[0]: if user is None or user == netrcentry[0]:
return netrcentry[2] return netrcentry[2]
# 5. read password from /etc/netrc # 5. Read password from /etc/netrc.
try: try:
netrcentry = netrc.netrc('/etc/netrc').authenticators(self.gethost()) netrcentry = netrc.netrc('/etc/netrc').authenticators(self.gethost())
except IOError as inst: except IOError as inst:
@ -402,9 +405,9 @@ class IMAPRepository(BaseRepository):
else: else:
if netrcentry: if netrcentry:
user = self.getuser() user = self.getuser()
if user == None or user == netrcentry[0]: if user is None or user == netrcentry[0]:
return netrcentry[2] return netrcentry[2]
# no strategy yielded a password! # No strategy yielded a password!
return None return None
def getfolder(self, foldername): def getfolder(self, foldername):
@ -425,7 +428,7 @@ class IMAPRepository(BaseRepository):
def getfolders(self): def getfolders(self):
"""Return a list of instances of OfflineIMAP representative folder.""" """Return a list of instances of OfflineIMAP representative folder."""
if self.folders != None: if self.folders is not None:
return self.folders return self.folders
retval = [] retval = []
imapobj = self.imapserver.acquireconnection() imapobj = self.imapserver.acquireconnection()
@ -434,7 +437,7 @@ class IMAPRepository(BaseRepository):
if self.getconfboolean('subscribedonly', False): if self.getconfboolean('subscribedonly', False):
listfunction = imapobj.lsub listfunction = imapobj.lsub
try: try:
listresult = listfunction(directory = self.imapserver.reference)[1] listresult = listfunction(directory=self.imapserver.reference)[1]
finally: finally:
self.imapserver.releaseconnection(imapobj) self.imapserver.releaseconnection(imapobj)
for s in listresult: for s in listresult:
@ -456,7 +459,7 @@ class IMAPRepository(BaseRepository):
try: try:
for foldername in self.folderincludes: for foldername in self.folderincludes:
try: try:
imapobj.select(foldername, readonly = True) imapobj.select(foldername, readonly=True)
except OfflineImapError as e: except OfflineImapError as e:
# couldn't select this folderinclude, so ignore folder. # couldn't select this folderinclude, so ignore folder.
if e.severity > OfflineImapError.ERROR.FOLDER: if e.severity > OfflineImapError.ERROR.FOLDER:
@ -478,7 +481,7 @@ class IMAPRepository(BaseRepository):
def cmp2key(mycmp): def cmp2key(mycmp):
"""Converts a cmp= function into a key= function """Converts a cmp= function into a key= function
We need to keep cmp functions for backward compatibility""" We need to keep cmp functions for backward compatibility"""
class K: class K(object):
def __init__(self, obj, *args): def __init__(self, obj, *args):
self.obj = obj self.obj = obj
def __cmp__(self, other): def __cmp__(self, other):