def set(self, key, value): """Change a configuration value. These changes will be persistent right away. """ key_str = self.optionxform(key) value_str = to_unicode(value) self._cache.pop(key_str, None) option_key = { 'product': self.product, 'section': self.name, 'option': key_str, } try: setting = ProductSetting(self.env, option_key) except ResourceNotFound: if value is not None: # Insert new record in the database setting = ProductSetting(self.env) setting._data.update(option_key) setting._data['value'] = value_str self.env.log.debug('Writing option %s', setting._data) setting.insert() else: if value is None: # Delete existing record from the database # FIXME : Why bother with setting overriden self.overridden[key] = True setting.delete() else: # Update existing record setting._data['value'] = value setting.update()
def _write(self, lines, product=None): r"""Override superclass method by writing configuration values to the database rather than ini file in the filesystem. """ if product is None: product = self.default_product product = to_unicode(product) fp = StringIO(('\n'.join(lines + [''])).encode('utf-8')) parser = ConfigParser() parser.readfp(fp, 'bh-product-test') with self.env.db_transaction as db: # Delete existing setting for target product , if any for setting in ProductSetting.select(self.env, db, {'product' : product}): setting.delete() # Insert new options for section in parser.sections(): option_key = dict( section=to_unicode(section), product=to_unicode(product) ) for option, value in parser.items(section): option_key.update(dict(option=to_unicode(option))) setting = ProductSetting(self.env) setting._data.update(option_key) setting._data['value'] = to_unicode(value) setting.insert()
def iterate(self, compmgr=None, defaults=True): """Iterate over the options in this section. If `compmgr` is specified, only return default option values for components that are enabled in the given `ComponentManager`. """ options = set() name_str = self.name for setting in ProductSetting.select(self.env, where={ 'product': self.product, 'section': name_str }): option = self.optionxform(setting.option) options.add(option) yield option for parent in self.config.parents: for option in parent[self.name].iterate(defaults=False): loption = self.optionxform(option) if loption not in options: options.add(loption) yield option if defaults: for section, option in Option.get_registry(compmgr).keys(): if section == self.name and \ self.optionxform(option) not in options: yield option
def iterate(self, compmgr=None, defaults=True): """Iterate over the options in this section. If `compmgr` is specified, only return default option values for components that are enabled in the given `ComponentManager`. """ options = set() name_str = self.name for setting in ProductSetting.select(self.env, where={'product': self.product, 'section': name_str}): option = self.optionxform(setting.option) options.add(option) yield option for parent in self.config.parents: for option in parent[self.name].iterate(defaults=False): loption = self.optionxform(option) if loption not in options: options.add(loption) yield option if defaults: for section, option in Option.get_registry(compmgr).keys(): if section == self.name and \ self.optionxform(option) not in options: yield option
def get(self, key, default=''): """Return the value of the specified option. Valid default input is a string. Returns a string. """ key = self.optionxform(key) cached = self._cache.get(key, _use_default) if cached is not _use_default: return cached name_str = self.name key_str = to_unicode(key) settings = ProductSetting.select(self.env, where={'product':self.product, 'section':name_str, 'option':key_str}) if len(settings) > 0: value = settings[0].value else: for parent in self.config.parents: value = parent[self.name].get(key, _use_default) if value is not _use_default: break else: if default is not _use_default: option = Option.registry.get((self.name, key)) value = option.default if option else _use_default else: value = _use_default if value is _use_default: return default if not value: value = u'' elif isinstance(value, basestring): value = to_unicode(value) self._cache[key] = value return value
def contains(self, key, defaults=True): key = self.optionxform(key) if ProductSetting.exists(self.env, self.product, self.name, key): return True for parent in self.config.parents: if parent[self.name].contains(key, defaults=False): return True return defaults and Option.registry.has_key((self.name, key))
def contains(self, key, defaults=True): key = self.optionxform(key) if ProductSetting.exists(self.env, self.product, self.name, key): return True for parent in self.config.parents: if parent[self.name].contains(key, defaults=False): return True return defaults and (self.name, key) in Option.registry
def remove(self, key): """Delete a key from this section. Like for `set()`, the changes won't persist until `save()` gets called. """ key_str = self.optionxform(key) option_key = { 'product': self.product, 'section': self.name, 'option': key_str } try: setting = ProductSetting(self.env, keys=option_key) except ResourceNotFound: self.env.log.warning("No record for product option %s", option_key) else: self._cache.pop(key, None) setting.delete() self.env.log.info("Removing product option %s", option_key)
def remove(self, key): """Delete a key from this section. Like for `set()`, the changes won't persist until `save()` gets called. """ key_str = self.optionxform(key) option_key = { 'product': self.product, 'section': self.name, 'option': key_str, } try: setting = ProductSetting(self.env, keys=option_key) except ResourceNotFound: self.env.log.warning("No record for product option %s", option_key) else: self._cache.pop(key, None) setting.delete() self.env.log.info("Removing product option %s", option_key)
def _dump_settings(self, config): product = config.product fields = ('section', 'option', 'value') rows = [tuple(getattr(s, f, None) for f in fields) for s in ProductSetting.select(config.env, where={'product' : product})] dump = [] for section, group in groupby(sorted(rows), lambda row: row[0]): dump.append('[%s]\n' % (section,)) for row in group: dump.append('%s = %s\n' % (row[1], row[2])) return dump
def _write(self, lines, product=None): r"""Override superclass method by writing configuration values to the database rather than ini file in the filesystem. """ if product is None: product = self.default_product product = to_unicode(product) fp = StringIO(('\n'.join(lines + [''])).encode('utf-8')) parser = ConfigParser() parser.readfp(fp, 'bh-product-test') with self.env.db_transaction as db: # Delete existing setting for target product , if any for setting in ProductSetting.select(self.env, db, {'product': product}): setting.delete() # Insert new options for section in parser.sections(): option_key = dict(section=to_unicode(section), product=to_unicode(product)) for option, value in parser.items(section): option_key.update(dict(option=to_unicode(option))) setting = ProductSetting(self.env) setting._data.update(option_key) setting._data['value'] = to_unicode(value) setting.insert()
def has_option(self, section, option, defaults=True): """Returns True if option exists in section in either the project trac.ini or one of the parents, or is available through the Option registry. (since Trac 0.11) """ if ProductSetting.exists(self.env, self.product, section, option): return True for parent in self.parents: if parent.has_option(section, option, defaults=False): return True return defaults and (section, option) in Option.registry
def sections(self, compmgr=None, defaults=True): """Return a list of section names. If `compmgr` is specified, only the section names corresponding to options declared in components that are enabled in the given `ComponentManager` are returned. """ sections = set(to_unicode(s) \ for s in ProductSetting.get_sections(self.env, self.product)) for parent in self.parents: sections.update(parent.sections(compmgr, defaults=False)) if defaults: sections.update(self.defaults(compmgr)) return sorted(sections)
def set_defaults(self, compmgr=None): """Retrieve all default values and store them explicitly in the configuration, so that they can be saved to file. Values already set in the configuration are not overridden. """ for section, default_options in self.defaults(compmgr).items(): for name, value in default_options.items(): if not ProductSetting.exists(self.env, self.product, section, name): if any(parent[section].contains(name, defaults=False) for parent in self.parents): value = None self.set(section, name, value)
def _dump_settings(self, config): product = config.product fields = ('section', 'option', 'value') rows = [ tuple(getattr(s, f, None) for f in fields) for s in ProductSetting.select(config.env, where={'product': product}) ] dump = [] for section, group in groupby(sorted(rows), lambda row: row[0]): dump.append('[%s]\n' % (section, )) for row in group: dump.append('%s = %s\n' % (row[1], row[2])) return dump
def get(self, key, default=''): """Return the value of the specified option. Valid default input is a string. Returns a string. """ key = self.optionxform(key) cached = self._cache.get(key, _use_default) if cached is not _use_default: return cached name_str = self.name key_str = to_unicode(key) settings = ProductSetting.select(self.env, where={ 'product': self.product, 'section': name_str, 'option': key_str }) if len(settings) > 0: value = settings[0].value else: for parent in self.config.parents: value = parent[self.name].get(key, _use_default) if value is not _use_default: break else: if default is not _use_default: option = Option.registry.get((self.name, key)) value = option.default if option else _use_default else: value = _use_default if value is _use_default: return default if not value: value = u'' elif isinstance(value, basestring): value = to_unicode(value) self._cache[key] = value return value
from trac.db_default import schema as tracschema from trac.util.text import printout from trac.util.translation import _ from trac.wiki.admin import WikiAdmin from trac.wiki.model import WikiPage from bhdashboard import wiki try: from multiproduct.model import Product, ProductResourceMap, ProductSetting except ImportError: Product = ProductResourceMap = ProductSetting = None schema = tracschema[:] if Product is not None: schema.extend([Product._get_schema(), ProductResourceMap._get_schema(), ProductSetting._get_schema()]) structure = dict([(table.name, [col.name for col in table.columns]) for table in schema]) # add product for any columns required for table in ['ticket']: structure[table].append('product') # probably no point in keeping data from these tables ignored = ['auth_cookie', 'session', 'session_attribute', 'cache'] IGNORED_DB_STRUCTURE = dict([(k, structure[k]) for k in ignored]) DB_STRUCTURE = dict([(k, structure[k]) for k in structure if k not in ignored]) class BloodhoundAdmin(Component):
from trac.wiki.admin import WikiAdmin from trac.wiki.model import WikiPage from bhdashboard import wiki from bhdashboard.util.translation import _ try: from multiproduct.model import Product, ProductResourceMap, ProductSetting except ImportError: Product = ProductResourceMap = ProductSetting = None schema = tracschema[:] if Product is not None: schema.extend([ Product._get_schema(), ProductResourceMap._get_schema(), ProductSetting._get_schema() ]) structure = dict([(table.name, [col.name for col in table.columns]) for table in schema]) # add product for any columns required for table in ['ticket']: structure[table].append('product') # probably no point in keeping data from these tables ignored = ['auth_cookie', 'session', 'session_attribute', 'cache'] IGNORED_DB_STRUCTURE = dict([(k, structure[k]) for k in ignored]) DB_STRUCTURE = dict([(k, structure[k]) for k in structure if k not in ignored])
def _create_product_tables_for_plugins(self, db): self.log.debug("creating additional db tables for %s plugin." % PLUGIN_NAME) db_connector, dummy = DatabaseManager(self.env)._get_connector() for statement in db_connector.to_sql(ProductSetting._get_schema()): db(statement)