# -*- coding: utf-8 -*- # Copyright (C) 2017 Team tiramisu (see AUTHORS for all contributors) # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program 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 Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with this program. If not, see . # ____________________________________________________________ from inspect import ismethod, getdoc from .error import APIError from .i18n import _ from .setting import owners, undefined try: from .value import Multi except: Multi = list class CommonTiramisu(object): icon = '\u2937' tmpl_help = u' {} {}: {}' allow_unrestraint = False slave_need_index = True def __init__(self, opt, path, index, config, setting_properties, force_permissive, force_unrestraint): self.opt = opt self.path = path self.index = index if self.slave_need_index: self._test_slave_index() self.config = config self.setting_properties = setting_properties self.force_permissive = force_permissive self.force_unrestraint = force_unrestraint if not self.allow_unrestraint: self._unrestraint_not_allowed(force_unrestraint) def _test_slave_index(self): if self.index is None and self.opt.impl_is_master_slaves('slave'): raise APIError('index must be set with a slave option') def _unrestraint_not_allowed(self, force_unrestraint): if force_unrestraint: name = self.__class__.__name__[14:].lower() raise APIError(_('{} cannot be unrestraint').format(name)) def __getattr__(self, name): if name == 'help': return self._help() else: if not hasattr(CommonTiramisu, name): raise APIError(_('unknown method {}').format(name)) else: super(CommonTiramisu, self).__getattribute__(name) def _help(self): txt = [] for func_name in dir(self): if not func_name.startswith('_'): func = getattr(self, func_name) if ismethod(func): txt.append(self.tmpl_help.format(self.icon, func_name, getdoc(func))) return '\n'.join(txt) class TiramisuOptionOption(CommonTiramisu): """get information from an option""" allow_unrestraint = True slave_need_index = False def __init__(self, opt, path, index, config, setting_properties, force_permissive, force_unrestraint): super(TiramisuOptionOption, self).__init__(opt, path, index, config, setting_properties, force_permissive, force_unrestraint) if config: self.values = self.config.cfgimpl_get_values() def ismulti(self): """test if option could have multi value""" return self.opt.impl_is_multi() def ismasterslaves(self): """test if option is a master or a slave""" return self.opt.impl_is_master_slaves() def ismaster(self): """test if option is a master""" return self.opt.impl_is_master_slaves('master') def isslave(self): """test if option is a slave""" return self.opt.impl_is_master_slaves('slave') def getname(self): return self.opt.impl_getname() def getdoc(self): return self.opt.impl_get_display_name() class TiramisuOptionOwner(CommonTiramisu): """manager option's owner""" def __init__(self, opt, path, index, config, setting_properties, force_permissive, force_unrestraint): super(TiramisuOptionOwner, self).__init__(opt, path, index, config, setting_properties, force_permissive, force_unrestraint) if config: self.values = self.config.cfgimpl_get_values() def get(self): """get owner for a specified option""" return self.values.getowner(self.opt, index=self.index, force_permissive=self.force_permissive) def isdefault(self): """is option has defaut value""" return self.values.is_default_owner(self.opt, index=self.index, force_permissive=self.force_permissive) def set(self, owner): """get owner for a specified option""" try: obj_owner = getattr(owners, owner) except AttributeError: owners.addowner(owner) obj_owner = getattr(owners, owner) self.values.setowner(self.opt, obj_owner, self.index, force_permissive=self.force_permissive) class TiramisuOptionProperty(CommonTiramisu): """manager option's property""" #allow_unrestraint = True slave_need_index = False def __init__(self, opt, path, index, config, setting_properties, force_permissive, force_unrestraint): super(TiramisuOptionProperty, self).__init__(opt, path, index, config, setting_properties, force_permissive, force_unrestraint) if config: self.settings = config.cfgimpl_get_settings() def get(self): self._test_slave_index() return self.settings.getproperties(self.opt, self.path, index=self.index, obj=False) def set(self, properties): """set properties for a specified option""" self.settings.setproperties(set(properties), self.opt, self.path) def reset(self): """reset all personalised properties """ self.settings.reset(_path=self.path) class TiramisuOptionPermissive(CommonTiramisu): """manager option's property""" allow_unrestraint = True slave_need_index = False def __init__(self, opt, path, index, config, setting_properties, force_permissive, force_unrestraint): super(TiramisuOptionPermissive, self).__init__(opt, path, index, config, setting_properties, force_permissive, force_unrestraint) if config: self.settings = config.cfgimpl_get_settings() def get(self): """get permissive value for a specified path""" return self.settings.getpermissive(self.setting_properties, self.path) def set(self, permissive): self.settings.setpermissive(permissive, opt=self.opt, path=self.path) #def reset(self, path): # """reset all personalised properties # """ # self._get_obj_by_path(path) # self.settings.reset(_path=path) class TiramisuOptionValue(CommonTiramisu): """manager option's value""" def __init__(self, opt, path, index, config, setting_properties, force_permissive, force_unrestraint): super(TiramisuOptionValue, self).__init__(opt, path, index, config, setting_properties, force_permissive, force_unrestraint) def get(self): settings = self.config.cfgimpl_get_settings() value = self.config.getattr(self.path, index=self.index, setting_properties=self.setting_properties, force_permissive=self.force_permissive) if isinstance(value, Multi): value = list(value) return value def set(self, value): """set a value for a specified option""" values = self.config.cfgimpl_get_values() if isinstance(value, list): while undefined in value: idx = value.index(undefined) value[idx] = values.getdefaultvalue(self.opt, self.path, idx) else: if value == undefined: value = values.getdefaultvalue(self.opt, self.path, self.index) self.config.setattr(self.path, value, index=self.index, force_permissive=self.force_permissive) def pop(self, index): """pop value for a specified master values """ self.config.delattr(self.path, index=index, setting_properties=self.setting_properties, force_permissive=self.force_permissive) def reset(self): """reset value for a value""" self.config.delattr(self.path, index=self.index, setting_properties=self.setting_properties, force_permissive=self.force_permissive) class TiramisuOption(object): icon = '\u2937' tmpl_help = ' {} {}: {}' def __init__(self, opt, path, index, config, setting_properties, force_permissive, force_unrestraint): self.opt = opt self.path = path self.index = index self.config = config self.setting_properties = setting_properties self.force_permissive = force_permissive self.force_unrestraint = force_unrestraint self.registers = {} self.prefix = self.__class__.__name__ for module_name in globals().keys(): if module_name != self.prefix and module_name.startswith(self.prefix): module = globals()[module_name] func_name = module_name[len(self.prefix):].lower() self.registers[func_name] = module def _help(self): txt = [] for module_name, module in self.registers.items(): module_doc = getdoc(module) txt.append(self.tmpl_help.format(self.icon, module_name, module_doc)) txt.append(module(None, None).help) return '\n'.join(txt) def __getattr__(self, subfunc): if subfunc in self.registers: return self.registers[subfunc](self.opt, self.path, self.index, self.config, self.setting_properties, self.force_permissive, self.force_unrestraint) elif subfunc == 'help': return self._help() else: raise APIError(_('please specify a valid sub function')) class TiramisuAPI(object): icon = '\u2937' tmpl_help = ' {} {}: {}' def __init__(self, config, force_permissive=False, force_unrestraint=False): self.config = config self.force_permissive = force_permissive self.force_unrestraint = force_unrestraint settings = self.config.cfgimpl_get_settings() #FIXME ? self.config.read_write() settings.setpermissive(('hidden',)) #/FIXME ? def option(self, path, index=None): validate = not self.force_unrestraint settings = self.config.cfgimpl_get_settings() setting_properties = settings.get_global_properties() opt = self.config.unwrap_from_path(path, setting_properties=setting_properties, validate=validate, validate_properties=validate, force_permissive=self.force_permissive, index=index) if index is not None and not opt.impl_is_master_slaves('slave'): raise APIError('index must be set only with a slave option') return TiramisuOption(opt, path, index, self.config, setting_properties, self.force_permissive, self.force_unrestraint) def __getattr__(self, subfunc): if subfunc == 'forcepermissive': return TiramisuAPI(self.config, force_permissive=True, force_unrestraint=self.force_unrestraint) elif subfunc == 'unrestraint': return TiramisuAPI(self.config, force_permissive=self.force_permissive, force_unrestraint=True) elif subfunc == 'help': return self._help() else: raise APIError(_('please specify a valid sub function')) def _help(self): txt = ['[forcepermissive]'] for module_name, module in self.registers.items(): module_doc = getdoc(module) txt.append(self.tmpl_help.format(self.icon, module_name, module_doc)) txt.append(module(None, None).help) return '\n'.join(txt) def getapi(config): """instanciate TiramisuAPI :param config: Config object :type descr: an instance of ``config.Config`` """ return TiramisuAPI(config)