comparison sat_frontends/jp/cmd_pubsub.py @ 4037:524856bd7b19

massive refactoring to switch from camelCase to snake_case: historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a pre-PEP8 code, to use the same coding style as in Twisted. However, snake_case is more readable and it's better to follow PEP8 best practices, so it has been decided to move on full snake_case. Because Libervia has a huge codebase, this ended with a ugly mix of camelCase and snake_case. To fix that, this patch does a big refactoring by renaming every function and method (including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case. This is a massive change, and may result in some bugs.
author Goffi <goffi@goffi.org>
date Sat, 08 Apr 2023 13:54:42 +0200
parents 570254d5a798
children 4b842c1fb686
comparison
equal deleted inserted replaced
4036:c4464d7ae97b 4037:524856bd7b19
68 action="append", 68 action="append",
69 dest="keys", 69 dest="keys",
70 help=_("data key to filter"), 70 help=_("data key to filter"),
71 ) 71 )
72 72
73 def removePrefix(self, key): 73 def remove_prefix(self, key):
74 return key[7:] if key.startswith("pubsub#") else key 74 return key[7:] if key.startswith("pubsub#") else key
75 75
76 def filterKey(self, key): 76 def filter_key(self, key):
77 return any((key == k or key == "pubsub#" + k) for k in self.args.keys) 77 return any((key == k or key == "pubsub#" + k) for k in self.args.keys)
78 78
79 async def start(self): 79 async def start(self):
80 try: 80 try:
81 config_dict = await self.host.bridge.psNodeConfigurationGet( 81 config_dict = await self.host.bridge.ps_node_configuration_get(
82 self.args.service, 82 self.args.service,
83 self.args.node, 83 self.args.node,
84 self.profile, 84 self.profile,
85 ) 85 )
86 except BridgeException as e: 86 except BridgeException as e:
95 self.host.quit(C.EXIT_BRIDGE_ERRBACK) 95 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
96 except Exception as e: 96 except Exception as e:
97 self.disp(f"Internal error: {e}", error=True) 97 self.disp(f"Internal error: {e}", error=True)
98 self.host.quit(C.EXIT_INTERNAL_ERROR) 98 self.host.quit(C.EXIT_INTERNAL_ERROR)
99 else: 99 else:
100 key_filter = (lambda k: True) if not self.args.keys else self.filterKey 100 key_filter = (lambda k: True) if not self.args.keys else self.filter_key
101 config_dict = { 101 config_dict = {
102 self.removePrefix(k): v for k, v in config_dict.items() if key_filter(k) 102 self.remove_prefix(k): v for k, v in config_dict.items() if key_filter(k)
103 } 103 }
104 await self.output(config_dict) 104 await self.output(config_dict)
105 self.host.quit() 105 self.host.quit()
106 106
107 107
148 return dict(args.fields) 148 return dict(args.fields)
149 149
150 async def start(self): 150 async def start(self):
151 options = self.get_config_options(self.args) 151 options = self.get_config_options(self.args)
152 try: 152 try:
153 node_id = await self.host.bridge.psNodeCreate( 153 node_id = await self.host.bridge.ps_node_create(
154 self.args.service, 154 self.args.service,
155 self.args.node, 155 self.args.node,
156 options, 156 options,
157 self.profile, 157 self.profile,
158 ) 158 )
196 else: 196 else:
197 message = _( 197 message = _(
198 "Are you sure to delete node [{node}] on service " 198 "Are you sure to delete node [{node}] on service "
199 "[{service}]? This will delete ALL items from it!" 199 "[{service}]? This will delete ALL items from it!"
200 ).format(node=self.args.node, service=self.args.service) 200 ).format(node=self.args.node, service=self.args.service)
201 await self.host.confirmOrQuit(message, _("node purge cancelled")) 201 await self.host.confirm_or_quit(message, _("node purge cancelled"))
202 202
203 try: 203 try:
204 await self.host.bridge.psNodePurge( 204 await self.host.bridge.ps_node_purge(
205 self.args.service, 205 self.args.service,
206 self.args.node, 206 self.args.node,
207 self.profile, 207 self.profile,
208 ) 208 )
209 except Exception as e: 209 except Exception as e:
241 ) 241 )
242 else: 242 else:
243 message = _( 243 message = _(
244 "Are you sure to delete node [{node}] on " "service [{service}]?" 244 "Are you sure to delete node [{node}] on " "service [{service}]?"
245 ).format(node=self.args.node, service=self.args.service) 245 ).format(node=self.args.node, service=self.args.service)
246 await self.host.confirmOrQuit(message, _("node deletion cancelled")) 246 await self.host.confirm_or_quit(message, _("node deletion cancelled"))
247 247
248 try: 248 try:
249 await self.host.bridge.psNodeDelete( 249 await self.host.bridge.ps_node_delete(
250 self.args.service, 250 self.args.service,
251 self.args.node, 251 self.args.node,
252 self.profile, 252 self.profile,
253 ) 253 )
254 except Exception as e: 254 except Exception as e:
288 "--full-prefix", 288 "--full-prefix",
289 action="store_true", 289 action="store_true",
290 help=_('don\'t prepend "pubsub#" prefix to field names'), 290 help=_('don\'t prepend "pubsub#" prefix to field names'),
291 ) 291 )
292 292
293 def getKeyName(self, k): 293 def get_key_name(self, k):
294 if self.args.full_prefix or k.startswith("pubsub#"): 294 if self.args.full_prefix or k.startswith("pubsub#"):
295 return k 295 return k
296 else: 296 else:
297 return "pubsub#" + k 297 return "pubsub#" + k
298 298
299 async def start(self): 299 async def start(self):
300 try: 300 try:
301 await self.host.bridge.psNodeConfigurationSet( 301 await self.host.bridge.ps_node_configuration_set(
302 self.args.service, 302 self.args.service,
303 self.args.node, 303 self.args.node,
304 {self.getKeyName(k): v for k, v in self.args.fields}, 304 {self.get_key_name(k): v for k, v in self.args.fields},
305 self.profile, 305 self.profile,
306 ) 306 )
307 except Exception as e: 307 except Exception as e:
308 self.disp(f"can't set node configuration: {e}", error=True) 308 self.disp(f"can't set node configuration: {e}", error=True)
309 self.host.quit(C.EXIT_BRIDGE_ERRBACK) 309 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
337 ), 337 ),
338 ) 338 )
339 339
340 async def start(self): 340 async def start(self):
341 try: 341 try:
342 element, etree = xml_tools.etreeParse( 342 element, etree = xml_tools.etree_parse(
343 self, self.args.import_file, reraise=True 343 self, self.args.import_file, reraise=True
344 ) 344 )
345 except Exception as e: 345 except Exception as e:
346 from lxml.etree import XMLSyntaxError 346 from lxml.etree import XMLSyntaxError
347 347
348 if isinstance(e, XMLSyntaxError) and e.code == 5: 348 if isinstance(e, XMLSyntaxError) and e.code == 5:
349 # we have extra content, this probaby means that item are not wrapped 349 # we have extra content, this probaby means that item are not wrapped
350 # so we wrap them here and try again 350 # so we wrap them here and try again
351 self.args.import_file.seek(0) 351 self.args.import_file.seek(0)
352 xml_buf = "<import>" + self.args.import_file.read() + "</import>" 352 xml_buf = "<import>" + self.args.import_file.read() + "</import>"
353 element, etree = xml_tools.etreeParse(self, xml_buf) 353 element, etree = xml_tools.etree_parse(self, xml_buf)
354 354
355 # we reverse element as we expect to have most recently published element first 355 # we reverse element as we expect to have most recently published element first
356 # TODO: make this more explicit and add an option 356 # TODO: make this more explicit and add an option
357 element[:] = reversed(element) 357 element[:] = reversed(element)
358 358
364 self.host.quit(C.EXIT_DATA_ERROR) 364 self.host.quit(C.EXIT_DATA_ERROR)
365 return 365 return
366 366
367 items = [etree.tostring(i, encoding="unicode") for i in element] 367 items = [etree.tostring(i, encoding="unicode") for i in element]
368 if self.args.admin: 368 if self.args.admin:
369 method = self.host.bridge.psAdminItemsSend 369 method = self.host.bridge.ps_admin_items_send
370 else: 370 else:
371 self.disp( 371 self.disp(
372 _( 372 _(
373 "Items are imported without using admin mode, publisher can't " 373 "Items are imported without using admin mode, publisher can't "
374 "be changed" 374 "be changed"
375 ) 375 )
376 ) 376 )
377 method = self.host.bridge.psItemsSend 377 method = self.host.bridge.ps_items_send
378 378
379 try: 379 try:
380 items_ids = await method( 380 items_ids = await method(
381 self.args.service, 381 self.args.service,
382 self.args.node, 382 self.args.node,
414 def add_parser_options(self): 414 def add_parser_options(self):
415 pass 415 pass
416 416
417 async def start(self): 417 async def start(self):
418 try: 418 try:
419 affiliations = await self.host.bridge.psNodeAffiliationsGet( 419 affiliations = await self.host.bridge.ps_node_affiliations_get(
420 self.args.service, 420 self.args.service,
421 self.args.node, 421 self.args.node,
422 self.profile, 422 self.profile,
423 ) 423 )
424 except Exception as e: 424 except Exception as e:
456 ) 456 )
457 457
458 async def start(self): 458 async def start(self):
459 affiliations = dict(self.args.affiliations) 459 affiliations = dict(self.args.affiliations)
460 try: 460 try:
461 await self.host.bridge.psNodeAffiliationsSet( 461 await self.host.bridge.ps_node_affiliations_set(
462 self.args.service, 462 self.args.service,
463 self.args.node, 463 self.args.node,
464 affiliations, 464 affiliations,
465 self.profile, 465 self.profile,
466 ) 466 )
503 help=_("get public subscriptions"), 503 help=_("get public subscriptions"),
504 ) 504 )
505 505
506 async def start(self): 506 async def start(self):
507 if self.args.public: 507 if self.args.public:
508 method = self.host.bridge.psPublicNodeSubscriptionsGet 508 method = self.host.bridge.ps_public_node_subscriptions_get
509 else: 509 else:
510 method = self.host.bridge.psNodeSubscriptionsGet 510 method = self.host.bridge.ps_node_subscriptions_get
511 try: 511 try:
512 subscriptions = await method( 512 subscriptions = await method(
513 self.args.service, 513 self.args.service,
514 self.args.node, 514 self.args.node,
515 self.profile, 515 self.profile,
573 help=_("entity/subscription couple(s)"), 573 help=_("entity/subscription couple(s)"),
574 ) 574 )
575 575
576 async def start(self): 576 async def start(self):
577 try: 577 try:
578 self.host.bridge.psNodeSubscriptionsSet( 578 self.host.bridge.ps_node_subscriptions_set(
579 self.args.service, 579 self.args.service,
580 self.args.node, 580 self.args.node,
581 self.args.subscriptions, 581 self.args.subscriptions,
582 self.profile, 582 self.profile,
583 ) 583 )
616 def add_parser_options(self): 616 def add_parser_options(self):
617 self.parser.add_argument("schema", help=_("schema to set (must be XML)")) 617 self.parser.add_argument("schema", help=_("schema to set (must be XML)"))
618 618
619 async def start(self): 619 async def start(self):
620 try: 620 try:
621 await self.host.bridge.psSchemaSet( 621 await self.host.bridge.ps_schema_set(
622 self.args.service, 622 self.args.service,
623 self.args.node, 623 self.args.node,
624 self.args.schema, 624 self.args.schema,
625 self.profile, 625 self.profile,
626 ) 626 )
651 def add_parser_options(self): 651 def add_parser_options(self):
652 pass 652 pass
653 653
654 async def publish(self, schema): 654 async def publish(self, schema):
655 try: 655 try:
656 await self.host.bridge.psSchemaSet( 656 await self.host.bridge.ps_schema_set(
657 self.args.service, 657 self.args.service,
658 self.args.node, 658 self.args.node,
659 schema, 659 schema,
660 self.profile, 660 self.profile,
661 ) 661 )
664 self.host.quit(C.EXIT_BRIDGE_ERRBACK) 664 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
665 else: 665 else:
666 self.disp(_("schema has been set"), 1) 666 self.disp(_("schema has been set"), 1)
667 self.host.quit() 667 self.host.quit()
668 668
669 async def psSchemaGetCb(self, schema): 669 async def ps_schema_get_cb(self, schema):
670 try: 670 try:
671 from lxml import etree 671 from lxml import etree
672 except ImportError: 672 except ImportError:
673 self.disp( 673 self.disp(
674 "lxml module must be installed to use edit, please install it " 674 "lxml module must be installed to use edit, please install it "
675 'with "pip install lxml"', 675 'with "pip install lxml"',
676 error=True, 676 error=True,
677 ) 677 )
678 self.host.quit(1) 678 self.host.quit(1)
679 content_file_obj, content_file_path = self.getTmpFile() 679 content_file_obj, content_file_path = self.get_tmp_file()
680 schema = schema.strip() 680 schema = schema.strip()
681 if schema: 681 if schema:
682 parser = etree.XMLParser(remove_blank_text=True) 682 parser = etree.XMLParser(remove_blank_text=True)
683 schema_elt = etree.fromstring(schema, parser) 683 schema_elt = etree.fromstring(schema, parser)
684 content_file_obj.write( 684 content_file_obj.write(
685 etree.tostring(schema_elt, encoding="utf-8", pretty_print=True) 685 etree.tostring(schema_elt, encoding="utf-8", pretty_print=True)
686 ) 686 )
687 content_file_obj.seek(0) 687 content_file_obj.seek(0)
688 await self.runEditor( 688 await self.run_editor(
689 "pubsub_schema_editor_args", content_file_path, content_file_obj 689 "pubsub_schema_editor_args", content_file_path, content_file_obj
690 ) 690 )
691 691
692 async def start(self): 692 async def start(self):
693 try: 693 try:
694 schema = await self.host.bridge.psSchemaGet( 694 schema = await self.host.bridge.ps_schema_get(
695 self.args.service, 695 self.args.service,
696 self.args.node, 696 self.args.node,
697 self.profile, 697 self.profile,
698 ) 698 )
699 except BridgeException as e: 699 except BridgeException as e:
701 schema = "" 701 schema = ""
702 else: 702 else:
703 self.disp(f"can't edit schema: {e}", error=True) 703 self.disp(f"can't edit schema: {e}", error=True)
704 self.host.quit(C.EXIT_BRIDGE_ERRBACK) 704 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
705 705
706 await self.psSchemaGetCb(schema) 706 await self.ps_schema_get_cb(schema)
707 707
708 708
709 class NodeSchemaGet(base.CommandBase): 709 class NodeSchemaGet(base.CommandBase):
710 def __init__(self, host): 710 def __init__(self, host):
711 base.CommandBase.__init__( 711 base.CommandBase.__init__(
722 def add_parser_options(self): 722 def add_parser_options(self):
723 pass 723 pass
724 724
725 async def start(self): 725 async def start(self):
726 try: 726 try:
727 schema = await self.host.bridge.psSchemaGet( 727 schema = await self.host.bridge.ps_schema_get(
728 self.args.service, 728 self.args.service,
729 self.args.node, 729 self.args.node,
730 self.profile, 730 self.profile,
731 ) 731 )
732 except BridgeException as e: 732 except BridgeException as e:
792 ) 792 )
793 793
794 async def start(self): 794 async def start(self):
795 try: 795 try:
796 ps_result = data_format.deserialise( 796 ps_result = data_format.deserialise(
797 await self.host.bridge.psCacheGet( 797 await self.host.bridge.ps_cache_get(
798 self.args.service, 798 self.args.service,
799 self.args.node, 799 self.args.node,
800 self.args.max, 800 self.args.max,
801 self.args.items, 801 self.args.items,
802 self.args.sub_id, 802 self.args.sub_id,
803 self.getPubsubExtra(), 803 self.get_pubsub_extra(),
804 self.profile, 804 self.profile,
805 ) 805 )
806 ) 806 )
807 except BridgeException as e: 807 except BridgeException as e:
808 if e.classname == "NotFound": 808 if e.classname == "NotFound":
837 def add_parser_options(self): 837 def add_parser_options(self):
838 pass 838 pass
839 839
840 async def start(self): 840 async def start(self):
841 try: 841 try:
842 await self.host.bridge.psCacheSync( 842 await self.host.bridge.ps_cache_sync(
843 self.args.service, 843 self.args.service,
844 self.args.node, 844 self.args.node,
845 self.profile, 845 self.profile,
846 ) 846 )
847 except BridgeException as e: 847 except BridgeException as e:
908 help=_("purge items without confirmation") 908 help=_("purge items without confirmation")
909 ) 909 )
910 910
911 async def start(self): 911 async def start(self):
912 if not self.args.force: 912 if not self.args.force:
913 await self.host.confirmOrQuit( 913 await self.host.confirm_or_quit(
914 _( 914 _(
915 "Are you sure to purge items from cache? You'll have to bypass cache " 915 "Are you sure to purge items from cache? You'll have to bypass cache "
916 "or resynchronise nodes to access deleted items again." 916 "or resynchronise nodes to access deleted items again."
917 ), 917 ),
918 _("Items purgins has been cancelled.") 918 _("Items purgins has been cancelled.")
924 ): 924 ):
925 value = getattr(self.args, key) 925 value = getattr(self.args, key)
926 if value is not None: 926 if value is not None:
927 purge_data[key] = value 927 purge_data[key] = value
928 try: 928 try:
929 await self.host.bridge.psCachePurge( 929 await self.host.bridge.ps_cache_purge(
930 data_format.serialise( 930 data_format.serialise(
931 purge_data 931 purge_data
932 ) 932 )
933 ) 933 )
934 except Exception as e: 934 except Exception as e:
954 help=_("reset cache without confirmation") 954 help=_("reset cache without confirmation")
955 ) 955 )
956 956
957 async def start(self): 957 async def start(self):
958 if not self.args.force: 958 if not self.args.force:
959 await self.host.confirmOrQuit( 959 await self.host.confirm_or_quit(
960 _( 960 _(
961 "Are you sure to reset cache? All nodes and items will be removed " 961 "Are you sure to reset cache? All nodes and items will be removed "
962 "from it, then it will be progressively refilled as if it were new. " 962 "from it, then it will be progressively refilled as if it were new. "
963 "This may be resources intensive." 963 "This may be resources intensive."
964 ), 964 ),
965 _("Pubsub cache reset has been cancelled.") 965 _("Pubsub cache reset has been cancelled.")
966 ) 966 )
967 try: 967 try:
968 await self.host.bridge.psCacheReset() 968 await self.host.bridge.ps_cache_reset()
969 except Exception as e: 969 except Exception as e:
970 self.disp(f"Internal error: {e}", error=True) 970 self.disp(f"Internal error: {e}", error=True)
971 self.host.quit(C.EXIT_INTERNAL_ERROR) 971 self.host.quit(C.EXIT_INTERNAL_ERROR)
972 else: 972 else:
973 self.host.quit(C.EXIT_OK) 973 self.host.quit(C.EXIT_OK)
1145 query["with_payload"] = True 1145 query["with_payload"] = True
1146 if self.args.keys: 1146 if self.args.keys:
1147 self.args.keys.append("item_payload") 1147 self.args.keys.append("item_payload")
1148 try: 1148 try:
1149 found_items = data_format.deserialise( 1149 found_items = data_format.deserialise(
1150 await self.host.bridge.psCacheSearch( 1150 await self.host.bridge.ps_cache_search(
1151 data_format.serialise(query) 1151 data_format.serialise(query)
1152 ), 1152 ),
1153 type_check=list, 1153 type_check=list,
1154 ) 1154 )
1155 except BridgeException as e: 1155 except BridgeException as e:
1247 default="", 1247 default="",
1248 help=_("id, URL of the item to update, keyword, or nothing for new item"), 1248 help=_("id, URL of the item to update, keyword, or nothing for new item"),
1249 ) 1249 )
1250 1250
1251 async def start(self): 1251 async def start(self):
1252 element, etree = xml_tools.etreeParse(self, sys.stdin) 1252 element, etree = xml_tools.etree_parse(self, sys.stdin)
1253 element = xml_tools.getPayload(self, element) 1253 element = xml_tools.get_payload(self, element)
1254 payload = etree.tostring(element, encoding="unicode") 1254 payload = etree.tostring(element, encoding="unicode")
1255 extra = {} 1255 extra = {}
1256 if self.args.encrypt: 1256 if self.args.encrypt:
1257 extra["encrypted"] = True 1257 extra["encrypted"] = True
1258 if self.args.encrypt_for: 1258 if self.args.encrypt_for:
1262 publish_options = NodeCreate.get_config_options(self.args) 1262 publish_options = NodeCreate.get_config_options(self.args)
1263 if publish_options: 1263 if publish_options:
1264 extra["publish_options"] = publish_options 1264 extra["publish_options"] = publish_options
1265 1265
1266 try: 1266 try:
1267 published_id = await self.host.bridge.psItemSend( 1267 published_id = await self.host.bridge.ps_item_send(
1268 self.args.service, 1268 self.args.service,
1269 self.args.node, 1269 self.args.node,
1270 payload, 1270 payload,
1271 self.args.item, 1271 self.args.item,
1272 data_format.serialise(extra), 1272 data_format.serialise(extra),
1316 extra = {} 1316 extra = {}
1317 if self.args.no_decrypt: 1317 if self.args.no_decrypt:
1318 extra["decrypt"] = False 1318 extra["decrypt"] = False
1319 try: 1319 try:
1320 ps_result = data_format.deserialise( 1320 ps_result = data_format.deserialise(
1321 await self.host.bridge.psItemsGet( 1321 await self.host.bridge.ps_items_get(
1322 self.args.service, 1322 self.args.service,
1323 self.args.node, 1323 self.args.node,
1324 self.args.max, 1324 self.args.max,
1325 self.args.items, 1325 self.args.items,
1326 self.args.sub_id, 1326 self.args.sub_id,
1327 self.getPubsubExtra(extra), 1327 self.get_pubsub_extra(extra),
1328 self.profile, 1328 self.profile,
1329 ) 1329 )
1330 ) 1330 )
1331 except BridgeException as e: 1331 except BridgeException as e:
1332 if e.condition == "item-not-found" or e.classname == "NotFound": 1332 if e.condition == "item-not-found" or e.classname == "NotFound":
1371 self.parser.error(_("You need to specify an item to delete")) 1371 self.parser.error(_("You need to specify an item to delete"))
1372 if not self.args.force: 1372 if not self.args.force:
1373 message = _("Are you sure to delete item {item_id} ?").format( 1373 message = _("Are you sure to delete item {item_id} ?").format(
1374 item_id=self.args.item 1374 item_id=self.args.item
1375 ) 1375 )
1376 await self.host.confirmOrQuit(message, _("item deletion cancelled")) 1376 await self.host.confirm_or_quit(message, _("item deletion cancelled"))
1377 try: 1377 try:
1378 await self.host.bridge.psItemRetract( 1378 await self.host.bridge.ps_item_retract(
1379 self.args.service, 1379 self.args.service,
1380 self.args.node, 1380 self.args.node,
1381 self.args.item, 1381 self.args.item,
1382 self.args.notify, 1382 self.args.notify,
1383 self.profile, 1383 self.profile,
1430 extra["encrypted"] = True 1430 extra["encrypted"] = True
1431 if self.args.encrypt_for: 1431 if self.args.encrypt_for:
1432 extra["encrypted_for"] = {"targets": self.args.encrypt_for} 1432 extra["encrypted_for"] = {"targets": self.args.encrypt_for}
1433 if self.args.sign: 1433 if self.args.sign:
1434 extra["signed"] = True 1434 extra["signed"] = True
1435 published_id = await self.host.bridge.psItemSend( 1435 published_id = await self.host.bridge.ps_item_send(
1436 self.pubsub_service, 1436 self.pubsub_service,
1437 self.pubsub_node, 1437 self.pubsub_node,
1438 content, 1438 content,
1439 self.pubsub_item or "", 1439 self.pubsub_item or "",
1440 data_format.serialise(extra), 1440 data_format.serialise(extra),
1443 if published_id: 1443 if published_id:
1444 self.disp("Item published at {pub_id}".format(pub_id=published_id)) 1444 self.disp("Item published at {pub_id}".format(pub_id=published_id))
1445 else: 1445 else:
1446 self.disp("Item published") 1446 self.disp("Item published")
1447 1447
1448 async def getItemData(self, service, node, item): 1448 async def get_item_data(self, service, node, item):
1449 try: 1449 try:
1450 from lxml import etree 1450 from lxml import etree
1451 except ImportError: 1451 except ImportError:
1452 self.disp( 1452 self.disp(
1453 "lxml module must be installed to use edit, please install it " 1453 "lxml module must be installed to use edit, please install it "
1455 error=True, 1455 error=True,
1456 ) 1456 )
1457 self.host.quit(1) 1457 self.host.quit(1)
1458 items = [item] if item else [] 1458 items = [item] if item else []
1459 ps_result = data_format.deserialise( 1459 ps_result = data_format.deserialise(
1460 await self.host.bridge.psItemsGet( 1460 await self.host.bridge.ps_items_get(
1461 service, node, 1, items, "", data_format.serialise({}), self.profile 1461 service, node, 1, items, "", data_format.serialise({}), self.profile
1462 ) 1462 )
1463 ) 1463 )
1464 item_raw = ps_result["items"][0] 1464 item_raw = ps_result["items"][0]
1465 parser = etree.XMLParser(remove_blank_text=True, recover=True) 1465 parser = etree.XMLParser(remove_blank_text=True, recover=True)
1477 self.pubsub_service, 1477 self.pubsub_service,
1478 self.pubsub_node, 1478 self.pubsub_node,
1479 self.pubsub_item, 1479 self.pubsub_item,
1480 content_file_path, 1480 content_file_path,
1481 content_file_obj, 1481 content_file_obj,
1482 ) = await self.getItemPath() 1482 ) = await self.get_item_path()
1483 await self.runEditor("pubsub_editor_args", content_file_path, content_file_obj) 1483 await self.run_editor("pubsub_editor_args", content_file_path, content_file_obj)
1484 self.host.quit() 1484 self.host.quit()
1485 1485
1486 1486
1487 class Rename(base.CommandBase): 1487 class Rename(base.CommandBase):
1488 def __init__(self, host): 1488 def __init__(self, host):
1498 def add_parser_options(self): 1498 def add_parser_options(self):
1499 self.parser.add_argument("new_id", help=_("new item id to use")) 1499 self.parser.add_argument("new_id", help=_("new item id to use"))
1500 1500
1501 async def start(self): 1501 async def start(self):
1502 try: 1502 try:
1503 await self.host.bridge.psItemRename( 1503 await self.host.bridge.ps_item_rename(
1504 self.args.service, 1504 self.args.service,
1505 self.args.node, 1505 self.args.node,
1506 self.args.item, 1506 self.args.item,
1507 self.args.new_id, 1507 self.args.new_id,
1508 self.profile, 1508 self.profile,
1535 ) 1535 )
1536 1536
1537 async def start(self): 1537 async def start(self):
1538 options = {} 1538 options = {}
1539 if self.args.public: 1539 if self.args.public:
1540 namespaces = await self.host.bridge.namespacesGet() 1540 namespaces = await self.host.bridge.namespaces_get()
1541 try: 1541 try:
1542 ns_pps = namespaces["pps"] 1542 ns_pps = namespaces["pps"]
1543 except KeyError: 1543 except KeyError:
1544 self.disp( 1544 self.disp(
1545 "Pubsub Public Subscription plugin is not loaded, can't use --public " 1545 "Pubsub Public Subscription plugin is not loaded, can't use --public "
1547 ) 1547 )
1548 self.host.quit(C.EXIT_MISSING_FEATURE) 1548 self.host.quit(C.EXIT_MISSING_FEATURE)
1549 else: 1549 else:
1550 options[f"{{{ns_pps}}}public"] = True 1550 options[f"{{{ns_pps}}}public"] = True
1551 try: 1551 try:
1552 sub_id = await self.host.bridge.psSubscribe( 1552 sub_id = await self.host.bridge.ps_subscribe(
1553 self.args.service, 1553 self.args.service,
1554 self.args.node, 1554 self.args.node,
1555 data_format.serialise(options), 1555 data_format.serialise(options),
1556 self.profile, 1556 self.profile,
1557 ) 1557 )
1582 def add_parser_options(self): 1582 def add_parser_options(self):
1583 pass 1583 pass
1584 1584
1585 async def start(self): 1585 async def start(self):
1586 try: 1586 try:
1587 await self.host.bridge.psUnsubscribe( 1587 await self.host.bridge.ps_unsubscribe(
1588 self.args.service, 1588 self.args.service,
1589 self.args.node, 1589 self.args.node,
1590 self.profile, 1590 self.profile,
1591 ) 1591 )
1592 except Exception as e: 1592 except Exception as e:
1615 help=_("get public subscriptions"), 1615 help=_("get public subscriptions"),
1616 ) 1616 )
1617 1617
1618 async def start(self): 1618 async def start(self):
1619 if self.args.public: 1619 if self.args.public:
1620 method = self.host.bridge.psPublicSubscriptionsGet 1620 method = self.host.bridge.ps_public_subscriptions_get
1621 else: 1621 else:
1622 method = self.host.bridge.psSubscriptionsGet 1622 method = self.host.bridge.ps_subscriptions_get
1623 try: 1623 try:
1624 subscriptions = data_format.deserialise( 1624 subscriptions = data_format.deserialise(
1625 await method( 1625 await method(
1626 self.args.service, 1626 self.args.service,
1627 self.args.node, 1627 self.args.node,
1651 def add_parser_options(self): 1651 def add_parser_options(self):
1652 pass 1652 pass
1653 1653
1654 async def start(self): 1654 async def start(self):
1655 try: 1655 try:
1656 affiliations = await self.host.bridge.psAffiliationsGet( 1656 affiliations = await self.host.bridge.ps_affiliations_get(
1657 self.args.service, 1657 self.args.service,
1658 self.args.node, 1658 self.args.node,
1659 self.profile, 1659 self.profile,
1660 ) 1660 )
1661 except Exception as e: 1661 except Exception as e:
1690 ) 1690 )
1691 1691
1692 async def start(self): 1692 async def start(self):
1693 service = self.args.service or await self.host.get_profile_jid() 1693 service = self.args.service or await self.host.get_profile_jid()
1694 if self.args.item: 1694 if self.args.item:
1695 anchor = uri.buildXMPPUri( 1695 anchor = uri.build_xmpp_uri(
1696 "pubsub", path=service, node=self.args.node, item=self.args.item 1696 "pubsub", path=service, node=self.args.node, item=self.args.item
1697 ) 1697 )
1698 else: 1698 else:
1699 anchor = uri.buildXMPPUri("pubsub", path=service, node=self.args.node) 1699 anchor = uri.build_xmpp_uri("pubsub", path=service, node=self.args.node)
1700 1700
1701 try: 1701 try:
1702 await self.host.bridge.referenceSend( 1702 await self.host.bridge.reference_send(
1703 self.args.recipient, 1703 self.args.recipient,
1704 anchor, 1704 anchor,
1705 self.args.type, 1705 self.args.type,
1706 "", 1706 "",
1707 self.profile, 1707 self.profile,
1897 choices=("print", "exec", "external"), 1897 choices=("print", "exec", "external"),
1898 help=_("action to do on found items (DEFAULT: print)"), 1898 help=_("action to do on found items (DEFAULT: print)"),
1899 ) 1899 )
1900 self.parser.add_argument("command", nargs=argparse.REMAINDER) 1900 self.parser.add_argument("command", nargs=argparse.REMAINDER)
1901 1901
1902 async def getItems(self, depth, service, node, items): 1902 async def get_items(self, depth, service, node, items):
1903 self.to_get += 1 1903 self.to_get += 1
1904 try: 1904 try:
1905 ps_result = data_format.deserialise( 1905 ps_result = data_format.deserialise(
1906 await self.host.bridge.psItemsGet( 1906 await self.host.bridge.ps_items_get(
1907 service, 1907 service,
1908 node, 1908 node,
1909 self.args.node_max, 1909 self.args.node_max,
1910 items, 1910 items,
1911 "", 1911 "",
1912 self.getPubsubExtra(), 1912 self.get_pubsub_extra(),
1913 self.profile, 1913 self.profile,
1914 ) 1914 )
1915 ) 1915 )
1916 except Exception as e: 1916 except Exception as e:
1917 self.disp( 1917 self.disp(
1920 ) 1920 )
1921 self.to_get -= 1 1921 self.to_get -= 1
1922 else: 1922 else:
1923 await self.search(ps_result, depth) 1923 await self.search(ps_result, depth)
1924 1924
1925 def _checkPubsubURL(self, match, found_nodes): 1925 def _check_pubsub_url(self, match, found_nodes):
1926 """check that the matched URL is an xmpp: one 1926 """check that the matched URL is an xmpp: one
1927 1927
1928 @param found_nodes(list[unicode]): found_nodes 1928 @param found_nodes(list[unicode]): found_nodes
1929 this list will be filled while xmpp: URIs are discovered 1929 this list will be filled while xmpp: URIs are discovered
1930 """ 1930 """
1931 url = match.group(0) 1931 url = match.group(0)
1932 if url.startswith("xmpp"): 1932 if url.startswith("xmpp"):
1933 try: 1933 try:
1934 url_data = uri.parseXMPPUri(url) 1934 url_data = uri.parse_xmpp_uri(url)
1935 except ValueError: 1935 except ValueError:
1936 return 1936 return
1937 if url_data["type"] == "pubsub": 1937 if url_data["type"] == "pubsub":
1938 found_node = {"service": url_data["path"], "node": url_data["node"]} 1938 found_node = {"service": url_data["path"], "node": url_data["node"]}
1939 if "item" in url_data: 1939 if "item" in url_data:
1940 found_node["item"] = url_data["item"] 1940 found_node["item"] = url_data["item"]
1941 found_nodes.append(found_node) 1941 found_nodes.append(found_node)
1942 1942
1943 async def getSubNodes(self, item, depth): 1943 async def get_sub_nodes(self, item, depth):
1944 """look for pubsub URIs in item, and getItems on the linked nodes""" 1944 """look for pubsub URIs in item, and get_items on the linked nodes"""
1945 found_nodes = [] 1945 found_nodes = []
1946 checkURI = partial(self._checkPubsubURL, found_nodes=found_nodes) 1946 checkURI = partial(self._check_pubsub_url, found_nodes=found_nodes)
1947 strings.RE_URL.sub(checkURI, item) 1947 strings.RE_URL.sub(checkURI, item)
1948 for data in found_nodes: 1948 for data in found_nodes:
1949 await self.getItems( 1949 await self.get_items(
1950 depth + 1, 1950 depth + 1,
1951 data["service"], 1951 data["service"],
1952 data["node"], 1952 data["node"],
1953 [data["item"]] if "item" in data else [], 1953 [data["item"]] if "item" in data else [],
1954 ) 1954 )
2059 if not keep: 2059 if not keep:
2060 return False, item 2060 return False, item
2061 2061
2062 return True, item 2062 return True, item
2063 2063
2064 async def doItemAction(self, item, metadata): 2064 async def do_item_action(self, item, metadata):
2065 """called when item has been kepts and the action need to be done 2065 """called when item has been kepts and the action need to be done
2066 2066
2067 @param item(unicode): accepted item 2067 @param item(unicode): accepted item
2068 """ 2068 """
2069 action = self.args.action 2069 action = self.args.action
2112 _("executed command failed with exit code {ret}").format(ret=ret), 2112 _("executed command failed with exit code {ret}").format(ret=ret),
2113 ) 2113 )
2114 ) 2114 )
2115 2115
2116 async def search(self, ps_result, depth): 2116 async def search(self, ps_result, depth):
2117 """callback of getItems 2117 """callback of get_items
2118 2118
2119 this method filters items, get sub nodes if needed, 2119 this method filters items, get sub nodes if needed,
2120 do the requested action, and exit the command when everything is done 2120 do the requested action, and exit the command when everything is done
2121 @param items_data(tuple): result of getItems 2121 @param items_data(tuple): result of get_items
2122 @param depth(int): current depth level 2122 @param depth(int): current depth level
2123 0 for first node, 1 for first children, and so on 2123 0 for first node, 1 for first children, and so on
2124 """ 2124 """
2125 for item in ps_result["items"]: 2125 for item in ps_result["items"]:
2126 if depth < self.args.max_depth: 2126 if depth < self.args.max_depth:
2127 await self.getSubNodes(item, depth) 2127 await self.get_sub_nodes(item, depth)
2128 keep, item = self.filter(item) 2128 keep, item = self.filter(item)
2129 if not keep: 2129 if not keep:
2130 continue 2130 continue
2131 await self.doItemAction(item, ps_result) 2131 await self.do_item_action(item, ps_result)
2132 2132
2133 #  we check if we got all getItems results 2133 #  we check if we got all get_items results
2134 self.to_get -= 1 2134 self.to_get -= 1
2135 if self.to_get == 0: 2135 if self.to_get == 0:
2136 # yes, we can quit 2136 # yes, we can quit
2137 self.host.quit() 2137 self.host.quit()
2138 assert self.to_get > 0 2138 assert self.to_get > 0
2158 if self.args.filters is None: 2158 if self.args.filters is None:
2159 self.args.filters = [] 2159 self.args.filters = []
2160 self.args.namespace = dict( 2160 self.args.namespace = dict(
2161 self.args.namespace + [("pubsub", "http://jabber.org/protocol/pubsub")] 2161 self.args.namespace + [("pubsub", "http://jabber.org/protocol/pubsub")]
2162 ) 2162 )
2163 await self.getItems(0, self.args.service, self.args.node, self.args.items) 2163 await self.get_items(0, self.args.service, self.args.node, self.args.items)
2164 2164
2165 2165
2166 class Transform(base.CommandBase): 2166 class Transform(base.CommandBase):
2167 def __init__(self, host): 2167 def __init__(self, host):
2168 base.CommandBase.__init__( 2168 base.CommandBase.__init__(
2206 "item as input. Output (full item XML) will be used as new one. " 2206 "item as input. Output (full item XML) will be used as new one. "
2207 'Return "DELETE" string to delete the item, and "SKIP" to ignore it' 2207 'Return "DELETE" string to delete the item, and "SKIP" to ignore it'
2208 ), 2208 ),
2209 ) 2209 )
2210 2210
2211 async def psItemsSendCb(self, item_ids, metadata): 2211 async def ps_items_send_cb(self, item_ids, metadata):
2212 if item_ids: 2212 if item_ids:
2213 self.disp( 2213 self.disp(
2214 _("items published with ids {item_ids}").format( 2214 _("items published with ids {item_ids}").format(
2215 item_ids=", ".join(item_ids) 2215 item_ids=", ".join(item_ids)
2216 ) 2216 )
2217 ) 2217 )
2218 else: 2218 else:
2219 self.disp(_("items published")) 2219 self.disp(_("items published"))
2220 if self.args.all: 2220 if self.args.all:
2221 return await self.handleNextPage(metadata) 2221 return await self.handle_next_page(metadata)
2222 else: 2222 else:
2223 self.host.quit() 2223 self.host.quit()
2224 2224
2225 async def handleNextPage(self, metadata): 2225 async def handle_next_page(self, metadata):
2226 """Retrieve new page through RSM or quit if we're in the last page 2226 """Retrieve new page through RSM or quit if we're in the last page
2227 2227
2228 use to handle --all option 2228 use to handle --all option
2229 @param metadata(dict): metadata as returned by psItemsGet 2229 @param metadata(dict): metadata as returned by ps_items_get
2230 """ 2230 """
2231 try: 2231 try:
2232 last = metadata["rsm"]["last"] 2232 last = metadata["rsm"]["last"]
2233 index = int(metadata["rsm"]["index"]) 2233 index = int(metadata["rsm"]["index"])
2234 count = int(metadata["rsm"]["count"]) 2234 count = int(metadata["rsm"]["count"])
2253 page_idx=int(index / self.args.rsm_max) + 1, 2253 page_idx=int(index / self.args.rsm_max) + 1,
2254 page_total=int(count / self.args.rsm_max), 2254 page_total=int(count / self.args.rsm_max),
2255 ) 2255 )
2256 ) 2256 )
2257 2257
2258 extra = self.getPubsubExtra() 2258 extra = self.get_pubsub_extra()
2259 extra["rsm_after"] = last 2259 extra["rsm_after"] = last
2260 try: 2260 try:
2261 ps_result = await data_format.deserialise( 2261 ps_result = await data_format.deserialise(
2262 self.host.bridge.psItemsGet( 2262 self.host.bridge.ps_items_get(
2263 self.args.service, 2263 self.args.service,
2264 self.args.node, 2264 self.args.node,
2265 self.args.rsm_max, 2265 self.args.rsm_max,
2266 self.args.items, 2266 self.args.items,
2267 "", 2267 "",
2271 ) 2271 )
2272 except Exception as e: 2272 except Exception as e:
2273 self.disp(f"can't retrieve items: {e}", error=True) 2273 self.disp(f"can't retrieve items: {e}", error=True)
2274 self.host.quit(C.EXIT_BRIDGE_ERRBACK) 2274 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
2275 else: 2275 else:
2276 await self.psItemsGetCb(ps_result) 2276 await self.ps_items_get_cb(ps_result)
2277 2277
2278 async def psItemsGetCb(self, ps_result): 2278 async def ps_items_get_cb(self, ps_result):
2279 encoding = "utf-8" 2279 encoding = "utf-8"
2280 new_items = [] 2280 new_items = []
2281 2281
2282 for item in ps_result["items"]: 2282 for item in ps_result["items"]:
2283 if self.check_duplicates: 2283 if self.check_duplicates:
2284 # this is used when we are not ordering by creation 2284 # this is used when we are not ordering by creation
2285 # to avoid infinite loop 2285 # to avoid infinite loop
2286 item_elt, __ = xml_tools.etreeParse(self, item) 2286 item_elt, __ = xml_tools.etree_parse(self, item)
2287 item_id = item_elt.get("id") 2287 item_id = item_elt.get("id")
2288 if item_id in self.items_ids: 2288 if item_id in self.items_ids:
2289 self.disp( 2289 self.disp(
2290 _( 2290 _(
2291 "Duplicate found on item {item_id}, we have probably handled " 2291 "Duplicate found on item {item_id}, we have probably handled "
2320 if cmd_std_err is not None: 2320 if cmd_std_err is not None:
2321 cmd_std_err = cmd_std_err.decode(encoding, errors="ignore") 2321 cmd_std_err = cmd_std_err.decode(encoding, errors="ignore")
2322 self.disp(cmd_std_err, error=True) 2322 self.disp(cmd_std_err, error=True)
2323 cmd_std_out = cmd_std_out.decode(encoding).strip() 2323 cmd_std_out = cmd_std_out.decode(encoding).strip()
2324 if cmd_std_out == "DELETE": 2324 if cmd_std_out == "DELETE":
2325 item_elt, __ = xml_tools.etreeParse(self, item) 2325 item_elt, __ = xml_tools.etree_parse(self, item)
2326 item_id = item_elt.get("id") 2326 item_id = item_elt.get("id")
2327 self.disp(_("Deleting item {item_id}").format(item_id=item_id)) 2327 self.disp(_("Deleting item {item_id}").format(item_id=item_id))
2328 if self.args.apply: 2328 if self.args.apply:
2329 try: 2329 try:
2330 await self.host.bridge.psItemRetract( 2330 await self.host.bridge.ps_item_retract(
2331 self.args.service, 2331 self.args.service,
2332 self.args.node, 2332 self.args.node,
2333 item_id, 2333 item_id,
2334 False, 2334 False,
2335 self.profile, 2335 self.profile,
2337 except Exception as e: 2337 except Exception as e:
2338 self.disp(f"can't delete item {item_id}: {e}", error=True) 2338 self.disp(f"can't delete item {item_id}: {e}", error=True)
2339 self.host.quit(C.EXIT_BRIDGE_ERRBACK) 2339 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
2340 continue 2340 continue
2341 elif cmd_std_out == "SKIP": 2341 elif cmd_std_out == "SKIP":
2342 item_elt, __ = xml_tools.etreeParse(self, item) 2342 item_elt, __ = xml_tools.etree_parse(self, item)
2343 item_id = item_elt.get("id") 2343 item_id = item_elt.get("id")
2344 self.disp(_("Skipping item {item_id}").format(item_id=item_id)) 2344 self.disp(_("Skipping item {item_id}").format(item_id=item_id))
2345 continue 2345 continue
2346 element, etree = xml_tools.etreeParse(self, cmd_std_out) 2346 element, etree = xml_tools.etree_parse(self, cmd_std_out)
2347 2347
2348 # at this point command has been run and we have a etree.Element object 2348 # at this point command has been run and we have a etree.Element object
2349 if element.tag not in ("item", "{http://jabber.org/protocol/pubsub}item"): 2349 if element.tag not in ("item", "{http://jabber.org/protocol/pubsub}item"):
2350 self.disp( 2350 self.disp(
2351 "your script must return a whole item, this is not:\n{xml}".format( 2351 "your script must return a whole item, this is not:\n{xml}".format(
2365 new_items.append(etree.tostring(element, encoding="unicode")) 2365 new_items.append(etree.tostring(element, encoding="unicode"))
2366 2366
2367 if not self.args.apply: 2367 if not self.args.apply:
2368 # on dry run we have nothing to wait for, we can quit 2368 # on dry run we have nothing to wait for, we can quit
2369 if self.args.all: 2369 if self.args.all:
2370 return await self.handleNextPage(ps_result) 2370 return await self.handle_next_page(ps_result)
2371 self.host.quit() 2371 self.host.quit()
2372 else: 2372 else:
2373 if self.args.admin: 2373 if self.args.admin:
2374 bridge_method = self.host.bridge.psAdminItemsSend 2374 bridge_method = self.host.bridge.ps_admin_items_send
2375 else: 2375 else:
2376 bridge_method = self.host.bridge.psItemsSend 2376 bridge_method = self.host.bridge.ps_items_send
2377 2377
2378 try: 2378 try:
2379 ps_items_send_result = await bridge_method( 2379 ps_items_send_result = await bridge_method(
2380 self.args.service, 2380 self.args.service,
2381 self.args.node, 2381 self.args.node,
2385 ) 2385 )
2386 except Exception as e: 2386 except Exception as e:
2387 self.disp(f"can't send item: {e}", error=True) 2387 self.disp(f"can't send item: {e}", error=True)
2388 self.host.quit(C.EXIT_BRIDGE_ERRBACK) 2388 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
2389 else: 2389 else:
2390 await self.psItemsSendCb(ps_items_send_result, metadata=ps_result) 2390 await self.ps_items_send_cb(ps_items_send_result, metadata=ps_result)
2391 2391
2392 async def start(self): 2392 async def start(self):
2393 if self.args.all and self.args.order_by != C.ORDER_BY_CREATION: 2393 if self.args.all and self.args.order_by != C.ORDER_BY_CREATION:
2394 self.check_duplicates = True 2394 self.check_duplicates = True
2395 self.items_ids = [] 2395 self.items_ids = []
2407 else: 2407 else:
2408 self.check_duplicates = False 2408 self.check_duplicates = False
2409 2409
2410 try: 2410 try:
2411 ps_result = data_format.deserialise( 2411 ps_result = data_format.deserialise(
2412 await self.host.bridge.psItemsGet( 2412 await self.host.bridge.ps_items_get(
2413 self.args.service, 2413 self.args.service,
2414 self.args.node, 2414 self.args.node,
2415 self.args.max, 2415 self.args.max,
2416 self.args.items, 2416 self.args.items,
2417 "", 2417 "",
2418 self.getPubsubExtra(), 2418 self.get_pubsub_extra(),
2419 self.profile, 2419 self.profile,
2420 ) 2420 )
2421 ) 2421 )
2422 except Exception as e: 2422 except Exception as e:
2423 self.disp(f"can't retrieve items: {e}", error=True) 2423 self.disp(f"can't retrieve items: {e}", error=True)
2424 self.host.quit(C.EXIT_BRIDGE_ERRBACK) 2424 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
2425 else: 2425 else:
2426 await self.psItemsGetCb(ps_result) 2426 await self.ps_items_get_cb(ps_result)
2427 2427
2428 2428
2429 class Uri(base.CommandBase): 2429 class Uri(base.CommandBase):
2430 def __init__(self, host): 2430 def __init__(self, host):
2431 base.CommandBase.__init__( 2431 base.CommandBase.__init__(
2455 value = getattr(self.args, key) 2455 value = getattr(self.args, key)
2456 if key == "service": 2456 if key == "service":
2457 key = "path" 2457 key = "path"
2458 if value: 2458 if value:
2459 uri_args[key] = value 2459 uri_args[key] = value
2460 self.disp(uri.buildXMPPUri("pubsub", **uri_args)) 2460 self.disp(uri.build_xmpp_uri("pubsub", **uri_args))
2461 self.host.quit() 2461 self.host.quit()
2462 2462
2463 async def start(self): 2463 async def start(self):
2464 if not self.args.service: 2464 if not self.args.service:
2465 try: 2465 try:
2466 jid_ = await self.host.bridge.asyncGetParamA( 2466 jid_ = await self.host.bridge.param_get_a_async(
2467 "JabberID", "Connection", profile_key=self.args.profile 2467 "JabberID", "Connection", profile_key=self.args.profile
2468 ) 2468 )
2469 except Exception as e: 2469 except Exception as e:
2470 self.disp(f"can't retrieve jid: {e}", error=True) 2470 self.disp(f"can't retrieve jid: {e}", error=True)
2471 self.host.quit(C.EXIT_BRIDGE_ERRBACK) 2471 self.host.quit(C.EXIT_BRIDGE_ERRBACK)
2498 ) 2498 )
2499 ) 2499 )
2500 2500
2501 async def start(self): 2501 async def start(self):
2502 try: 2502 try:
2503 attached_data, __ = await self.host.bridge.psAttachmentsGet( 2503 attached_data, __ = await self.host.bridge.ps_attachments_get(
2504 self.args.service, 2504 self.args.service,
2505 self.args.node, 2505 self.args.node,
2506 self.args.item, 2506 self.args.item,
2507 self.args.jids or [], 2507 self.args.jids or [],
2508 "", 2508 "",
2585 2585
2586 if not attachments_data["extra"]: 2586 if not attachments_data["extra"]:
2587 self.parser.error(_("At leat one attachment must be specified.")) 2587 self.parser.error(_("At leat one attachment must be specified."))
2588 2588
2589 try: 2589 try:
2590 await self.host.bridge.psAttachmentsSet( 2590 await self.host.bridge.ps_attachments_set(
2591 data_format.serialise(attachments_data), 2591 data_format.serialise(attachments_data),
2592 self.profile, 2592 self.profile,
2593 ) 2593 )
2594 except Exception as e: 2594 except Exception as e:
2595 self.disp(f"can't attach data to item: {e}", error=True) 2595 self.disp(f"can't attach data to item: {e}", error=True)
2633 # we set None to use profile's bare JID 2633 # we set None to use profile's bare JID
2634 "signature": {"signer": None} 2634 "signature": {"signer": None}
2635 } 2635 }
2636 } 2636 }
2637 try: 2637 try:
2638 await self.host.bridge.psAttachmentsSet( 2638 await self.host.bridge.ps_attachments_set(
2639 data_format.serialise(attachments_data), 2639 data_format.serialise(attachments_data),
2640 self.profile, 2640 self.profile,
2641 ) 2641 )
2642 except Exception as e: 2642 except Exception as e:
2643 self.disp(f"can't sign the item: {e}", error=True) 2643 self.disp(f"can't sign the item: {e}", error=True)
2665 help=_("signature data") 2665 help=_("signature data")
2666 ) 2666 )
2667 2667
2668 async def start(self): 2668 async def start(self):
2669 try: 2669 try:
2670 ret_s = await self.host.bridge.psSignatureCheck( 2670 ret_s = await self.host.bridge.ps_signature_check(
2671 self.args.service, 2671 self.args.service,
2672 self.args.node, 2672 self.args.node,
2673 self.args.item, 2673 self.args.item,
2674 self.args.signature, 2674 self.args.signature,
2675 self.profile, 2675 self.profile,
2716 "recipient", metavar="JID", help=_("entity who must get the shared secret") 2716 "recipient", metavar="JID", help=_("entity who must get the shared secret")
2717 ) 2717 )
2718 2718
2719 async def start(self): 2719 async def start(self):
2720 try: 2720 try:
2721 await self.host.bridge.psSecretShare( 2721 await self.host.bridge.ps_secret_share(
2722 self.args.recipient, 2722 self.args.recipient,
2723 self.args.service, 2723 self.args.service,
2724 self.args.node, 2724 self.args.node,
2725 self.args.secret_ids, 2725 self.args.secret_ids,
2726 self.profile, 2726 self.profile,
2755 ) 2755 )
2756 ) 2756 )
2757 2757
2758 async def start(self): 2758 async def start(self):
2759 try: 2759 try:
2760 await self.host.bridge.psSecretRevoke( 2760 await self.host.bridge.ps_secret_revoke(
2761 self.args.service, 2761 self.args.service,
2762 self.args.node, 2762 self.args.node,
2763 self.args.secret_id, 2763 self.args.secret_id,
2764 self.args.recipients, 2764 self.args.recipients,
2765 self.profile, 2765 self.profile,
2791 ) 2791 )
2792 ) 2792 )
2793 2793
2794 async def start(self): 2794 async def start(self):
2795 try: 2795 try:
2796 await self.host.bridge.psSecretRotate( 2796 await self.host.bridge.ps_secret_rotate(
2797 self.args.service, 2797 self.args.service,
2798 self.args.node, 2798 self.args.node,
2799 self.args.recipients, 2799 self.args.recipients,
2800 self.profile, 2800 self.profile,
2801 ) 2801 )
2822 def add_parser_options(self): 2822 def add_parser_options(self):
2823 pass 2823 pass
2824 2824
2825 async def start(self): 2825 async def start(self):
2826 try: 2826 try:
2827 secrets = data_format.deserialise(await self.host.bridge.psSecretsList( 2827 secrets = data_format.deserialise(await self.host.bridge.ps_secrets_list(
2828 self.args.service, 2828 self.args.service,
2829 self.args.node, 2829 self.args.node,
2830 self.profile, 2830 self.profile,
2831 ), type_check=list) 2831 ), type_check=list)
2832 except Exception as e: 2832 except Exception as e:
2883 "hook_arg", 2883 "hook_arg",
2884 help=_("argument of the hook (depend of the type)"), 2884 help=_("argument of the hook (depend of the type)"),
2885 ) 2885 )
2886 2886
2887 @staticmethod 2887 @staticmethod
2888 def checkArgs(self): 2888 def check_args(self):
2889 if self.args.type == "python_file": 2889 if self.args.type == "python_file":
2890 self.args.hook_arg = os.path.abspath(self.args.hook_arg) 2890 self.args.hook_arg = os.path.abspath(self.args.hook_arg)
2891 if not os.path.isfile(self.args.hook_arg): 2891 if not os.path.isfile(self.args.hook_arg):
2892 self.parser.error( 2892 self.parser.error(
2893 _("{path} is not a file").format(path=self.args.hook_arg) 2893 _("{path} is not a file").format(path=self.args.hook_arg)
2894 ) 2894 )
2895 2895
2896 async def start(self): 2896 async def start(self):
2897 self.checkArgs(self) 2897 self.check_args(self)
2898 try: 2898 try:
2899 await self.host.bridge.psHookAdd( 2899 await self.host.bridge.ps_hook_add(
2900 self.args.service, 2900 self.args.service,
2901 self.args.node, 2901 self.args.node,
2902 self.args.type, 2902 self.args.type,
2903 self.args.hook_arg, 2903 self.args.hook_arg,
2904 self.args.persistent, 2904 self.args.persistent,
2939 "argument of the hook to remove, empty to remove all (DEFAULT: remove all)" 2939 "argument of the hook to remove, empty to remove all (DEFAULT: remove all)"
2940 ), 2940 ),
2941 ) 2941 )
2942 2942
2943 async def start(self): 2943 async def start(self):
2944 HookCreate.checkArgs(self) 2944 HookCreate.check_args(self)
2945 try: 2945 try:
2946 nb_deleted = await self.host.bridge.psHookRemove( 2946 nb_deleted = await self.host.bridge.ps_hook_remove(
2947 self.args.service, 2947 self.args.service,
2948 self.args.node, 2948 self.args.node,
2949 self.args.type, 2949 self.args.type,
2950 self.args.hook_arg, 2950 self.args.hook_arg,
2951 self.profile, 2951 self.profile,
2973 def add_parser_options(self): 2973 def add_parser_options(self):
2974 pass 2974 pass
2975 2975
2976 async def start(self): 2976 async def start(self):
2977 try: 2977 try:
2978 data = await self.host.bridge.psHookList( 2978 data = await self.host.bridge.ps_hook_list(
2979 self.profile, 2979 self.profile,
2980 ) 2980 )
2981 except Exception as e: 2981 except Exception as e:
2982 self.disp(f"can't list hooks: {e}", error=True) 2982 self.disp(f"can't list hooks: {e}", error=True)
2983 self.host.quit(C.EXIT_BRIDGE_ERRBACK) 2983 self.host.quit(C.EXIT_BRIDGE_ERRBACK)