# HG changeset patch # User Goffi # Date 1579982920 -3600 # Node ID 130f9cb6e0ab4aa9af1c1806477f9cbc9ee3a17b # Parent 4486d72658b9da16cbb1ae443891efae2ae490d0 core (memory/params): added `extra` argument to filter out params notably in `getParamsUI`: In some case, it may be desirable for a frontend to not expose some parameters to user (e.g. it is the case on Android with the `autoconnect_backend` parameter). An new `extra` parameter has been added to a couple of parameters method for that: it can contain the `ignore` key with a list of [category, name] of parameters to skip. diff -r 4486d72658b9 -r 130f9cb6e0ab sat/bridge/bridge_constructor/bridge_template.ini --- a/sat/bridge/bridge_constructor/bridge_template.ini Sat Jan 25 21:08:39 2020 +0100 +++ b/sat/bridge/bridge_constructor/bridge_template.ini Sat Jan 25 21:08:40 2020 +0100 @@ -593,28 +593,34 @@ async= type=method category=code -sig_in=sis +sig_in=sisss sig_out=a{ss} param_1_default=-1 -param_2_default="@DEFAULT@" +param_2_default="" +param_3_default="" +param_4_default="@DEFAULT@" doc=Get "attribute" for all params of a category doc_param_0=category: as for [setParam] doc_param_1=%(doc_security_limit)s -doc_param_2=%(doc_profile_key)s +doc_param_2=app: name of the frontend requesting the parameters, or '' to get all parameters +doc_param_3=extra: extra options/filters +doc_param_4=%(doc_profile_key)s [getParamsUI] async= type=method category=core -sig_in=iss +sig_in=isss sig_out=s param_0_default=-1 param_1_default='' -param_2_default="@DEFAULT@" +param_2_default='' +param_3_default="@DEFAULT@" doc=Return a SàT XMLUI for parameters, eventually restrict the result to the parameters concerning a given frontend doc_param_0=%(doc_security_limit)s doc_param_1=app: name of the frontend requesting the parameters, or '' to get all parameters -doc_param_2=%(doc_profile_key)s +doc_param_2=extra: extra options/filters +doc_param_3=%(doc_profile_key)s [getParamsCategories] type=method diff -r 4486d72658b9 -r 130f9cb6e0ab sat/bridge/dbus_bridge.py --- a/sat/bridge/dbus_bridge.py Sat Jan 25 21:08:39 2020 +0100 +++ b/sat/bridge/dbus_bridge.py Sat Jan 25 21:08:40 2020 +0100 @@ -235,10 +235,10 @@ return self._callback("asyncGetParamA", str(name), str(category), str(attribute), security_limit, str(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, - in_signature='sis', out_signature='a{ss}', + in_signature='sisss', out_signature='a{ss}', async_callbacks=('callback', 'errback')) - def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None): - return self._callback("asyncGetParamsValuesFromCategory", str(category), security_limit, str(profile_key), callback=callback, errback=errback) + def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, app="", extra="", profile_key="@DEFAULT@", callback=None, errback=None): + return self._callback("asyncGetParamsValuesFromCategory", str(category), security_limit, str(app), str(extra), str(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ssa{ss}', out_signature='b', @@ -349,10 +349,10 @@ return self._callback("getParamsCategories", ) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, - in_signature='iss', out_signature='s', + in_signature='isss', out_signature='s', async_callbacks=('callback', 'errback')) - def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None): - return self._callback("getParamsUI", security_limit, str(app), str(profile_key), callback=callback, errback=errback) + def getParamsUI(self, security_limit=-1, app='', extra='', profile_key="@DEFAULT@", callback=None, errback=None): + return self._callback("getParamsUI", security_limit, str(app), str(extra), str(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='a{sa{s(sia{ss})}}', diff -r 4486d72658b9 -r 130f9cb6e0ab sat/core/sat_main.py --- a/sat/core/sat_main.py Sat Jan 25 21:08:39 2020 +0100 +++ b/sat/core/sat_main.py Sat Jan 25 21:08:40 2020 +0100 @@ -139,9 +139,9 @@ self.bridge.register_method("asyncGetParamA", self.memory.asyncGetStringParamA) self.bridge.register_method( "asyncGetParamsValuesFromCategory", - self.memory.asyncGetParamsValuesFromCategory, + self.memory._getParamsValuesFromCategory, ) - self.bridge.register_method("getParamsUI", self.memory.getParamsUI) + self.bridge.register_method("getParamsUI", self.memory._getParamsUI) self.bridge.register_method( "getParamsCategories", self.memory.getParamsCategories ) diff -r 4486d72658b9 -r 130f9cb6e0ab sat/memory/memory.py --- a/sat/memory/memory.py Sat Jan 25 21:08:39 2020 +0100 +++ b/sat/memory/memory.py Sat Jan 25 21:08:40 2020 +0100 @@ -1130,29 +1130,24 @@ name, category, attr, security_limit, profile_key ) - def asyncGetParamsValuesFromCategory( - self, category, security_limit=C.NO_SECURITY_LIMIT, profile_key=C.PROF_KEY_NONE + def _getParamsValuesFromCategory( + self, category, security_limit, app, extra_s, profile_key ): - return self.params.asyncGetParamsValuesFromCategory( - category, security_limit, profile_key + return self.params._getParamsValuesFromCategory( + category, security_limit, app, extra_s, profile_key ) def asyncGetStringParamA( - self, - name, - category, - attr="value", - security_limit=C.NO_SECURITY_LIMIT, - profile_key=C.PROF_KEY_NONE, - ): - return self.params.asyncGetStringParamA( - name, category, attr, security_limit, profile_key - ) + self, name, category, attr="value", security_limit=C.NO_SECURITY_LIMIT, + profile_key=C.PROF_KEY_NONE): - def getParamsUI( - self, security_limit=C.NO_SECURITY_LIMIT, app="", profile_key=C.PROF_KEY_NONE - ): - return self.params.getParamsUI(security_limit, app, profile_key) + profile = self.getProfileName(profile_key) + return defer.ensureDeferred(self.params.asyncGetStringParamA( + name, category, attr, security_limit, profile + )) + + def _getParamsUI(self, security_limit, app, extra_s, profile_key): + return self.params._getParamsUI(security_limit, app, extra_s, profile_key) def getParamsCategories(self): return self.params.getParamsCategories() diff -r 4486d72658b9 -r 130f9cb6e0ab sat/memory/params.py --- a/sat/memory/params.py Sat Jan 25 21:08:39 2020 +0100 +++ b/sat/memory/params.py Sat Jan 25 21:08:40 2020 +0100 @@ -31,6 +31,7 @@ from twisted.words.xish import domish from twisted.words.protocols.jabber import jid from sat.tools.xml_tools import paramsXML2XMLUI, getText +from sat.tools.common import data_format from xml.sax.saxutils import quoteattr # TODO: params should be rewritten using Twisted directly instead of minidom @@ -553,7 +554,7 @@ """Helper method to get a specific attribute. /!\ This method would return encrypted password values, - to get the plain values you have to use _asyncGetParamA. + to get the plain values you have to use asyncGetParamA. @param name: name of the parameter @param category: category of the parameter @param attr: name of the attribute (default: "value") @@ -602,12 +603,12 @@ return value return self._getAttr(node[1], attr, value) - def asyncGetStringParamA( + async def asyncGetStringParamA( self, name, category, attr="value", security_limit=C.NO_SECURITY_LIMIT, - profile_key=C.PROF_KEY_NONE): - d = self.asyncGetParamA(name, category, attr, security_limit, profile_key) - d.addCallback(self._type_to_str) - return d + profile=C.PROF_KEY_NONE): + value = await self.asyncGetParamA( + name, category, attr, security_limit, profile_key=profile) + return self._type_to_str(value) def asyncGetParamA( self, @@ -668,56 +669,50 @@ lambda value: self._asyncGetAttr(node[1], attr, value, profile) ) - def asyncGetParamsValuesFromCategory(self, category, security_limit, profile_key): + def _getParamsValuesFromCategory( + self, category, security_limit, app, extra_s, profile_key): + client = self.host.getClient(profile_key) + extra = data_format.deserialise(extra_s) + return defer.ensureDeferred(self.getParamsValuesFromCategory( + client, category, security_limit, app, extra)) + + async def getParamsValuesFromCategory( + self, client, category, security_limit, app='', extra=None): """Get all parameters "attribute" for a category @param category(unicode): the desired category @param security_limit(int): NO_SECURITY_LIMIT (-1) to return all the params. Otherwise sole the params which have a security level defined *and* lower or equal to the specified value are returned. - @param profile_key: %(doc_profile_key)s + @param app(str): see [getParams] + @param extra(dict): see [getParams] @return (dict): key: param name, value: param value (converted to string if needed) """ # TODO: manage category of general type (without existant profile) - profile = self.getProfileName(profile_key) - if not profile: - log.error(_("Asking params for inexistant profile")) - return "" - - def setValue(value, ret, name): - ret[name] = value + if extra is None: + extra = {} + prof_xml = await self._constructProfileXml(client, security_limit, app, extra) + ret = {} + for category_node in prof_xml.getElementsByTagName("category"): + if category_node.getAttribute("name") == category: + for param_node in category_node.getElementsByTagName("param"): + name = param_node.getAttribute("name") + if not name: + log.warning( + "ignoring attribute without name: {}".format( + param_node.toxml() + ) + ) + continue + value = await self.asyncGetStringParamA( + name, category, security_limit=security_limit, + profile=client.profile) - def returnCategoryXml(prof_xml): - ret = {} - names_d_list = [] - for category_node in prof_xml.getElementsByTagName("category"): - if category_node.getAttribute("name") == category: - for param_node in category_node.getElementsByTagName("param"): - name = param_node.getAttribute("name") - if not name: - log.warning( - "ignoring attribute without name: {}".format( - param_node.toxml() - ) - ) - continue - d = self.asyncGetStringParamA( - name, - category, - security_limit=security_limit, - profile_key=profile, - ) - d.addCallback(setValue, ret, name) - names_d_list.append(d) - break + ret[name] = value + break - prof_xml.unlink() - dlist = defer.gatherResults(names_d_list) - dlist.addCallback(lambda __: ret) - return ret - - d = self._constructProfileXml(security_limit, "", profile) - return d.addCallback(returnCategoryXml) + prof_xml.unlink() + return ret def _getParam( self, category, name, type_=C.INDIVIDUAL, cache=None, profile=C.PROF_KEY_NONE @@ -749,7 +744,7 @@ return None return cache[(category, name)] - def _constructProfileXml(self, security_limit, app, profile): + async def _constructProfileXml(self, client, security_limit, app, extra): """Construct xml for asked profile, filling values when needed /!\ as noticed in doc, don't forget to unlink the minidom.Document @@ -760,166 +755,163 @@ @param profile: profile name (not key !) @return: a deferred that fire a minidom.Document of the profile xml (cf warning above) """ + profile = client.profile def checkNode(node): - """Check the node against security_limit and app""" - return self.checkSecurityLimit(node, security_limit) and self.checkApp( - node, app - ) - - def constructProfile(ignore, profile_cache): - # init the result document - prof_xml = minidom.parseString("") - cache = {} - - for type_node in self.dom.documentElement.childNodes: - if type_node.nodeName != C.GENERAL and type_node.nodeName != C.INDIVIDUAL: - continue - # we use all params, general and individual - for cat_node in type_node.childNodes: - if cat_node.nodeName != "category": - continue - category = cat_node.getAttribute("name") - dest_params = {} # result (merged) params for category - if category not in cache: - # we make a copy for the new xml - cache[category] = dest_cat = cat_node.cloneNode(True) - to_remove = [] - for node in dest_cat.childNodes: - if node.nodeName != "param": - continue - if not checkNode(node): - to_remove.append(node) - continue - dest_params[node.getAttribute("name")] = node - for node in to_remove: - dest_cat.removeChild(node) - new_node = True - else: - # It's not a new node, we use the previously cloned one - dest_cat = cache[category] - new_node = False - params = cat_node.getElementsByTagName("param") - - for param_node in params: - # we have to merge new params (we are parsing individual parameters, we have to add them - # to the previously parsed general ones) - name = param_node.getAttribute("name") - if not checkNode(param_node): - continue - if name not in dest_params: - # this is reached when a previous category exists - dest_params[name] = param_node.cloneNode(True) - dest_cat.appendChild(dest_params[name]) - - profile_value = self._getParam( - category, - name, - type_node.nodeName, - cache=profile_cache, - profile=profile, - ) - if profile_value is not None: - # there is a value for this profile, we must change the default - if dest_params[name].getAttribute("type") == "list": - for option in dest_params[name].getElementsByTagName( - "option" - ): - if option.getAttribute("value") == profile_value: - option.setAttribute("selected", "true") - else: - try: - option.removeAttribute("selected") - except NotFoundErr: - pass - elif dest_params[name].getAttribute("type") == "jids_list": - jids = profile_value.split("\t") - for jid_elt in dest_params[name].getElementsByTagName( - "jid" - ): - dest_params[name].removeChild( - jid_elt - ) # remove all default - for jid_ in jids: # rebuilt the children with use values - try: - jid.JID(jid_) - except ( - RuntimeError, - jid.InvalidFormat, - AttributeError, - ): - log.warning( - "Incorrect jid value found in jids list: [{}]".format( - jid_ - ) - ) - else: - jid_elt = prof_xml.createElement("jid") - jid_elt.appendChild(prof_xml.createTextNode(jid_)) - dest_params[name].appendChild(jid_elt) - else: - dest_params[name].setAttribute("value", profile_value) - if new_node: - prof_xml.documentElement.appendChild(dest_cat) - - to_remove = [] - for cat_node in prof_xml.documentElement.childNodes: - # we remove empty categories - if cat_node.getElementsByTagName("param").length == 0: - to_remove.append(cat_node) - for node in to_remove: - prof_xml.documentElement.removeChild(node) - return prof_xml + """Check the node against security_limit, app and extra""" + return (self.checkSecurityLimit(node, security_limit) + and self.checkApp(node, app) + and self.checkExtra(node, extra)) if profile in self.params: - d = defer.succeed(None) profile_cache = self.params[profile] else: # profile is not in cache, we load values in a short time cache profile_cache = {} - d = self.loadIndParams(profile, profile_cache) + await self.loadIndParams(profile, profile_cache) + + # init the result document + prof_xml = minidom.parseString("") + cache = {} - return d.addCallback(constructProfile, profile_cache) + for type_node in self.dom.documentElement.childNodes: + if type_node.nodeName != C.GENERAL and type_node.nodeName != C.INDIVIDUAL: + continue + # we use all params, general and individual + for cat_node in type_node.childNodes: + if cat_node.nodeName != "category": + continue + category = cat_node.getAttribute("name") + dest_params = {} # result (merged) params for category + if category not in cache: + # we make a copy for the new xml + cache[category] = dest_cat = cat_node.cloneNode(True) + to_remove = [] + for node in dest_cat.childNodes: + if node.nodeName != "param": + continue + if not checkNode(node): + to_remove.append(node) + continue + dest_params[node.getAttribute("name")] = node + for node in to_remove: + dest_cat.removeChild(node) + new_node = True + else: + # It's not a new node, we use the previously cloned one + dest_cat = cache[category] + new_node = False + params = cat_node.getElementsByTagName("param") + + for param_node in params: + # we have to merge new params (we are parsing individual parameters, we have to add them + # to the previously parsed general ones) + name = param_node.getAttribute("name") + if not checkNode(param_node): + continue + if name not in dest_params: + # this is reached when a previous category exists + dest_params[name] = param_node.cloneNode(True) + dest_cat.appendChild(dest_params[name]) - def getParamsUI(self, security_limit, app, profile_key): - """ + profile_value = self._getParam( + category, + name, + type_node.nodeName, + cache=profile_cache, + profile=profile, + ) + if profile_value is not None: + # there is a value for this profile, we must change the default + if dest_params[name].getAttribute("type") == "list": + for option in dest_params[name].getElementsByTagName( + "option" + ): + if option.getAttribute("value") == profile_value: + option.setAttribute("selected", "true") + else: + try: + option.removeAttribute("selected") + except NotFoundErr: + pass + elif dest_params[name].getAttribute("type") == "jids_list": + jids = profile_value.split("\t") + for jid_elt in dest_params[name].getElementsByTagName( + "jid" + ): + dest_params[name].removeChild( + jid_elt + ) # remove all default + for jid_ in jids: # rebuilt the children with use values + try: + jid.JID(jid_) + except ( + RuntimeError, + jid.InvalidFormat, + AttributeError, + ): + log.warning( + "Incorrect jid value found in jids list: [{}]".format( + jid_ + ) + ) + else: + jid_elt = prof_xml.createElement("jid") + jid_elt.appendChild(prof_xml.createTextNode(jid_)) + dest_params[name].appendChild(jid_elt) + else: + dest_params[name].setAttribute("value", profile_value) + if new_node: + prof_xml.documentElement.appendChild(dest_cat) + + to_remove = [] + for cat_node in prof_xml.documentElement.childNodes: + # we remove empty categories + if cat_node.getElementsByTagName("param").length == 0: + to_remove.append(cat_node) + for node in to_remove: + prof_xml.documentElement.removeChild(node) + + return prof_xml + + + def _getParamsUI(self, security_limit, app, extra_s, profile_key): + client = self.host.getClient(profile_key) + extra = data_format.deserialise(extra_s) + return defer.ensureDeferred(self.getParamsUI(client, security_limit, app, extra)) + + async def getParamsUI(self, client, security_limit, app, extra=None): + """Get XMLUI to handle parameters + @param security_limit: NO_SECURITY_LIMIT (-1) to return all the params. - Otherwise sole the params which have a security level defined *and* - lower or equal to the specified value are returned. + Otherwise sole the params which have a security level defined *and* + lower or equal to the specified value are returned. @param app: name of the frontend requesting the parameters, or '' to get all parameters - @param profile_key: Profile key which can be either a magic (eg: @DEFAULT@) or the name of an existing profile. - @return: a SàT XMLUI for parameters + @param extra (dict, None): extra options. Key can be: + - ignore: list of (category/name) values to remove from parameters + @return(str): a SàT XMLUI for parameters """ - profile = self.getProfileName(profile_key) - if not profile: - log.error(_("Asking params for inexistant profile")) - return "" - d = self.getParams(security_limit, app, profile) - return d.addCallback(lambda param_xml: paramsXML2XMLUI(param_xml)) + param_xml = await self.getParams(client, security_limit, app, extra) + return paramsXML2XMLUI(param_xml) - def getParams(self, security_limit, app, profile_key): + async def getParams(self, client, security_limit, app, extra=None): """Construct xml for asked profile, take params xml as skeleton @param security_limit: NO_SECURITY_LIMIT (-1) to return all the params. - Otherwise sole the params which have a security level defined *and* - lower or equal to the specified value are returned. + Otherwise sole the params which have a security level defined *and* + lower or equal to the specified value are returned. @param app: name of the frontend requesting the parameters, or '' to get all parameters + @param extra (dict, None): extra options. Key can be: + - ignore: list of (category/name) values to remove from parameters @param profile_key: Profile key which can be either a magic (eg: @DEFAULT@) or the name of an existing profile. @return: XML of parameters """ - profile = self.getProfileName(profile_key) - if not profile: - log.error(_("Asking params for inexistant profile")) - return defer.succeed("") - - def returnXML(prof_xml): - return_xml = prof_xml.toxml() - prof_xml.unlink() - return "\n".join((line for line in return_xml.split("\n") if line)) - - return self._constructProfileXml(security_limit, app, profile).addCallback( - returnXML - ) + if extra is None: + extra = {} + prof_xml = await self._constructProfileXml(client, security_limit, app, extra) + return_xml = prof_xml.toxml() + prof_xml.unlink() + return "\n".join((line for line in return_xml.split("\n") if line)) def _getParamNode(self, name, category, type_="@ALL@"): # FIXME: is type_ useful ? """Return a node from the param_xml @@ -1128,6 +1120,7 @@ def checkApp(self, node, app): """Check the given node against the given app. + @param node: parameter node @param app: name of the frontend requesting the parameters, or '' to get all parameters @return: True if this node concerns the given app. @@ -1136,6 +1129,24 @@ return True return node.getAttribute("app") == app + def checkExtra(self, node, extra): + """Check the given node against the extra filters. + + @param node: parameter node + @param app: name of the frontend requesting the parameters, or '' to get all parameters + @return: True if node doesn't match category/name of extra['ignore'] list + """ + ignore_list = extra.get('ignore') + if not ignore_list: + return True + category = node.parentNode.getAttribute('name') + name = node.getAttribute('name') + ignore = [category, name] in ignore_list + if ignore: + log.debug(f"Ignoring parameter {category}/{name} as requested") + return False + return True + def makeOptions(options, selected=None): """Create option XML form dictionary diff -r 4486d72658b9 -r 130f9cb6e0ab sat_frontends/bridge/dbus_bridge.py --- a/sat_frontends/bridge/dbus_bridge.py Sat Jan 25 21:08:39 2020 +0100 +++ b/sat_frontends/bridge/dbus_bridge.py Sat Jan 25 21:08:40 2020 +0100 @@ -184,14 +184,14 @@ error_handler = lambda err:errback(dbus_to_bridge_exception(err)) return str(self.db_core_iface.asyncGetParamA(name, category, attribute, security_limit, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)) - def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None): + def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, app="", extra="", profile_key="@DEFAULT@", callback=None, errback=None): if callback is None: error_handler = None else: if errback is None: errback = log.error error_handler = lambda err:errback(dbus_to_bridge_exception(err)) - return self.db_core_iface.asyncGetParamsValuesFromCategory(category, security_limit, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler) + return self.db_core_iface.asyncGetParamsValuesFromCategory(category, security_limit, app, extra, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler) def connect(self, profile_key="@DEFAULT@", password='', options={}, callback=None, errback=None): if callback is None: @@ -400,14 +400,14 @@ kwargs['error_handler'] = error_handler return self.db_core_iface.getParamsCategories(**kwargs) - def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None): + def getParamsUI(self, security_limit=-1, app='', extra='', profile_key="@DEFAULT@", callback=None, errback=None): if callback is None: error_handler = None else: if errback is None: errback = log.error error_handler = lambda err:errback(dbus_to_bridge_exception(err)) - return str(self.db_core_iface.getParamsUI(security_limit, app, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)) + return str(self.db_core_iface.getParamsUI(security_limit, app, extra, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)) def getPresenceStatuses(self, profile_key="@DEFAULT@", callback=None, errback=None): if callback is None: @@ -908,12 +908,12 @@ self.db_core_iface.asyncGetParamA(name, category, attribute, security_limit, profile_key, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler) return fut - def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, profile_key="@DEFAULT@"): + def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, app="", extra="", profile_key="@DEFAULT@"): loop = asyncio.get_running_loop() fut = loop.create_future() reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret) error_handler = lambda err: loop.call_soon_threadsafe(fut.set_exception, dbus_to_bridge_exception(err)) - self.db_core_iface.asyncGetParamsValuesFromCategory(category, security_limit, profile_key, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler) + self.db_core_iface.asyncGetParamsValuesFromCategory(category, security_limit, app, extra, profile_key, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler) return fut def connect(self, profile_key="@DEFAULT@", password='', options={}): @@ -1060,12 +1060,12 @@ self.db_core_iface.getParamsCategories(timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler) return fut - def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@"): + def getParamsUI(self, security_limit=-1, app='', extra='', profile_key="@DEFAULT@"): loop = asyncio.get_running_loop() fut = loop.create_future() reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret) error_handler = lambda err: loop.call_soon_threadsafe(fut.set_exception, dbus_to_bridge_exception(err)) - self.db_core_iface.getParamsUI(security_limit, app, profile_key, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler) + self.db_core_iface.getParamsUI(security_limit, app, extra, profile_key, timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler) return fut def getPresenceStatuses(self, profile_key="@DEFAULT@"): diff -r 4486d72658b9 -r 130f9cb6e0ab sat_frontends/bridge/pb.py --- a/sat_frontends/bridge/pb.py Sat Jan 25 21:08:39 2020 +0100 +++ b/sat_frontends/bridge/pb.py Sat Jan 25 21:08:40 2020 +0100 @@ -175,8 +175,8 @@ errback = self._generic_errback d.addErrback(errback) - def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None): - d = self.root.callRemote("asyncGetParamsValuesFromCategory", category, security_limit, profile_key) + def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, app="", extra="", profile_key="@DEFAULT@", callback=None, errback=None): + d = self.root.callRemote("asyncGetParamsValuesFromCategory", category, security_limit, app, extra, profile_key) if callback is not None: d.addCallback(callback) if errback is None: @@ -327,8 +327,8 @@ errback = self._generic_errback d.addErrback(errback) - def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None): - d = self.root.callRemote("getParamsUI", security_limit, app, profile_key) + def getParamsUI(self, security_limit=-1, app='', extra='', profile_key="@DEFAULT@", callback=None, errback=None): + d = self.root.callRemote("getParamsUI", security_limit, app, extra, profile_key) if callback is not None: d.addCallback(callback) if errback is None: @@ -664,8 +664,8 @@ d.addErrback(self._errback) return d.asFuture(asyncio.get_event_loop()) - def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, profile_key="@DEFAULT@"): - d = self.root.callRemote("asyncGetParamsValuesFromCategory", category, security_limit, profile_key) + def asyncGetParamsValuesFromCategory(self, category, security_limit=-1, app="", extra="", profile_key="@DEFAULT@"): + d = self.root.callRemote("asyncGetParamsValuesFromCategory", category, security_limit, app, extra, profile_key) d.addErrback(self._errback) return d.asFuture(asyncio.get_event_loop()) @@ -759,8 +759,8 @@ d.addErrback(self._errback) return d.asFuture(asyncio.get_event_loop()) - def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@"): - d = self.root.callRemote("getParamsUI", security_limit, app, profile_key) + def getParamsUI(self, security_limit=-1, app='', extra='', profile_key="@DEFAULT@"): + d = self.root.callRemote("getParamsUI", security_limit, app, extra, profile_key) d.addErrback(self._errback) return d.asFuture(asyncio.get_event_loop()) diff -r 4486d72658b9 -r 130f9cb6e0ab sat_frontends/jp/cmd_param.py --- a/sat_frontends/jp/cmd_param.py Sat Jan 25 21:08:39 2020 +0100 +++ b/sat_frontends/jp/cmd_param.py Sat Jan 25 21:08:40 2020 +0100 @@ -47,7 +47,7 @@ elif self.args.name is None: try: values_dict = await self.host.bridge.asyncGetParamsValuesFromCategory( - self.args.category, self.args.security_limit, self.profile) + self.args.category, self.args.security_limit, "", "", self.profile) except Exception as e: self.disp(_(f"can't find requested parameters: {e}"), error=True) self.host.quit(C.EXIT_NOT_FOUND)