Merge branch 'next'
This commit is contained in:
		| @@ -8,6 +8,18 @@ ChangeLog | ||||
| 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: | ||||
|   - add missing idle_lock in _handler() | ||||
|  | ||||
|   | ||||
| @@ -23,6 +23,12 @@ | ||||
|  | ||||
| # 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 | ||||
| ################################################## | ||||
| @@ -31,6 +37,8 @@ | ||||
|  | ||||
| # This specifies where offlineimap is to store its metadata. | ||||
| # This directory will be created if it does not already exist. | ||||
| # | ||||
| # Tilde and environment variable expansions will be performed. | ||||
|  | ||||
| #metadata = ~/.offlineimap | ||||
|  | ||||
| @@ -89,6 +97,8 @@ accounts = Test | ||||
| # source file and call them from this config file.  You can find | ||||
| # an example of this in the manual. | ||||
| # | ||||
| # Tilde and environment variable expansions will be performed. | ||||
| # | ||||
| # pythonfile = ~/.offlineimap.py | ||||
| # | ||||
|  | ||||
| @@ -135,6 +145,9 @@ accounts = Test | ||||
| # - foldername: the name of the folder; | ||||
| # - localfolders: path to the local directory hosting all Maildir | ||||
| #   folders for the account. | ||||
| # | ||||
| # Tilde and environment variable expansions will be performed | ||||
| # for "filename" knob. | ||||
|  | ||||
| enabled = no | ||||
| filename = ~/Mutt/muttrc.mailboxes | ||||
| @@ -375,9 +388,15 @@ remotehost = examplehost | ||||
| ssl = yes | ||||
|  | ||||
| # SSL Client certificate (optional) | ||||
| # | ||||
| # Tilde and environment variable expansions will be performed. | ||||
|  | ||||
| # sslclientcert = /path/to/file.crt | ||||
|  | ||||
| # SSL Client key (optional) | ||||
| # | ||||
| # Tilde and environment variable expansions will be performed. | ||||
|  | ||||
| # sslclientkey = /path/to/file.key | ||||
|  | ||||
| # 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 | ||||
| # match the hostname (* wildcard allowed on the left hand side) | ||||
| # The certificate should be in PEM format. | ||||
| # | ||||
| # Tilde and environment variable expansions will be performed. | ||||
|  | ||||
| # sslcacertfile = /path/to/cacertfile.crt | ||||
|  | ||||
| # If you connect via SSL/TLS (ssl=true) and you have no CA certificate | ||||
|   | ||||
| @@ -94,14 +94,17 @@ class CustomConfigParser(SafeConfigParser): | ||||
|             return default | ||||
|  | ||||
|     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): | ||||
|             os.mkdir(metadatadir, 0o700) | ||||
|         return metadatadir | ||||
|  | ||||
|     def getlocaleval(self): | ||||
|         xforms = [os.path.expanduser, os.path.expandvars] | ||||
|         if self.has_option("general", "pythonfile"): | ||||
|             path = os.path.expanduser(self.get("general", "pythonfile")) | ||||
|             path = self.apply_xforms(self.get("general", "pythonfile"), xforms) | ||||
|         else: | ||||
|             path = None | ||||
|         return LocalEval(path) | ||||
| @@ -132,6 +135,26 @@ class CustomConfigParser(SafeConfigParser): | ||||
|             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(): | ||||
|     """ | ||||
| @@ -161,9 +184,10 @@ class ConfigHelperMixin: | ||||
|      | ||||
|     """ | ||||
|  | ||||
|  | ||||
|     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(). | ||||
|  | ||||
|         Arguments: | ||||
| @@ -213,27 +237,96 @@ class ConfigHelperMixin: | ||||
|  | ||||
|  | ||||
|     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) | ||||
|   | ||||
| @@ -49,12 +49,14 @@ def write(): | ||||
| def __genmbnames(): | ||||
|     """Takes a configparser object and a boxlist, which is a list of hashes | ||||
|     containing 'accountname' and 'foldername' keys.""" | ||||
|     xforms = [os.path.expanduser, os.path.expandvars] | ||||
|     mblock.acquire() | ||||
|     try: | ||||
|         localeval = config.getlocaleval() | ||||
|         if not config.getdefaultboolean("mbnames", "enabled", 0): | ||||
|             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"))) | ||||
|         folderfilter = lambda accountname, foldername: 1 | ||||
|         if config.has_option("mbnames", "folderfilter"): | ||||
|   | ||||
| @@ -194,18 +194,20 @@ class IMAPRepository(BaseRepository): | ||||
|         return self.getconfboolean('ssl', 0) | ||||
|  | ||||
|     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): | ||||
|         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): | ||||
|         """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: | ||||
|             return None | ||||
|         cacertfile = os.path.expanduser(cacertfile) | ||||
|         cacertfile = os.path.abspath(cacertfile) | ||||
|         if not os.path.isfile(cacertfile): | ||||
|             raise SyntaxWarning("CA certfile for repository '%s' could " | ||||
|                                 "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))) | ||||
|  | ||||
|     def getlocalroot(self): | ||||
|         return os.path.expanduser(self.getconf('localfolders')) | ||||
|         xforms = [os.path.expanduser] | ||||
|         return self.getconf_xform('localfolders', xforms) | ||||
|  | ||||
|     def debug(self, msg): | ||||
|         self.ui.debug('maildir', msg) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Eygene Ryabinkin
					Eygene Ryabinkin