Merge branch 'next'
This commit is contained in:
commit
50b727b15c
@ -8,6 +8,18 @@ ChangeLog
|
|||||||
OfflineIMAP v6.5.6.1 (YYYY-MM-DD)
|
OfflineIMAP v6.5.6.1 (YYYY-MM-DD)
|
||||||
=================================
|
=================================
|
||||||
|
|
||||||
|
* Expand environment variables in the following
|
||||||
|
configuration items:
|
||||||
|
- general.pythonfile;
|
||||||
|
- general.metadata;
|
||||||
|
- mbnames.filename;
|
||||||
|
- Repository.localfolders.
|
||||||
|
- Repository.sslcacertfile.
|
||||||
|
Make tilde and environment variable expansion in the following
|
||||||
|
configuration items:
|
||||||
|
- Repository.sslclientcert;
|
||||||
|
- Repository.sslclientkey.
|
||||||
|
|
||||||
* Updated bundled imaplib2 to 2.37:
|
* Updated bundled imaplib2 to 2.37:
|
||||||
- add missing idle_lock in _handler()
|
- add missing idle_lock in _handler()
|
||||||
|
|
||||||
|
@ -23,6 +23,12 @@
|
|||||||
|
|
||||||
# NOTE2: This implies that any '%' needs to be encoded as '%%'
|
# NOTE2: This implies that any '%' needs to be encoded as '%%'
|
||||||
|
|
||||||
|
# NOTE3: Any variables that are subject to the environment variables
|
||||||
|
# ($NAME) and tilde (~username/~) expansions will receive tilde
|
||||||
|
# expansion first and only after this environment variables will be
|
||||||
|
# expanded in the resulting string. This behaviour is intentional
|
||||||
|
# as it coincides with typical shell expansion strategy.
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# General definitions
|
# General definitions
|
||||||
##################################################
|
##################################################
|
||||||
@ -31,6 +37,8 @@
|
|||||||
|
|
||||||
# This specifies where offlineimap is to store its metadata.
|
# This specifies where offlineimap is to store its metadata.
|
||||||
# This directory will be created if it does not already exist.
|
# This directory will be created if it does not already exist.
|
||||||
|
#
|
||||||
|
# Tilde and environment variable expansions will be performed.
|
||||||
|
|
||||||
#metadata = ~/.offlineimap
|
#metadata = ~/.offlineimap
|
||||||
|
|
||||||
@ -89,6 +97,8 @@ accounts = Test
|
|||||||
# source file and call them from this config file. You can find
|
# source file and call them from this config file. You can find
|
||||||
# an example of this in the manual.
|
# an example of this in the manual.
|
||||||
#
|
#
|
||||||
|
# Tilde and environment variable expansions will be performed.
|
||||||
|
#
|
||||||
# pythonfile = ~/.offlineimap.py
|
# pythonfile = ~/.offlineimap.py
|
||||||
#
|
#
|
||||||
|
|
||||||
@ -135,6 +145,9 @@ accounts = Test
|
|||||||
# - foldername: the name of the folder;
|
# - foldername: the name of the folder;
|
||||||
# - localfolders: path to the local directory hosting all Maildir
|
# - localfolders: path to the local directory hosting all Maildir
|
||||||
# folders for the account.
|
# folders for the account.
|
||||||
|
#
|
||||||
|
# Tilde and environment variable expansions will be performed
|
||||||
|
# for "filename" knob.
|
||||||
|
|
||||||
enabled = no
|
enabled = no
|
||||||
filename = ~/Mutt/muttrc.mailboxes
|
filename = ~/Mutt/muttrc.mailboxes
|
||||||
@ -375,9 +388,15 @@ remotehost = examplehost
|
|||||||
ssl = yes
|
ssl = yes
|
||||||
|
|
||||||
# SSL Client certificate (optional)
|
# SSL Client certificate (optional)
|
||||||
|
#
|
||||||
|
# Tilde and environment variable expansions will be performed.
|
||||||
|
|
||||||
# sslclientcert = /path/to/file.crt
|
# sslclientcert = /path/to/file.crt
|
||||||
|
|
||||||
# SSL Client key (optional)
|
# SSL Client key (optional)
|
||||||
|
#
|
||||||
|
# Tilde and environment variable expansions will be performed.
|
||||||
|
|
||||||
# sslclientkey = /path/to/file.key
|
# sslclientkey = /path/to/file.key
|
||||||
|
|
||||||
# SSL CA Cert(s) to verify the server cert against (optional).
|
# SSL CA Cert(s) to verify the server cert against (optional).
|
||||||
@ -385,6 +404,9 @@ ssl = yes
|
|||||||
# specified, the CA Cert(s) need to verify the Server cert AND
|
# specified, the CA Cert(s) need to verify the Server cert AND
|
||||||
# match the hostname (* wildcard allowed on the left hand side)
|
# match the hostname (* wildcard allowed on the left hand side)
|
||||||
# The certificate should be in PEM format.
|
# The certificate should be in PEM format.
|
||||||
|
#
|
||||||
|
# Tilde and environment variable expansions will be performed.
|
||||||
|
|
||||||
# sslcacertfile = /path/to/cacertfile.crt
|
# sslcacertfile = /path/to/cacertfile.crt
|
||||||
|
|
||||||
# If you connect via SSL/TLS (ssl=true) and you have no CA certificate
|
# If you connect via SSL/TLS (ssl=true) and you have no CA certificate
|
||||||
|
@ -94,14 +94,17 @@ class CustomConfigParser(SafeConfigParser):
|
|||||||
return default
|
return default
|
||||||
|
|
||||||
def getmetadatadir(self):
|
def getmetadatadir(self):
|
||||||
metadatadir = os.path.expanduser(self.getdefault("general", "metadata", "~/.offlineimap"))
|
xforms = [os.path.expanduser, os.path.expandvars]
|
||||||
|
d = self.getdefault("general", "metadata", "~/.offlineimap")
|
||||||
|
metadatadir = self.apply_xforms(d, xforms)
|
||||||
if not os.path.exists(metadatadir):
|
if not os.path.exists(metadatadir):
|
||||||
os.mkdir(metadatadir, 0o700)
|
os.mkdir(metadatadir, 0o700)
|
||||||
return metadatadir
|
return metadatadir
|
||||||
|
|
||||||
def getlocaleval(self):
|
def getlocaleval(self):
|
||||||
|
xforms = [os.path.expanduser, os.path.expandvars]
|
||||||
if self.has_option("general", "pythonfile"):
|
if self.has_option("general", "pythonfile"):
|
||||||
path = os.path.expanduser(self.get("general", "pythonfile"))
|
path = self.apply_xforms(self.get("general", "pythonfile"), xforms)
|
||||||
else:
|
else:
|
||||||
path = None
|
path = None
|
||||||
return LocalEval(path)
|
return LocalEval(path)
|
||||||
@ -132,6 +135,26 @@ class CustomConfigParser(SafeConfigParser):
|
|||||||
self.set(section, option, value)
|
self.set(section, option, value)
|
||||||
|
|
||||||
|
|
||||||
|
def apply_xforms(self, string, transforms):
|
||||||
|
"""
|
||||||
|
Applies set of transformations to a string.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- string: source string; if None, then no processing will
|
||||||
|
take place.
|
||||||
|
- transforms: iterable that returns transformation function
|
||||||
|
on each turn.
|
||||||
|
|
||||||
|
Returns transformed string.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if string == None:
|
||||||
|
return None
|
||||||
|
for f in transforms:
|
||||||
|
string = f(string)
|
||||||
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def CustomConfigDefault():
|
def CustomConfigDefault():
|
||||||
"""
|
"""
|
||||||
@ -161,9 +184,10 @@ class ConfigHelperMixin:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def _confighelper_runner(self, option, default, defaultfunc, mainfunc, *args):
|
def _confighelper_runner(self, option, default, defaultfunc, mainfunc, *args):
|
||||||
"""
|
"""
|
||||||
Return configuration or default value for option
|
Returns configuration or default value for option
|
||||||
that contains in section identified by getsection().
|
that contains in section identified by getsection().
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
@ -213,27 +237,96 @@ class ConfigHelperMixin:
|
|||||||
|
|
||||||
|
|
||||||
def getconf(self, option, default = CustomConfigDefault):
|
def getconf(self, option, default = CustomConfigDefault):
|
||||||
|
"""
|
||||||
|
Retrieves string from the configuration.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- option: option name whose value is to be retrieved;
|
||||||
|
- default: default return value if no such option
|
||||||
|
exists.
|
||||||
|
|
||||||
|
"""
|
||||||
return self._confighelper_runner(option, default,
|
return self._confighelper_runner(option, default,
|
||||||
self.getconfig().getdefault,
|
self.getconfig().getdefault,
|
||||||
self.getconfig().get)
|
self.getconfig().get)
|
||||||
|
|
||||||
|
|
||||||
|
def getconf_xform(self, option, xforms, default = CustomConfigDefault):
|
||||||
|
"""
|
||||||
|
Retrieves string from the configuration transforming the result.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- option: option name whose value is to be retrieved;
|
||||||
|
- xforms: iterable that returns transform functions
|
||||||
|
to be applied to the value of the option,
|
||||||
|
both retrieved and default one;
|
||||||
|
- default: default value for string if no such option
|
||||||
|
exists.
|
||||||
|
|
||||||
|
"""
|
||||||
|
value = self.getconf(option, default)
|
||||||
|
return self.getconfig().apply_xforms(value, xforms)
|
||||||
|
|
||||||
|
|
||||||
def getconfboolean(self, option, default = CustomConfigDefault):
|
def getconfboolean(self, option, default = CustomConfigDefault):
|
||||||
|
"""
|
||||||
|
Retrieves boolean value from the configuration.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- option: option name whose value is to be retrieved;
|
||||||
|
- default: default return value if no such option
|
||||||
|
exists.
|
||||||
|
|
||||||
|
"""
|
||||||
return self._confighelper_runner(option, default,
|
return self._confighelper_runner(option, default,
|
||||||
self.getconfig().getdefaultboolean,
|
self.getconfig().getdefaultboolean,
|
||||||
self.getconfig().getboolean)
|
self.getconfig().getboolean)
|
||||||
|
|
||||||
|
|
||||||
def getconfint(self, option, default = CustomConfigDefault):
|
def getconfint(self, option, default = CustomConfigDefault):
|
||||||
|
"""
|
||||||
|
Retrieves integer value from the configuration.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- option: option name whose value is to be retrieved;
|
||||||
|
- default: default return value if no such option
|
||||||
|
exists.
|
||||||
|
|
||||||
|
"""
|
||||||
return self._confighelper_runner(option, default,
|
return self._confighelper_runner(option, default,
|
||||||
self.getconfig().getdefaultint,
|
self.getconfig().getdefaultint,
|
||||||
self.getconfig().getint)
|
self.getconfig().getint)
|
||||||
|
|
||||||
|
|
||||||
def getconffloat(self, option, default = CustomConfigDefault):
|
def getconffloat(self, option, default = CustomConfigDefault):
|
||||||
|
"""
|
||||||
|
Retrieves floating-point value from the configuration.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- option: option name whose value is to be retrieved;
|
||||||
|
- default: default return value if no such option
|
||||||
|
exists.
|
||||||
|
|
||||||
|
"""
|
||||||
return self._confighelper_runner(option, default,
|
return self._confighelper_runner(option, default,
|
||||||
self.getconfig().getdefaultfloat,
|
self.getconfig().getdefaultfloat,
|
||||||
self.getconfig().getfloat)
|
self.getconfig().getfloat)
|
||||||
|
|
||||||
|
|
||||||
def getconflist(self, option, separator_re,
|
def getconflist(self, option, separator_re,
|
||||||
default = CustomConfigDefault):
|
default = CustomConfigDefault):
|
||||||
|
"""
|
||||||
|
Retrieves strings from the configuration and splits it
|
||||||
|
into the list of strings.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
- option: option name whose value is to be retrieved;
|
||||||
|
- separator_re: regular expression for separator
|
||||||
|
to be used for split operation;
|
||||||
|
- default: default return value if no such option
|
||||||
|
exists.
|
||||||
|
|
||||||
|
"""
|
||||||
return self._confighelper_runner(option, default,
|
return self._confighelper_runner(option, default,
|
||||||
self.getconfig().getdefaultlist,
|
self.getconfig().getdefaultlist,
|
||||||
self.getconfig().getlist, separator_re)
|
self.getconfig().getlist, separator_re)
|
||||||
|
@ -49,12 +49,14 @@ def write():
|
|||||||
def __genmbnames():
|
def __genmbnames():
|
||||||
"""Takes a configparser object and a boxlist, which is a list of hashes
|
"""Takes a configparser object and a boxlist, which is a list of hashes
|
||||||
containing 'accountname' and 'foldername' keys."""
|
containing 'accountname' and 'foldername' keys."""
|
||||||
|
xforms = [os.path.expanduser, os.path.expandvars]
|
||||||
mblock.acquire()
|
mblock.acquire()
|
||||||
try:
|
try:
|
||||||
localeval = config.getlocaleval()
|
localeval = config.getlocaleval()
|
||||||
if not config.getdefaultboolean("mbnames", "enabled", 0):
|
if not config.getdefaultboolean("mbnames", "enabled", 0):
|
||||||
return
|
return
|
||||||
file = open(os.path.expanduser(config.get("mbnames", "filename")), "wt")
|
path = config.apply_xform(config.get("mbnames", "filename"), xforms)
|
||||||
|
file = open(path, "wt")
|
||||||
file.write(localeval.eval(config.get("mbnames", "header")))
|
file.write(localeval.eval(config.get("mbnames", "header")))
|
||||||
folderfilter = lambda accountname, foldername: 1
|
folderfilter = lambda accountname, foldername: 1
|
||||||
if config.has_option("mbnames", "folderfilter"):
|
if config.has_option("mbnames", "folderfilter"):
|
||||||
|
@ -194,18 +194,20 @@ class IMAPRepository(BaseRepository):
|
|||||||
return self.getconfboolean('ssl', 0)
|
return self.getconfboolean('ssl', 0)
|
||||||
|
|
||||||
def getsslclientcert(self):
|
def getsslclientcert(self):
|
||||||
return self.getconf('sslclientcert', None)
|
xforms = [os.path.expanduser, os.path.expandvars, os.path.abspath]
|
||||||
|
return self.getconf_xform('sslclientcert', xforms, None)
|
||||||
|
|
||||||
def getsslclientkey(self):
|
def getsslclientkey(self):
|
||||||
return self.getconf('sslclientkey', None)
|
xforms = [os.path.expanduser, os.path.expandvars, os.path.abspath]
|
||||||
|
return self.getconf_xform('sslclientkey', xforms, None)
|
||||||
|
|
||||||
def getsslcacertfile(self):
|
def getsslcacertfile(self):
|
||||||
"""Return the absolute path of the CA certfile to use, if any"""
|
"""Return the absolute path of the CA certfile to use, if any"""
|
||||||
cacertfile = self.getconf('sslcacertfile', get_os_sslcertfile())
|
xforms = [os.path.expanduser, os.path.expandvars, os.path.abspath]
|
||||||
|
cacertfile = self.getconf_xform('sslcacertfile', xforms,
|
||||||
|
get_os_sslcertfile())
|
||||||
if cacertfile is None:
|
if cacertfile is None:
|
||||||
return None
|
return None
|
||||||
cacertfile = os.path.expanduser(cacertfile)
|
|
||||||
cacertfile = os.path.abspath(cacertfile)
|
|
||||||
if not os.path.isfile(cacertfile):
|
if not os.path.isfile(cacertfile):
|
||||||
raise SyntaxWarning("CA certfile for repository '%s' could "
|
raise SyntaxWarning("CA certfile for repository '%s' could "
|
||||||
"not be found. No such file: '%s'" \
|
"not be found. No such file: '%s'" \
|
||||||
|
@ -61,7 +61,8 @@ class MaildirRepository(BaseRepository):
|
|||||||
os.utime(cur_dir, (cur_atime, os.path.getmtime(cur_dir)))
|
os.utime(cur_dir, (cur_atime, os.path.getmtime(cur_dir)))
|
||||||
|
|
||||||
def getlocalroot(self):
|
def getlocalroot(self):
|
||||||
return os.path.expanduser(self.getconf('localfolders'))
|
xforms = [os.path.expanduser]
|
||||||
|
return self.getconf_xform('localfolders', xforms)
|
||||||
|
|
||||||
def debug(self, msg):
|
def debug(self, msg):
|
||||||
self.ui.debug('maildir', msg)
|
self.ui.debug('maildir', msg)
|
||||||
|
Loading…
Reference in New Issue
Block a user