Mercurial > libervia-backend
diff sat_frontends/jp/cmd_pubsub.py @ 3568:04283582966f
core, frontends: fix invalid translatable strings.
Some f-strings where used in translatable text, this has been fixed by using explicit
`format()` call (using a script based on `tokenize`).
As tokenize messes with spaces, a reformating tool (`black`) has been applied to some
files afterwards.
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 14 Jun 2021 18:35:12 +0200 |
parents | 62f490eff51c |
children | 5f65f4e9f8cb |
line wrap: on
line diff
--- a/sat_frontends/jp/cmd_pubsub.py Mon Jun 14 12:19:21 2021 +0200 +++ b/sat_frontends/jp/cmd_pubsub.py Mon Jun 14 18:35:12 2021 +0200 @@ -82,10 +82,10 @@ self.profile, ) except BridgeException as e: - if e.condition == 'item-not-found': + if e.condition == "item-not-found": self.disp( f"The node {self.args.node} doesn't exist on {self.args.service}", - error=True + error=True, ) self.host.quit(C.EXIT_NOT_FOUND) else: @@ -155,7 +155,7 @@ self.profile, ) except Exception as e: - self.disp(msg=_(f"can't create node: {e}"), error=True) + self.disp(msg=_("can't create node: {e}").format(e=e), error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: if self.host.verbosity: @@ -167,7 +167,6 @@ class NodePurge(base.CommandBase): - def __init__(self, host): super(NodePurge, self).__init__( host, @@ -189,12 +188,14 @@ if not self.args.force: if not self.args.service: message = _( - f"Are you sure to purge PEP node [{self.args.node}]? This will " - f"delete ALL items from it!") + "Are you sure to purge PEP node [{node}]? This will " + "delete ALL items from it!" + ).format(node=self.args.node) else: message = _( - f"Are you sure to delete node [{self.args.node}] on service " - f"[{self.args.service}]? This will delete ALL items from it!") + "Are you sure to delete node [{node}] on service " + "[{service}]? This will delete ALL items from it!" + ).format(node=self.args.node, service=self.args.service) await self.host.confirmOrQuit(message, _("node purge cancelled")) try: @@ -204,10 +205,10 @@ self.profile, ) except Exception as e: - self.disp(msg=_(f"can't purge node: {e}"), error=True) + self.disp(msg=_("can't purge node: {e}").format(e=e), error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: - self.disp(_(f"node [{self.args.node}] purged successfully")) + self.disp(_("node [{node}] purged successfully").format(node=self.args.node)) self.host.quit() @@ -233,10 +234,13 @@ async def start(self): if not self.args.force: if not self.args.service: - message = _(f"Are you sure to delete PEP node [{self.args.node}] ?") + message = _("Are you sure to delete PEP node [{node}] ?").format( + node=self.args.node + ) else: - message = _(f"Are you sure to delete node [{self.args.node}] on " - f"service [{self.args.service}]?") + message = _( + "Are you sure to delete node [{node}] on " "service [{service}]?" + ).format(node=self.args.node, service=self.args.service) await self.host.confirmOrQuit(message, _("node deletion cancelled")) try: @@ -249,7 +253,7 @@ self.disp(f"can't delete node: {e}", error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: - self.disp(_(f"node [{self.args.node}] deleted successfully")) + self.disp(_("node [{node}] deleted successfully").format(node=self.args.node)) self.host.quit() @@ -307,7 +311,6 @@ class NodeImport(base.CommandBase): - def __init__(self, host): super(NodeImport, self).__init__( host, @@ -326,16 +329,20 @@ self.parser.add_argument( "import_file", type=argparse.FileType(), - help=_("path to the XML file with data to import. The file must contain " - "whole XML of each item to import."), + help=_( + "path to the XML file with data to import. The file must contain " + "whole XML of each item to import." + ), ) async def start(self): try: - element, etree = xml_tools.etreeParse(self, self.args.import_file, - reraise=True) + element, etree = xml_tools.etreeParse( + self, self.args.import_file, reraise=True + ) except Exception as e: from lxml.etree import XMLSyntaxError + if isinstance(e, XMLSyntaxError) and e.code == 5: # we have extra content, this probaby means that item are not wrapped # so we wrap them here and try again @@ -343,14 +350,15 @@ xml_buf = "<import>" + self.args.import_file.read() + "</import>" element, etree = xml_tools.etreeParse(self, xml_buf) - # we reverse element as we expect to have most recently published element first - # TODO: make this more explicit and add an option + # we reverse element as we expect to have most recently published element first + # TODO: make this more explicit and add an option element[:] = reversed(element) - if not all([i.tag == '{http://jabber.org/protocol/pubsub}item' for i in element]): + if not all([i.tag == "{http://jabber.org/protocol/pubsub}item" for i in element]): self.disp( _("You are not using list of pubsub items, we can't import this file"), - error=True) + error=True, + ) self.host.quit(C.EXIT_DATA_ERROR) return @@ -358,8 +366,12 @@ if self.args.admin: method = self.host.bridge.psAdminItemsSend else: - self.disp(_("Items are imported without using admin mode, publisher can't " - "be changed")) + self.disp( + _( + "Items are imported without using admin mode, publisher can't " + "be changed" + ) + ) method = self.host.bridge.psItemsSend try: @@ -375,10 +387,13 @@ self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: if items_ids: - self.disp(_('items published with id(s) {items_ids}').format( - items_ids=', '.join(items_ids))) + self.disp( + _("items published with id(s) {items_ids}").format( + items_ids=", ".join(items_ids) + ) + ) else: - self.disp(_('items published')) + self.disp(_("items published")) self.host.quit() @@ -645,8 +660,9 @@ try: from lxml import etree except ImportError: - self.disp('lxml module must be installed to use edit, please install it ' - 'with "pip install lxml"', + self.disp( + "lxml module must be installed to use edit, please install it " + 'with "pip install lxml"', error=True, ) self.host.quit(1) @@ -659,7 +675,9 @@ etree.tostring(schema_elt, encoding="utf-8", pretty_print=True) ) content_file_obj.seek(0) - await self.runEditor("pubsub_schema_editor_args", content_file_path, content_file_obj) + await self.runEditor( + "pubsub_schema_editor_args", content_file_path, content_file_obj + ) async def start(self): try: @@ -669,7 +687,7 @@ self.profile, ) except BridgeException as e: - if e.condition == 'item-not-found' or e.classname=="NotFound": + if e.condition == "item-not-found" or e.classname == "NotFound": schema = "" else: self.disp(f"can't edit schema: {e}", error=True) @@ -702,7 +720,7 @@ self.profile, ) except BridgeException as e: - if e.condition == 'item-not-found' or e.classname=="NotFound": + if e.condition == "item-not-found" or e.classname == "NotFound": schema = None else: self.disp(f"can't get schema: {e}", error=True) @@ -772,7 +790,7 @@ extra = {} publish_options = NodeCreate.get_config_options(self.args) if publish_options: - extra['publish_options'] = publish_options + extra["publish_options"] = publish_options try: published_id = await self.host.bridge.psItemSend( @@ -784,12 +802,12 @@ self.profile, ) except Exception as e: - self.disp(_(f"can't send item: {e}"), error=True) + self.disp(_("can't send item: {e}").format(e=e), error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: if published_id: if self.args.quiet: - self.disp(published_id, end='') + self.disp(published_id, end="") else: self.disp(f"Item published at {published_id}") else: @@ -833,10 +851,10 @@ ) ) except BridgeException as e: - if e.condition == 'item-not-found' or e.classname=="NotFound": + if e.condition == "item-not-found" or e.classname == "NotFound": self.disp( f"The node {self.args.node} doesn't exist on {self.args.service}", - error=True + error=True, ) self.host.quit(C.EXIT_NOT_FOUND) else: @@ -846,7 +864,7 @@ self.disp(f"Internal error: {e}", error=True) self.host.quit(C.EXIT_INTERNAL_ERROR) else: - await self.output(ps_result['items']) + await self.output(ps_result["items"]) self.host.quit(C.EXIT_OK) @@ -886,10 +904,10 @@ self.profile, ) except Exception as e: - self.disp(_(f"can't delete item: {e}"), error=True) + self.disp(_("can't delete item: {e}").format(e=e), error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: - self.disp(_(f"item {self.args.item} has been deleted")) + self.disp(_("item {item} has been deleted").format(item=self.args.item)) self.host.quit(C.EXIT_OK) @@ -928,8 +946,9 @@ try: from lxml import etree except ImportError: - self.disp('lxml module must be installed to use edit, please install it ' - 'with "pip install lxml"', + self.disp( + "lxml module must be installed to use edit, please install it " + 'with "pip install lxml"', error=True, ) self.host.quit(1) @@ -939,7 +958,7 @@ service, node, 1, items, "", {}, self.profile ) ) - item_raw = ps_result['items'][0] + item_raw = ps_result["items"][0] parser = etree.XMLParser(remove_blank_text=True, recover=True) item_elt = etree.fromstring(item_raw, parser) item_id = item_elt.get("id") @@ -951,17 +970,18 @@ return etree.tostring(payload, encoding="unicode", pretty_print=True), item_id async def start(self): - (self.pubsub_service, - self.pubsub_node, - self.pubsub_item, - content_file_path, - content_file_obj) = await self.getItemPath() + ( + self.pubsub_service, + self.pubsub_node, + self.pubsub_item, + content_file_path, + content_file_obj, + ) = await self.getItemPath() await self.runEditor("pubsub_editor_args", content_file_path, content_file_obj) self.host.quit() class Rename(base.CommandBase): - def __init__(self, host): base.CommandBase.__init__( self, @@ -973,10 +993,7 @@ ) def add_parser_options(self): - self.parser.add_argument( - "new_id", - help=_("new item id to use") - ) + self.parser.add_argument("new_id", help=_("new item id to use")) async def start(self): try: @@ -988,9 +1005,7 @@ self.profile, ) except Exception as e: - self.disp( - f"can't rename item: {e}", error=True - ) + self.disp(f"can't rename item: {e}", error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: self.disp("Item renamed") @@ -1021,7 +1036,7 @@ self.profile, ) except Exception as e: - self.disp(_(f"can't subscribe to node: {e}"), error=True) + self.disp(_("can't subscribe to node: {e}").format(e=e), error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: self.disp(_("subscription done"), 1) @@ -1055,7 +1070,7 @@ self.profile, ) except Exception as e: - self.disp(_(f"can't unsubscribe from node: {e}"), error=True) + self.disp(_("can't unsubscribe from node: {e}").format(e=e), error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: self.disp(_("subscription removed"), 1) @@ -1084,7 +1099,7 @@ self.profile, ) except Exception as e: - self.disp(_(f"can't retrieve subscriptions: {e}"), error=True) + self.disp(_("can't retrieve subscriptions: {e}").format(e=e), error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: await self.output(subscriptions) @@ -1113,9 +1128,7 @@ self.profile, ) except Exception as e: - self.disp( - f"can't get node affiliations: {e}", error=True - ) + self.disp(f"can't get node affiliations: {e}", error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: await self.output(affiliations) @@ -1169,16 +1182,20 @@ "--max-depth", type=int, default=0, - help=_("maximum depth of recursion (will search linked nodes if > 0, " - "DEFAULT: 0)"), + help=_( + "maximum depth of recursion (will search linked nodes if > 0, " + "DEFAULT: 0)" + ), ) self.parser.add_argument( "-M", "--node-max", type=int, default=30, - help=_("maximum number of items to get per node ({} to get all items, " - "DEFAULT: 30)".format( C.NO_LIMIT)), + help=_( + "maximum number of items to get per node ({} to get all items, " + "DEFAULT: 30)".format(C.NO_LIMIT) + ), ) self.parser.add_argument( "-N", @@ -1233,9 +1250,10 @@ dest="filters", type=filter_python, metavar="PYTHON_CODE", - help=_('Python expression which much return a bool (True to keep item, ' - 'False to reject it). "item" is raw text item, "item_xml" is ' - 'lxml\'s etree.Element' + help=_( + "Python expression which much return a bool (True to keep item, " + 'False to reject it). "item" is raw text item, "item_xml" is ' + "lxml's etree.Element" ), ) @@ -1362,8 +1380,10 @@ return self.etree.fromstring(item) except self.etree.XMLSyntaxError: self.disp( - _("item doesn't looks like XML, you have probably used --only-matching " - "somewhere before and we have no more XML"), + _( + "item doesn't looks like XML, you have probably used --only-matching " + "somewhere before and we have no more XML" + ), error=True, ) self.host.quit(C.EXIT_BAD_ARG) @@ -1397,9 +1417,7 @@ # doesn't really make sens to keep a fixed string # so we raise an error self.host.disp( - _( - "--only-matching used with fixed --text string, are you sure?" - ), + _("--only-matching used with fixed --text string, are you sure?"), error=True, ) self.host.quit(C.EXIT_BAD_ARG) @@ -1420,9 +1438,7 @@ try: elts = item_xml.xpath(value, namespaces=self.args.namespace) except self.etree.XPathEvalError as e: - self.disp( - _("can't use xpath: {reason}").format(reason=e), error=True - ) + self.disp(_("can't use xpath: {reason}").format(reason=e), error=True) self.host.quit(C.EXIT_BAD_ARG) keep = bool(elts) if keep and only_matching: @@ -1436,18 +1452,14 @@ elif type_ == "python": if item_xml is None: item_xml = self.parseXml(item) - cmd_ns = { - "etree": self.etree, - "item": item, - "item_xml": item_xml - } + cmd_ns = {"etree": self.etree, "item": item, "item_xml": item_xml} try: keep = eval(value, cmd_ns) except SyntaxError as e: self.disp(str(e), error=True) self.host.quit(C.EXIT_BAD_ARG) - ## flags + ## flags elif type_ == "ignore-case": ignore_case = value @@ -1512,15 +1524,14 @@ p = await asyncio.create_subprocess_exec(*cmd_args) ret = await p.wait() else: - p = await asyncio.create_subprocess_exec(*cmd_args, - stdin=subprocess.PIPE) + p = await asyncio.create_subprocess_exec(*cmd_args, stdin=subprocess.PIPE) await p.communicate(item.encode(sys.getfilesystemencoding())) ret = p.returncode if ret != 0: self.disp( A.color( C.A_FAILURE, - _(f"executed command failed with exit code {ret}"), + _("executed command failed with exit code {ret}").format(ret=ret), ) ) @@ -1533,7 +1544,7 @@ @param depth(int): current depth level 0 for first node, 1 for first children, and so on """ - for item in ps_result['items']: + for item in ps_result["items"]: if depth < self.args.max_depth: await self.getSubNodes(item, depth) keep, item = self.filter(item) @@ -1541,7 +1552,7 @@ continue await self.doItemAction(item, ps_result) - # we check if we got all getItems results + # we check if we got all getItems results self.to_get -= 1 if self.to_get == 0: # yes, we can quit @@ -1562,8 +1573,8 @@ if not self.args.node: # TODO: handle get service affiliations when node is not set self.parser.error(_("empty node is not handled yet")) - # to_get is increased on each get and decreased on each answer - # when it reach 0 again, the command is finished + # to_get is increased on each get and decreased on each answer + # when it reach 0 again, the command is finished self.to_get = 0 self._etree = None if self.args.filters is None: @@ -1601,27 +1612,33 @@ "--ignore-errors", action="store_true", help=_( - "if command return a non zero exit code, ignore the item and continue"), + "if command return a non zero exit code, ignore the item and continue" + ), ) self.parser.add_argument( "-A", "--all", action="store_true", - help=_("get all items by looping over all pages using RSM") + help=_("get all items by looping over all pages using RSM"), ) self.parser.add_argument( "command_path", - help=_("path to the command to use. Will be called repetitivly with an " - "item as input. Output (full item XML) will be used as new one. " - 'Return "DELETE" string to delete the item, and "SKIP" to ignore it'), + help=_( + "path to the command to use. Will be called repetitivly with an " + "item as input. Output (full item XML) will be used as new one. " + 'Return "DELETE" string to delete the item, and "SKIP" to ignore it' + ), ) async def psItemsSendCb(self, item_ids, metadata): if item_ids: - self.disp(_('items published with ids {item_ids}').format( - item_ids=', '.join(item_ids))) + self.disp( + _("items published with ids {item_ids}").format( + item_ids=", ".join(item_ids) + ) + ) else: - self.disp(_('items published')) + self.disp(_("items published")) if self.args.all: return await self.handleNextPage(metadata) else: @@ -1634,30 +1651,34 @@ @param metadata(dict): metadata as returned by psItemsGet """ try: - last = metadata['rsm']['last'] - index = int(metadata['rsm']['index']) - count = int(metadata['rsm']['count']) + last = metadata["rsm"]["last"] + index = int(metadata["rsm"]["index"]) + count = int(metadata["rsm"]["count"]) except KeyError: - self.disp(_("Can't retrieve all items, RSM metadata not available"), - error=True) + self.disp( + _("Can't retrieve all items, RSM metadata not available"), error=True + ) self.host.quit(C.EXIT_MISSING_FEATURE) except ValueError as e: - self.disp(_("Can't retrieve all items, bad RSM metadata: {msg}") - .format(msg=e), error=True) + self.disp( + _("Can't retrieve all items, bad RSM metadata: {msg}").format(msg=e), + error=True, + ) self.host.quit(C.EXIT_ERROR) if index + self.args.rsm_max >= count: - self.disp(_('All items transformed')) + self.disp(_("All items transformed")) self.host.quit(0) - self.disp(_('Retrieving next page ({page_idx}/{page_total})').format( - page_idx = int(index/self.args.rsm_max) + 1, - page_total = int(count/self.args.rsm_max), + self.disp( + _("Retrieving next page ({page_idx}/{page_total})").format( + page_idx=int(index / self.args.rsm_max) + 1, + page_total=int(count / self.args.rsm_max), ) ) extra = self.getPubsubExtra() - extra['rsm_after'] = last + extra["rsm_after"] = last try: ps_result = await data_format.deserialise( self.host.bridge.psItemsGet( @@ -1671,36 +1692,36 @@ ) ) except Exception as e: - self.disp( - f"can't retrieve items: {e}", error=True - ) + self.disp(f"can't retrieve items: {e}", error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: await self.psItemsGetCb(ps_result) async def psItemsGetCb(self, ps_result): - encoding = 'utf-8' + encoding = "utf-8" new_items = [] - for item in ps_result['items']: + for item in ps_result["items"]: if self.check_duplicates: # this is used when we are not ordering by creation # to avoid infinite loop item_elt, __ = xml_tools.etreeParse(self, item) - item_id = item_elt.get('id') + item_id = item_elt.get("id") if item_id in self.items_ids: - self.disp(_( - "Duplicate found on item {item_id}, we have probably handled " - "all items.").format(item_id=item_id)) + self.disp( + _( + "Duplicate found on item {item_id}, we have probably handled " + "all items." + ).format(item_id=item_id) + ) self.host.quit() self.items_ids.append(item_id) - # we launch the command to filter the item + # we launch the command to filter the item try: p = await asyncio.create_subprocess_exec( - self.args.command_path, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE) + self.args.command_path, stdin=subprocess.PIPE, stdout=subprocess.PIPE + ) except OSError as e: exit_code = C.EXIT_CMD_NOT_FOUND if e.errno == 2 else C.EXIT_ERROR self.disp(f"Can't execute the command: {e}", error=True) @@ -1709,20 +1730,23 @@ cmd_std_out, cmd_std_err = await p.communicate(item.encode(encoding)) ret = p.returncode if ret != 0: - self.disp(f"The command returned a non zero status while parsing the " - f"following item:\n\n{item}", error=True) + self.disp( + f"The command returned a non zero status while parsing the " + f"following item:\n\n{item}", + error=True, + ) if self.args.ignore_errors: continue else: self.host.quit(C.EXIT_CMD_ERROR) if cmd_std_err is not None: - cmd_std_err = cmd_std_err.decode(encoding, errors='ignore') + cmd_std_err = cmd_std_err.decode(encoding, errors="ignore") self.disp(cmd_std_err, error=True) cmd_std_out = cmd_std_out.decode(encoding).strip() if cmd_std_out == "DELETE": item_elt, __ = xml_tools.etreeParse(self, item) - item_id = item_elt.get('id') - self.disp(_(f"Deleting item {item_id}")) + item_id = item_elt.get("id") + self.disp(_("Deleting item {item_id}").format(item_id=item_id)) if self.args.apply: try: await self.host.bridge.psItemRetract( @@ -1733,28 +1757,31 @@ self.profile, ) except Exception as e: - self.disp( - f"can't delete item {item_id}: {e}", error=True - ) + self.disp(f"can't delete item {item_id}: {e}", error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) continue elif cmd_std_out == "SKIP": item_elt, __ = xml_tools.etreeParse(self, item) - item_id = item_elt.get('id') + item_id = item_elt.get("id") self.disp(_("Skipping item {item_id}").format(item_id=item_id)) continue element, etree = xml_tools.etreeParse(self, cmd_std_out) # at this point command has been run and we have a etree.Element object if element.tag not in ("item", "{http://jabber.org/protocol/pubsub}item"): - self.disp("your script must return a whole item, this is not:\n{xml}" - .format(xml=etree.tostring(element, encoding="unicode")), error=True) + self.disp( + "your script must return a whole item, this is not:\n{xml}".format( + xml=etree.tostring(element, encoding="unicode") + ), + error=True, + ) self.host.quit(C.EXIT_DATA_ERROR) if not self.args.apply: # we have a dry run, we just display filtered items - serialised = etree.tostring(element, encoding='unicode', - pretty_print=True) + serialised = etree.tostring( + element, encoding="unicode", pretty_print=True + ) self.disp(serialised) else: new_items.append(etree.tostring(element, encoding="unicode")) @@ -1788,13 +1815,17 @@ if self.args.all and self.args.order_by != C.ORDER_BY_CREATION: self.check_duplicates = True self.items_ids = [] - self.disp(A.color( - A.FG_RED, A.BOLD, - '/!\\ "--all" should be used with "--order-by creation" /!\\\n', - A.RESET, - "We'll update items, so order may change during transformation,\n" - "we'll try to mitigate that by stopping on first duplicate,\n" - "but this method is not safe, and some items may be missed.\n---\n")) + self.disp( + A.color( + A.FG_RED, + A.BOLD, + '/!\\ "--all" should be used with "--order-by creation" /!\\\n', + A.RESET, + "We'll update items, so order may change during transformation,\n" + "we'll try to mitigate that by stopping on first duplicate,\n" + "but this method is not safe, and some items may be missed.\n---\n", + ) + ) else: self.check_duplicates = False @@ -1855,9 +1886,7 @@ if not self.args.service: try: jid_ = await self.host.bridge.asyncGetParamA( - "JabberID", - "Connection", - profile_key=self.args.profile + "JabberID", "Connection", profile_key=self.args.profile ) except Exception as e: self.disp(f"can't retrieve jid: {e}", error=True) @@ -1968,7 +1997,9 @@ self.disp(f"can't delete hook: {e}", error=True) self.host.quit(C.EXIT_BRIDGE_ERRBACK) else: - self.disp(_(f"{nb_deleted} hook(s) have been deleted")) + self.disp( + _("{nb_deleted} hook(s) have been deleted").format(nb_deleted=nb_deleted) + ) self.host.quit()