Remove superfluous class ConfigedIMAPServer
Remove a level of wrapper abstraction that is not needed. Just use IMAPserver and be done with it. We do this by passing in the IMAPRepository() instance rather than a long list of single paramters to the IMAPServer instanciation. This way we can retrieve all repository parameters ourselves, rather than passing a dozen paramters into IMAPServer. Also, this enables us to pass the repository() object into our WrappedIMAP4() instance, so that it can query, e.g. the SSL fingerprint configuration. Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de> Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
parent
f6b9c68333
commit
131298c2b1
@ -20,10 +20,14 @@ New Features
|
|||||||
Changes
|
Changes
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
* Refactor our IMAPServer class. Background work without user-visible
|
||||||
|
changes.
|
||||||
|
|
||||||
Bug Fixes
|
Bug Fixes
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
* We protect more robustly against asking for inexistent messages from the
|
||||||
|
IMAP server, when someone else deletes or moves messages while we sync.
|
||||||
|
|
||||||
Pending for the next major release
|
Pending for the next major release
|
||||||
==================================
|
==================================
|
||||||
|
@ -42,58 +42,56 @@ except ImportError:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
class IMAPServer:
|
class IMAPServer:
|
||||||
|
"""Initializes all variables from an IMAPRepository() instance
|
||||||
|
|
||||||
|
Various functions, such as acquireconnection() return an IMAP4
|
||||||
|
object on which we can operate."""
|
||||||
GSS_STATE_STEP = 0
|
GSS_STATE_STEP = 0
|
||||||
GSS_STATE_WRAP = 1
|
GSS_STATE_WRAP = 1
|
||||||
def __init__(self, config, reposname,
|
def __init__(self, repos):
|
||||||
username = None, password = None, hostname = None,
|
|
||||||
port = None, ssl = 1, maxconnections = 1, tunnel = None,
|
|
||||||
reference = '""', sslclientcert = None, sslclientkey = None,
|
|
||||||
sslcacertfile = None, idlefolders = []):
|
|
||||||
self.ui = getglobalui()
|
self.ui = getglobalui()
|
||||||
self.reposname = reposname
|
self.repos = repos
|
||||||
self.config = config
|
self.config = repos.getconfig()
|
||||||
self.username = username
|
self.tunnel = repos.getpreauthtunnel()
|
||||||
self.password = password
|
self.usessl = repos.getssl()
|
||||||
|
self.username = repos.getuser()
|
||||||
|
self.password = None
|
||||||
self.passworderror = None
|
self.passworderror = None
|
||||||
self.goodpassword = None
|
self.goodpassword = None
|
||||||
self.hostname = hostname
|
self.hostname = repos.gethost()
|
||||||
self.tunnel = tunnel
|
self.port = repos.getport()
|
||||||
self.port = port
|
if self.port == None:
|
||||||
self.usessl = ssl
|
self.port = 993 if self.usessl else 143
|
||||||
self.sslclientcert = sslclientcert
|
self.sslclientcert = repos.getsslclientcert()
|
||||||
self.sslclientkey = sslclientkey
|
self.sslclientkey = repos.getsslclientkey()
|
||||||
self.sslcacertfile = sslcacertfile
|
self.sslcacertfile = repos.getsslcacertfile()
|
||||||
self.delim = None
|
self.delim = None
|
||||||
self.root = None
|
self.root = None
|
||||||
if port == None:
|
self.maxconnections = repos.getmaxconnections()
|
||||||
if ssl:
|
|
||||||
self.port = 993
|
|
||||||
else:
|
|
||||||
self.port = 143
|
|
||||||
self.maxconnections = maxconnections
|
|
||||||
self.availableconnections = []
|
self.availableconnections = []
|
||||||
self.assignedconnections = []
|
self.assignedconnections = []
|
||||||
self.lastowner = {}
|
self.lastowner = {}
|
||||||
self.semaphore = BoundedSemaphore(self.maxconnections)
|
self.semaphore = BoundedSemaphore(self.maxconnections)
|
||||||
self.connectionlock = Lock()
|
self.connectionlock = Lock()
|
||||||
self.reference = reference
|
self.reference = repos.getreference()
|
||||||
self.idlefolders = idlefolders
|
self.idlefolders = repos.getidlefolders()
|
||||||
self.gss_step = self.GSS_STATE_STEP
|
self.gss_step = self.GSS_STATE_STEP
|
||||||
self.gss_vc = None
|
self.gss_vc = None
|
||||||
self.gssapi = False
|
self.gssapi = False
|
||||||
|
|
||||||
def getpassword(self):
|
def getpassword(self):
|
||||||
if self.goodpassword != None:
|
"""Returns the server password or None"""
|
||||||
|
if self.goodpassword != None: # use cached good one first
|
||||||
return self.goodpassword
|
return self.goodpassword
|
||||||
|
|
||||||
if self.password != None and self.passworderror == None:
|
if self.password != None and self.passworderror == None:
|
||||||
return self.password
|
return self.password # non-failed preconfigured one
|
||||||
|
|
||||||
self.password = self.ui.getpass(self.reposname,
|
# get 1) configured password first 2) fall back to asking via UI
|
||||||
self.config,
|
self.password = self.repos.getpassword() or \
|
||||||
self.passworderror)
|
self.ui.getpass(self.repos.getname(), self.config,
|
||||||
|
self.passworderror)
|
||||||
self.passworderror = None
|
self.passworderror = None
|
||||||
|
|
||||||
return self.password
|
return self.password
|
||||||
|
|
||||||
def getdelim(self):
|
def getdelim(self):
|
||||||
@ -204,7 +202,8 @@ class IMAPServer:
|
|||||||
success = 1
|
success = 1
|
||||||
elif self.usessl:
|
elif self.usessl:
|
||||||
self.ui.connecting(self.hostname, self.port)
|
self.ui.connecting(self.hostname, self.port)
|
||||||
imapobj = imaplibutil.WrappedIMAP4_SSL(self.hostname, self.port,
|
imapobj = imaplibutil.WrappedIMAP4_SSL(self.hostname,
|
||||||
|
self.port,
|
||||||
self.sslclientkey, self.sslclientcert,
|
self.sslclientkey, self.sslclientcert,
|
||||||
timeout=socket.getdefaulttimeout(),
|
timeout=socket.getdefaulttimeout(),
|
||||||
cacertfile = self.sslcacertfile)
|
cacertfile = self.sslcacertfile)
|
||||||
@ -260,7 +259,6 @@ class IMAPServer:
|
|||||||
except imapobj.error, val:
|
except imapobj.error, val:
|
||||||
self.passworderror = str(val)
|
self.passworderror = str(val)
|
||||||
raise
|
raise
|
||||||
#self.password = None
|
|
||||||
|
|
||||||
if self.delim == None:
|
if self.delim == None:
|
||||||
listres = imapobj.list(self.reference, '""')[1]
|
listres = imapobj.list(self.reference, '""')[1]
|
||||||
@ -292,8 +290,6 @@ class IMAPServer:
|
|||||||
error..."""
|
error..."""
|
||||||
self.semaphore.release()
|
self.semaphore.release()
|
||||||
|
|
||||||
#Make sure that this can be retried the next time...
|
|
||||||
self.passworderror = None
|
|
||||||
if(self.connectionlock.locked()):
|
if(self.connectionlock.locked()):
|
||||||
self.connectionlock.release()
|
self.connectionlock.release()
|
||||||
|
|
||||||
@ -304,7 +300,7 @@ class IMAPServer:
|
|||||||
reason = "Could not resolve name '%s' for repository "\
|
reason = "Could not resolve name '%s' for repository "\
|
||||||
"'%s'. Make sure you have configured the ser"\
|
"'%s'. Make sure you have configured the ser"\
|
||||||
"ver name correctly and that you are online."%\
|
"ver name correctly and that you are online."%\
|
||||||
(self.hostname, self.reposname)
|
(self.hostname, self.repos)
|
||||||
raise OfflineImapError(reason, severity)
|
raise OfflineImapError(reason, severity)
|
||||||
|
|
||||||
elif SSLError and isinstance(e, SSLError) and e.errno == 1:
|
elif SSLError and isinstance(e, SSLError) and e.errno == 1:
|
||||||
@ -317,7 +313,7 @@ class IMAPServer:
|
|||||||
else:
|
else:
|
||||||
reason = "Unknown SSL protocol connecting to host '%s' for"\
|
reason = "Unknown SSL protocol connecting to host '%s' for"\
|
||||||
"repository '%s'. OpenSSL responded:\n%s"\
|
"repository '%s'. OpenSSL responded:\n%s"\
|
||||||
% (self.hostname, self.reposname, e)
|
% (self.hostname, self.repos, e)
|
||||||
raise OfflineImapError(reason, severity)
|
raise OfflineImapError(reason, severity)
|
||||||
|
|
||||||
elif isinstance(e, socket.error) and e.args[0] == errno.ECONNREFUSED:
|
elif isinstance(e, socket.error) and e.args[0] == errno.ECONNREFUSED:
|
||||||
@ -333,7 +329,8 @@ class IMAPServer:
|
|||||||
if str(e)[:24] == "can't open socket; error":
|
if str(e)[:24] == "can't open socket; error":
|
||||||
raise OfflineImapError("Could not connect to remote server '%s' "\
|
raise OfflineImapError("Could not connect to remote server '%s' "\
|
||||||
"for repository '%s'. Remote does not answer."
|
"for repository '%s'. Remote does not answer."
|
||||||
% (self.hostname, self.reposname), severity)
|
% (self.hostname, self.repos),
|
||||||
|
OfflineImapError.ERROR.REPO)
|
||||||
else:
|
else:
|
||||||
# re-raise all other errors
|
# re-raise all other errors
|
||||||
raise
|
raise
|
||||||
@ -484,49 +481,3 @@ class IdleThread(object):
|
|||||||
if self.needsync:
|
if self.needsync:
|
||||||
self.event.clear()
|
self.event.clear()
|
||||||
self.dosync()
|
self.dosync()
|
||||||
|
|
||||||
class ConfigedIMAPServer(IMAPServer):
|
|
||||||
"""This class is designed for easier initialization given a ConfigParser
|
|
||||||
object and an account name. The passwordhash is used if
|
|
||||||
passwords for certain accounts are known. If the password for this
|
|
||||||
account is listed, it will be obtained from there."""
|
|
||||||
def __init__(self, repository, passwordhash = {}):
|
|
||||||
"""Initialize the object. If the account is not a tunnel,
|
|
||||||
the password is required."""
|
|
||||||
self.repos = repository
|
|
||||||
self.config = self.repos.getconfig()
|
|
||||||
usetunnel = self.repos.getpreauthtunnel()
|
|
||||||
if not usetunnel:
|
|
||||||
host = self.repos.gethost()
|
|
||||||
user = self.repos.getuser()
|
|
||||||
port = self.repos.getport()
|
|
||||||
ssl = self.repos.getssl()
|
|
||||||
sslclientcert = self.repos.getsslclientcert()
|
|
||||||
sslclientkey = self.repos.getsslclientkey()
|
|
||||||
sslcacertfile = self.repos.getsslcacertfile()
|
|
||||||
reference = self.repos.getreference()
|
|
||||||
idlefolders = self.repos.getidlefolders()
|
|
||||||
server = None
|
|
||||||
password = None
|
|
||||||
|
|
||||||
if repository.getname() in passwordhash:
|
|
||||||
password = passwordhash[repository.getname()]
|
|
||||||
|
|
||||||
# Connect to the remote server.
|
|
||||||
if usetunnel:
|
|
||||||
IMAPServer.__init__(self, self.config, self.repos.getname(),
|
|
||||||
tunnel = usetunnel,
|
|
||||||
reference = reference,
|
|
||||||
idlefolders = idlefolders,
|
|
||||||
maxconnections = self.repos.getmaxconnections())
|
|
||||||
else:
|
|
||||||
if not password:
|
|
||||||
password = self.repos.getpassword()
|
|
||||||
IMAPServer.__init__(self, self.config, self.repos.getname(),
|
|
||||||
user, password, host, port, ssl,
|
|
||||||
self.repos.getmaxconnections(),
|
|
||||||
reference = reference,
|
|
||||||
idlefolders = idlefolders,
|
|
||||||
sslclientcert = sslclientcert,
|
|
||||||
sslclientkey = sslclientkey,
|
|
||||||
sslcacertfile = sslcacertfile)
|
|
||||||
|
@ -33,7 +33,7 @@ class IMAPRepository(BaseRepository):
|
|||||||
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
|
||||||
self.imapserver = imapserver.ConfigedIMAPServer(self)
|
self.imapserver = imapserver.IMAPServer(self)
|
||||||
self.folders = None
|
self.folders = None
|
||||||
self.nametrans = lambda foldername: foldername
|
self.nametrans = lambda foldername: foldername
|
||||||
self.folderfilter = lambda foldername: 1
|
self.folderfilter = lambda foldername: 1
|
||||||
|
Loading…
Reference in New Issue
Block a user