jasperproject/jasper-client — pull request #128 by Holzhaus (2014-08-11 13:14:42+00:00)
Title: Add proper config module

# Rationale

Jasper really needs a proper config module.

I saw multiple errors caused by modules/classes/functions trying to access the yaml-configuration looking for values that were not set (e.g. `gmail_address`). This means that we'll end up writing checking functions all over the place or using a general `try: ... except: ... `-block wrapped around `Conversation.handleForever()` (which currently prevents us from killing Jasper with CRTL-C by the way).

So the obvious solution is to create a new module (named `jasperconf` in this case), that does this kind of stuff for us. It offers us a config singleton, which relieves us from the obligation to pass around the `profile`-variable or open the config file every time we need a value.

It also adds proper separation between main and plugin namespace in the config file (all plugins access the config via `plugin_get`/`plugin_set` methods, which retrieves and sets value in `plugins` → `plugin_name` → x.
If that namespace should ever be changed - no problem, just change the jasperconf module and probably add a conversion for old config files.

Last (and probably least), it also decouples the access to config values from the actual backend (YAML) and thus makes a transition - if neccessary - (e.g. to ConfigParser) a lot easier.

# Usage
## Main program
```Python
from jasperconf import Config as conf
firstname = conf.get("firstname")
# Alternative:
# firstname = conf.get(["firstname"])
conf.set(["keys","GOOGLE_SPEECH"], value="ABCDEF" )
google_api_key = conf.get(["keys", "GOOGLE_SPEECH"])
```
## Plugins (in client/modules)
```Python
PLUGIN_NAME = "foo"

from ..jasperconf import Config as conf
bar = conf.plugin_get(PLUGIN_NAME, "bar")
# Alternative:
# bar = conf.plugin_get(PLUGIN_NAME, ["bar"])
conf.plugin_set(PLUGIN_NAME, ['example','baz'], value="Doh!")
doh = conf.plugin_get(PLUGIN_NAME, ['example','baz'])
```