Source code for openpaperwork_core.config

#    Paperwork - Using OCR to grep dead trees the easy way
#    Copyright (C) 2012-2014  Jerome Flesch
#
#    Paperwork is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    Paperwork is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Paperwork.  If not, see <http://www.gnu.org/licenses/>.
"""
Paperwork configuration management code
"""

import collections
import gettext
import logging

from .. import PluginBase


LOGGER = logging.getLogger(__name__)

_ = gettext.gettext

# Only basic types are handled by shell commands
CMD_VALUE_TYPES = {
    'str': str,
    'int': int,
    'float': float,
    'bool': bool,
}


[docs]class Setting(object): def __init__(self, core, section, token, default_value_func): self.core = core self.section = section self.token = token self.default_value_func = default_value_func
[docs] def get(self): value = self.core.call_success( "config_backend_get", self.section, self.token, None ) if value is None: return self.default_value_func() else: return value
[docs] def put(self, value): self.core.call_all( "config_backend_put", self.section, self.token, value )
[docs]class Plugin(PluginBase): """ Translate values from the configuration into more usable ones. Provides default values (except for plugins). """ def __init__(self): self.core = None self.settings = {} self.values = {} # applicatiom here is a bit more specific: paperwork-gtk, # paperwork-shell, etc. # It is used to known which plugin list must be loaded self.application = None self.plugin_list_name = None self.observers = collections.defaultdict(set)
[docs] def get_interfaces(self): return ['config']
[docs] def get_deps(self): return [ { 'interface': 'config_backend', 'defaults': ['openpaperwork_core.config.backend.configparser'], }, ]
[docs] def init(self, core): self.core = core self.settings = {}
[docs] def config_load(self, application, plugin_list_name, default_plugins=[]): LOGGER.info( "Loading configuration for %s:%s", application, plugin_list_name ) self.application = application self.plugin_list_name = plugin_list_name self.values = {} self.core.call_all('config_backend_load', application) for observers in self.observers.values(): for observer in observers: observer() self.core.call_all( 'config_backend_load_plugins', plugin_list_name, default_plugins )
[docs] def config_get_application_name(self): return self.application
[docs] def config_get_plugin_list_name(self): return self.plugin_list_name
[docs] def config_save(self): LOGGER.info("Saving configuration") self.core.call_all('config_backend_save')
[docs] def config_build_simple( self, section, token, default_value_func ): """ Provide a default simple implementation for a new setting that can be registered using 'config_register'. Arguments: - section: Section in which option must be stored (see ConfigParser) - token: token name for the option (see ConfigParser) - default_value_func: function to call to get the default value if none is stored in the file. """ return Setting(self.core, section, token, default_value_func)
[docs] def config_register(self, key: str, setting): """ Add another setting to manage. Make this setting available to other components. Arguments: - key: configuration key - setting: Setting must be an object providing a method `get()` and a method `put(value)`. See :func:`config_build_simple` to get quickly a default implementation. """ LOGGER.debug("Registering configuration: %s", key) self.settings[key] = setting
[docs] def config_list_options(self): return list(self.settings.keys())
[docs] def config_get_setting(self, key: str): return self.settings[key]
[docs] def config_get(self, key: str): LOGGER.debug("Config get: %s", key) if key not in self.settings: return None if key not in self.values: self.values[key] = self.settings[key].get() return self.values[key]
[docs] def config_get_default(self, key: str): return self.settings[key].default_value_func()
[docs] def config_put(self, key: str, value): """ Store a setting value. Warning: You must call :func:`config_save` so the changes are actually saved. Arguments: - key: configuration key, - value: can be of many types (`str`, `int`, etc). """ LOGGER.debug("Config put: %s", key) self.settings[key].put(value) self.values[key] = value if key in self.observers: for callback in self.observers[key]: callback()
[docs] def config_add_plugin(self, plugin, plugin_list_name=None): if plugin_list_name is None: plugin_list_name = self.plugin_list_name LOGGER.debug("Config add plugin: %s -> %s", plugin, plugin_list_name) self.core.call_all( 'config_backend_add_plugin', plugin_list_name, plugin )
[docs] def config_remove_plugin(self, plugin, plugin_list_name=None): if plugin_list_name is None: plugin_list_name = self.plugin_list_name LOGGER.debug( "Config remove plugin: %s -> %s", plugin, plugin_list_name ) self.core.call_all( 'config_backend_remove_plugin', plugin_list_name, plugin )
[docs] def config_list_plugins(self, plugin_list_name=None): if plugin_list_name is None: plugin_list_name = self.plugin_list_name return self.core.call_success( "config_backend_list_active_plugins", plugin_list_name )
[docs] def config_reset_plugins(self, plugin_list_name=None): if plugin_list_name is None: plugin_list_name = self.plugin_list_name LOGGER.debug("Config reset plugin: %s", plugin_list_name) return self.core.call_success( "config_backend_reset_plugins", plugin_list_name )
[docs] def config_add_observer(self, key: str, callback): self.observers[key].add(callback)
[docs] def config_remove_observer(self, key: str, callback): self.observers[key].remove(callback)