summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/util/config.py170
1 files changed, 128 insertions, 42 deletions
diff --git a/src/leap/util/config.py b/src/leap/util/config.py
index ab91a60..a762853 100644
--- a/src/leap/util/config.py
+++ b/src/leap/util/config.py
@@ -1,69 +1,155 @@
#! -*- encoding: utf-8 -*-
"""
-xxx fill me in
+Config file utilities.
+
+This module has an :attr:`config_filename`, which can be used to set the
+filename outside of function calls:
+
+ >>> from leap.mx.util import config
+ >>> config.config_filename = "blahblah.yaml"
+
+If not set anywhere, it will default to using the top level repository
+directory, i.e. "/.../leap_mx/leap_mx.conf", and will create that file with
+the default settings if it does not exist.
+
+The config file can be loaded/created with :func:`config.loadConfig`:
+
+ >>> config.loadConfig()
+
+Once the config file is loaded, this module presents a highly object-oriented
+interface, so that sections taken from the config file become attribute of
+this module, and the name of their respective settings become attributes of
+the section names. Like this:
+
+ >>> print config.basic.postfix_port
+ 465
+
+@authors: Isis Lovecruft, <isis@leap.se> 0x2cdb8b35
+@version: 0.0.1
+@license: see included LICENSE file
"""
+
import os
import yaml
-from leap.util import log, version
+## xxx only install/import this in *nix
+from xdg import BaseDirectory
-config_filename = 'mx.conf'
+from leap.util import log, version, Storage
+from leap.util.exceptions import MissingConfig, UnsupportedOS
-class MissingConfig(Exception):
- """Raised when the config file cannot be found."""
- def __init__(self, message=None, config_file=None):
- if message:
- return
- else:
- self.message = "Cannot locate config file"
- if config_file:
- self.message += " %s" % config_file
- self.message += "."
-def getConfigFilename(dir=None, file=None):
+def _create_config_file(file):
"""
xxx fill me in
"""
- if not dir:
- dir = version.getRepoDir()
- if not file:
- file = config_filename
- return os.path.join(dir, file)
-
-def createConfigFile(config_file=None):
- """
- xxx fill me in
- """
- if not config_file:
- config_file = getConfigFilename()
-
- if not os.path.isfile(config_file):
- with open(config_file, 'w+') as conf:
- conf.write("""
+ with open(file, 'w+') as conf:
+ conf.write("""
#
# mx.conf
# =======
# Configurable options for the leap_mx encrypting mail exchange.
#
""")
- conf.flush()
+ conf.flush()
+ try:
+ assert os.path.isfile(file), "Config file %s not created!" % file
+ except AssertionError, ae:
+ raise SystemExit(ae.message)
else:
- log.debug("Config file %s already present." % config_file)
+ return file
-def loadConfigFile(config_file=None):
+def _get_config_filename(filename=None, use_dot_config_directory=False):
"""
- xxx fill me in
+ Get the full path and filename of the config file.
"""
- if not config_file:
- config_file = getConfigFilename()
+ platform = version.getClientPlatform()[0]
+ resource = version.name
- if os.path.isfile(config_file):
- with open(config_file, 'a+') as conf:
+ ## Oh hell, it could be said only to beguile:
+ ## That windoze users are capable of editing a .conf file.
+ ## Also, what maddened wingnut would be so fool
+ ## To run a mail exchange on a windoze nodule?
+ ## I'm ignoring these loons for now. And pardon if I seem jaded,
+ ## But srsly, this and that solaris sh*t should be deprecated.
+ if not platform.endswith('LINUX') and not platform.endswith('BSD'):
+ raise UnsupportedOS("Sorry, your operating system isn't supported.")
+
+ ## If not given, default to the application's name + '.conf'
+ if not filename:
+ filename = resource + ".conf"
+
+ where = None
+ if not use_dot_config_directory:
+ repo_dir = version.getRepoDir()
+ where = os.path.abspath(repo_dir)
+ ## Use ~/.config/ instead:
+ else:
+ dot_config_dirs = BaseDirectory.xdg_config_dirs
+ for dir in dot_config_dirs:
+ our_dir = os.path.join(dir, resource)
+ if os.path.isdir(our_dir):
+ if filename in os.listdir(our_dir):
+ where = os.path.abspath(our_dir)
+ if not where:
+ where = BaseDirectory.save_config_path(resource)
+
+ conffile = os.path.join(where, filename)
+ try:
+ with open(conffile) as cf: pass
+ except IOError:
+ conffile = _create_config_file(conffile)
+ finally:
+ return conffile
+
+def loadConfig(filename=config_filename):
+ """
+ Some of this is taken from OONI config code for now, and so this should be
+ refacotored, along with the leap_client config code, so that we have
+ similarly structured config files. It is perhaps desirable to also use
+ soledad as a backend for remote setup and maintainance, and thus this code
+ will need to hook into u1db (and potentially "pysqlcipher").
+
+ Excuse the yaml for now, I just wanted something that works.
+
+ @param filename: (optional) If provided, use this filename.
+ """
+ if not filename:
+ filename = _get_config_filename()
+
+ if os.path.isfile(filename):
+ with open(filename, 'a+') as conf:
config_contents = '\n'.join(conf.readlines())
configuration = yaml.safe_load(config_contents)
+
+ ## These become objects with their keys loaded as attributes:
+ ##
+ ## from leap.util import config
+ ## config.basic.foo = bar
+ ##
+ basic = Storage()
+ try:
+ for k, v in configuration['basic'].items():
+ basic[k] = v
+ except AttributeError:
+ pass
+
+ advanced = Storage()
+ try:
+ for k, v in configuration['advanced'].items():
+ advanced[k] = v
+ except AttributeError:
+ pass
+
+ return basic, advanced
else:
- createConfigFile(config_file)
+ raise MissingConfig("Could not load config file.")
+
+
+## This is the name of the config file to use:
+## If not set, it defaults to 'leap_mx/leap_mx.conf'
+if not config_filename:
+ config_filename = _get_config_filename()
+else:
+ config_filename = _get_config_filename(filename=config_filename)
- ## xxx finish load config
- ## ask kali if we're using yaml or json or what?
- ## xxx kali says json, so ixnay on the amlya bits