4
updated: April 24, 2011
6
Reads and writes config files in a simple (key = value) or just (key) for boolean
7
properties, and notifies listeners when the values are changed.
14
from gi.repository import GObject
15
from threading import Lock
17
logger = logging.getLogger("Config")
19
class ConfigException(Exception):
22
class Config(GObject.GObject):
25
"value-changed": (GObject.SignalFlags.RUN_LAST, None, [str, str])
27
def __init__(self, path):
28
GObject.GObject.__init__(self)
30
self._path = os.path.expanduser(path)
36
def __contains__(self, key):
37
"""Returns true if this config has the given key."""
38
return key in self._options
41
"""Returns an iterator over the keys of this Config object."""
42
return iter(self._options)
45
"""Loads a config file, if it exists."""
47
f = open(self._path, "r")
49
logger.warning("Failed to open config file: {0}".format(self._path))
57
if line.strip() == "":
60
item = line.split("=", 1)
66
value = item[1].strip()
70
raise ConfigException("Empty key on line {0}: {1}".format(line_number, line.strip()))
72
self._options[key] = value
73
self.emit("value-changed", key, value)
76
logger.exception("Error reading config file: {0}".format(self._path))
80
"""Saves the config file, creating the destination directory if necessary."""
81
# Create the destination directory
82
dirname = os.path.dirname(self._path)
84
os.makedirs(dirname, 0700)
86
if e.errno != errno.EEXIST:
87
logger.error("Failed to create directory: {0}".format(dirname))
90
with open(self._path, "w") as f:
91
for key, value in self._options.items():
92
f.write("{0} = {1}\n".format(key, value))
94
def get(self, key, default = ""):
95
"""Returns the value of the given key, or the default value."""
96
if key in self._options:
97
return self._options[key]
101
def get_bool(self, key, default = False):
102
"""Returns the value of the given key as a boolean, or the default value if it fails
103
to convert or does not exist."""
104
if key not in self._options:
106
value = self._options[key]
107
if value == True or value == "True":
109
elif value == False or value == "False":
114
def get_int(self, key, default = 0):
115
"""Returns this value of the given key as an int, or the default value if it fails to
116
convert or does not exist."""
117
if key not in self._options:
119
value = self._options[key]
125
def set(self, key, value):
126
"""Sets the value for the given key, saves the config file and notifies any
127
listeners that the value has changed."""
128
if not (isinstance(key, str) or isinstance(key, unicode)):
129
raise ConfigException("Trying to set a non-string key: {0} = {1}".format(key, value))
133
raise ConfigException("Trying to set empty key to value: {0}".format(value))
136
self._options[key] = value
138
self.emit("value-changed", key, value)
140
def set_if_unset(self, key, value):
141
"""Calls set(key, value) only if the key does not exist in this config."""
142
if key not in self._options: