123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- # Copyright (C) 2003-2016 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
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- import os
- import re
- from sys import exc_info
- from configparser import ConfigParser, Error
- from offlineimap.localeval import LocalEval
- class CustomConfigParser(ConfigParser):
- def __init__(self):
- ConfigParser.__init__(self)
- self.localeval = None
- def getdefault(self, section, option, default, *args, **kwargs):
- """Same as config.get, but returns the value of `default`
- if there is no such option specified."""
- if self.has_option(section, option):
- return self.get(*(section, option) + args, **kwargs)
- else:
- return default
- def getdefaultint(self, section, option, default, *args, **kwargs):
- """Same as config.getint, but returns the value of `default`
- if there is no such option specified."""
- if self.has_option(section, option):
- return self.getint(*(section, option) + args, **kwargs)
- else:
- return default
- def getdefaultfloat(self, section, option, default, *args, **kwargs):
- """Same as config.getfloat, but returns the value of `default`
- if there is no such option specified."""
- if self.has_option(section, option):
- return self.getfloat(*(section, option) + args, **kwargs)
- else:
- return default
- def getdefaultboolean(self, section, option, default, *args, **kwargs):
- """Same as config.getboolean, but returns the value of `default`
- if there is no such option specified."""
- if self.has_option(section, option):
- return self.getboolean(*(section, option) + args, **kwargs)
- else:
- return default
- def getlist(self, section, option, separator_re):
- """Parses option as the list of values separated
- by the given regexp."""
- try:
- val = self.get(section, option).strip()
- return re.split(separator_re, val)
- except re.error as e:
- raise Error("Bad split regexp '%s': %s" %
- (separator_re, e), exc_info()[2])
- def getdefaultlist(self, section, option, default, separator_re):
- """Same as getlist, but returns the value of `default`
- if there is no such option specified."""
- if self.has_option(section, option):
- return self.getlist(*(section, option, separator_re))
- else:
- return default
- def getmetadatadir(self):
- 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):
- os.mkdir(metadatadir, 0o700)
- return metadatadir
- def getlocaleval(self):
- # We already loaded pythonfile, so return this copy.
- if self.localeval is not None:
- return self.localeval
- xforms = [os.path.expanduser, os.path.expandvars]
- if self.has_option("general", "pythonfile"):
- path = self.get("general", "pythonfile")
- path = self.apply_xforms(path, xforms)
- else:
- path = None
- self.localeval = LocalEval(path)
- return self.localeval
- def getsectionlist(self, key):
- """Returns a list of sections that start with (str) key + " ".
- That is, if key is "Account", returns all section names that
- start with "Account ", but strips off the "Account ".
- For instance, for "Account Test", returns "Test"."""
- key = key + ' '
- return [x[len(key):] for x in self.sections()
- if x.startswith(key)]
- def set_if_not_exists(self, section, option, value):
- """Set a value if it does not exist yet.
- This allows to set default if the user has not explicitly
- configured anything."""
- if not self.has_option(section, option):
- 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 is None:
- return None
- for f in transforms:
- string = f(string)
- return string
- def CustomConfigDefault():
- """Just a constant that won't occur anywhere else.
- This allows us to differentiate if the user has passed in any
- default value to the getconf* functions in ConfigHelperMixin
- derived classes."""
- pass
- class ConfigHelperMixin:
- """Allow comfortable retrieving of config values pertaining
- to a section.
- If a class inherits from cls:`ConfigHelperMixin`, it needs
- to provide 2 functions:
- - meth:`getconfig` (returning a CustomConfigParser object)
- - and meth:`getsection` (returning a string which represents
- the section to look up).
- All calls to getconf* will then return the configuration values
- for the CustomConfigParser object in the specific section.
- """
- def _confighelper_runner(self, option, default, defaultfunc, mainfunc, *args):
- """Returns configuration or default value for option
- that contains in section identified by getsection().
- Arguments:
- - option: name of the option to retrieve;
- - default: governs which function we will call.
- * When CustomConfigDefault is passed, we will call
- the mainfunc.
- * When any other value is passed, we will call
- the defaultfunc and the value of `default` will
- be passed as the third argument to this function.
- - defaultfunc and mainfunc: processing helpers.
- - args: additional trailing arguments that will be passed
- to all processing helpers.
- """
- lst = [self.getsection(), option]
- if default == CustomConfigDefault:
- return mainfunc(*(lst + list(args)))
- else:
- lst.append(default)
- return defaultfunc(*(lst + list(args)))
- def getconfig(self):
- """Returns CustomConfigParser object that we will use
- for all our actions.
- Must be overriden in all classes that use this mix-in."""
- raise NotImplementedError("ConfigHelperMixin.getconfig() "
- "is to be overriden")
- def getsection(self):
- """Returns name of configuration section in which our
- class keeps its configuration.
- Must be overriden in all classes that use this mix-in."""
- raise NotImplementedError("ConfigHelperMixin.getsection() "
- "is to be overriden")
- 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,
- self.getconfig().getdefault,
- 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):
- """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,
- self.getconfig().getdefaultboolean,
- self.getconfig().getboolean)
- 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,
- self.getconfig().getdefaultint,
- self.getconfig().getint)
- 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,
- self.getconfig().getdefaultfloat,
- self.getconfig().getfloat)
- def getconflist(self, option, separator_re,
- 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,
- self.getconfig().getdefaultlist,
- self.getconfig().getlist, separator_re)
|