manager.py
90 lines
| 2.5 KiB
| text/x-python
|
PythonLexer
Thomas Kluyver
|
r19083 | """Manager to read and modify frontend config data in JSON files. | ||
""" | ||||
# Copyright (c) IPython Development Team. | ||||
# Distributed under the terms of the Modified BSD License. | ||||
import errno | ||||
import io | ||||
import json | ||||
import os | ||||
from IPython.config import LoggingConfigurable | ||||
Thomas Kluyver
|
r19084 | from IPython.utils.path import locate_profile | ||
Thomas Kluyver
|
r19083 | from IPython.utils.py3compat import PY3 | ||
from IPython.utils.traitlets import Unicode | ||||
def recursive_update(target, new): | ||||
"""Recursively update one dictionary using another. | ||||
None values will delete their keys. | ||||
""" | ||||
for k, v in new.items(): | ||||
if isinstance(v, dict): | ||||
if k not in target: | ||||
target[k] = {} | ||||
recursive_update(target[k], v) | ||||
if not target[k]: | ||||
# Prune empty subdicts | ||||
del target[k] | ||||
elif v is None: | ||||
target.pop(k, None) | ||||
else: | ||||
target[k] = v | ||||
class ConfigManager(LoggingConfigurable): | ||||
profile_dir = Unicode() | ||||
Thomas Kluyver
|
r19084 | def _profile_dir_default(self): | ||
return locate_profile() | ||||
Thomas Kluyver
|
r19083 | |||
@property | ||||
def config_dir(self): | ||||
return os.path.join(self.profile_dir, 'nbconfig') | ||||
def ensure_config_dir_exists(self): | ||||
try: | ||||
os.mkdir(self.config_dir, 0o755) | ||||
except OSError as e: | ||||
if e.errno != errno.EEXIST: | ||||
raise | ||||
def file_name(self, section_name): | ||||
return os.path.join(self.config_dir, section_name+'.json') | ||||
def get(self, section_name): | ||||
"""Retrieve the config data for the specified section. | ||||
Returns the data as a dictionary, or an empty dictionary if the file | ||||
doesn't exist. | ||||
""" | ||||
filename = self.file_name(section_name) | ||||
if os.path.isfile(filename): | ||||
with io.open(filename, encoding='utf-8') as f: | ||||
return json.load(f) | ||||
else: | ||||
return {} | ||||
def set(self, section_name, data): | ||||
"""Store the given config data. | ||||
""" | ||||
filename = self.file_name(section_name) | ||||
self.ensure_config_dir_exists() | ||||
if PY3: | ||||
f = io.open(filename, 'w', encoding='utf-8') | ||||
else: | ||||
f = open(filename, 'wb') | ||||
with f: | ||||
json.dump(data, f) | ||||
def update(self, section_name, new_data): | ||||
"""Modify the config section by recursively updating it with new_data. | ||||
Returns the modified config data as a dictionary. | ||||
""" | ||||
data = self.get(section_name) | ||||
recursive_update(data, new_data) | ||||
self.set(section_name, data) | ||||
return data | ||||