summaryrefslogtreecommitdiff
path: root/src/mailman/config/config.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/config/config.py')
-rw-r--r--src/mailman/config/config.py84
1 files changed, 55 insertions, 29 deletions
diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py
index 3b662553e..0293dacd4 100644
--- a/src/mailman/config/config.py
+++ b/src/mailman/config/config.py
@@ -22,15 +22,17 @@ from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'Configuration',
+ 'external_configuration',
+ 'load_external'
]
import os
import sys
-from ConfigParser import SafeConfigParser
+from ConfigParser import SafeConfigParser
from lazr.config import ConfigSchema, as_boolean
-from pkg_resources import resource_stream, resource_exists
+from pkg_resources import resource_filename, resource_stream, resource_string
from string import Template
from zope.component import getUtility
from zope.event import notify
@@ -40,7 +42,7 @@ import mailman.templates
from mailman import version
from mailman.interfaces.configuration import (
- ConfigurationUpdatedEvent, IConfiguration)
+ ConfigurationUpdatedEvent, IConfiguration, MissingConfigurationFileError)
from mailman.interfaces.languages import ILanguageManager
from mailman.utilities.filesystem import makedirs
from mailman.utilities.modules import call_name
@@ -237,30 +239,54 @@ class Configuration:
for section in self._config.getByCategory('language', []):
yield section
- def get_additional_config(self, name, keyname):
- """Return an external ini-file as specified by the keyname."""
- add_config = SafeConfigParser()
- if resource_exists('mailman.config', '%s.cfg' % name):
- included_config_file = resource_stream('mailman.config',
- '%s.cfg' % name)
- add_config.readfp(included_config_file)
- # Resolve the path value from the key name
- path = self._config
- for key in keyname.split("."):
- path = getattr(path, key)
- # Load the file
- configured_path = os.path.expanduser(path) # TODO: allow URLs
- if not configured_path.startswith("/"):
- # Consider it relative to the mailman.cfg file
- for overlay in self.overlays:
- if os.sep in overlay.filename:
- configured_path = os.path.join(
- os.path.dirname(overlay.filename),
- configured_path)
- break
- r = add_config.read([configured_path])
- return add_config
- def archiver_config(self, name):
- """A shortcut to self.get_additional_config() for achivers."""
- return self.get_additional_config(name, "archiver.%s.configure" % name)
+
+def load_external(path, encoding=None):
+ """Load the configuration file named by path.
+
+ :param path: A string naming the location of the external configuration
+ file. This is either an absolute file system path or a special
+ ``python:`` path. When path begins with ``python:``, the rest of the
+ value must name a ``.cfg`` file located within Python's import path,
+ however the trailing ``.cfg`` suffix is implied (don't provide it
+ here).
+ :param encoding: The encoding to apply to the data read from path. If
+ None, then bytes will be returned.
+ :return: A unicode string or bytes, depending on ``encoding``.
+ """
+ # Is the context coming from a file system or Python path?
+ if path.startswith('python:'):
+ resource_path = path[7:]
+ package, dot, resource = resource_path.rpartition('.')
+ config_string = resource_string(package, resource + '.cfg')
+ else:
+ with open(path, 'rb') as fp:
+ config_string = fp.read()
+ if encoding is None:
+ return config_string
+ return config_string.decode(encoding)
+
+
+def external_configuration(path):
+ """Parse the configuration file named by path.
+
+ :param path: A string naming the location of the external configuration
+ file. This is either an absolute file system path or a special
+ ``python:`` path. When path begins with ``python:``, the rest of the
+ value must name a ``.cfg`` file located within Python's import path,
+ however the trailing ``.cfg`` suffix is implied (don't provide it
+ here).
+ :return: A `ConfigParser` instance.
+ """
+ # Is the context coming from a file system or Python path?
+ if path.startswith('python:'):
+ resource_path = path[7:]
+ package, dot, resource = resource_path.rpartition('.')
+ cfg_path = resource_filename(package, resource + '.cfg')
+ else:
+ cfg_path = path
+ parser = SafeConfigParser()
+ files = parser.read(cfg_path)
+ if files != [cfg_path]:
+ raise MissingConfigurationFileError(path)
+ return parser