comparison sat/plugins/plugin_xep_0060.py @ 3519:02eec2a5b5f9

plugin XEP-0060, XEP-0277: new rename methods (`psItemRename`, `mbRename`): Those methods recreate an item to given new ID, and if successful, delete the former one.
author Goffi <goffi@goffi.org>
date Sat, 01 May 2021 18:37:57 +0200
parents fa796612adad
children edc79cefe968
comparison
equal deleted inserted replaced
3518:b258dce27d6d 3519:02eec2a5b5f9
15 15
16 # You should have received a copy of the GNU Affero General Public License 16 # You should have received a copy of the GNU Affero General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. 17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 18
19 19
20 from typing import Optional
20 from collections import namedtuple 21 from collections import namedtuple
21 import urllib.request, urllib.parse, urllib.error 22 import urllib.request, urllib.parse, urllib.error
22 from functools import reduce 23 from functools import reduce
23 from zope.interface import implementer 24 from zope.interface import implementer
24 from twisted.words.xish import domish 25 from twisted.words.xish import domish
32 from wokkel import rsm 33 from wokkel import rsm
33 from wokkel import mam 34 from wokkel import mam
34 from sat.core.i18n import _ 35 from sat.core.i18n import _
35 from sat.core.constants import Const as C 36 from sat.core.constants import Const as C
36 from sat.core.log import getLogger 37 from sat.core.log import getLogger
38 from sat.core.xmpp import SatXMPPEntity
37 from sat.core import exceptions 39 from sat.core import exceptions
38 from sat.tools import sat_defer 40 from sat.tools import sat_defer
39 from sat.tools import xml_tools 41 from sat.tools import xml_tools
40 from sat.tools.common import data_format 42 from sat.tools.common import data_format
41 43
228 "psItemsRetract", 230 "psItemsRetract",
229 ".plugin", 231 ".plugin",
230 in_sign="ssasbs", 232 in_sign="ssasbs",
231 out_sign="", 233 out_sign="",
232 method=self._retractItems, 234 method=self._retractItems,
235 async_=True,
236 )
237 host.bridge.addMethod(
238 "psItemRename",
239 ".plugin",
240 in_sign="sssss",
241 out_sign="",
242 method=self._renameItem,
233 async_=True, 243 async_=True,
234 ) 244 )
235 host.bridge.addMethod( 245 host.bridge.addMethod(
236 "psSubscribe", 246 "psSubscribe",
237 ".plugin", 247 ".plugin",
1029 ) 1039 )
1030 1040
1031 def _retractItems( 1041 def _retractItems(
1032 self, service_s, nodeIdentifier, itemIdentifiers, notify, profile_key 1042 self, service_s, nodeIdentifier, itemIdentifiers, notify, profile_key
1033 ): 1043 ):
1044 client = self.host.getClient(profile_key)
1034 return self.retractItems( 1045 return self.retractItems(
1046 client,
1035 jid.JID(service_s) if service_s else None, 1047 jid.JID(service_s) if service_s else None,
1036 nodeIdentifier, 1048 nodeIdentifier,
1037 itemIdentifiers, 1049 itemIdentifiers,
1038 notify, 1050 notify,
1039 profile_key,
1040 ) 1051 )
1041 1052
1042 def retractItems( 1053 def retractItems(
1043 self, 1054 self,
1055 client,
1044 service, 1056 service,
1045 nodeIdentifier, 1057 nodeIdentifier,
1046 itemIdentifiers, 1058 itemIdentifiers,
1047 notify=True, 1059 notify=True,
1060 ):
1061 return client.pubsub_client.retractItems(
1062 service, nodeIdentifier, itemIdentifiers, notify=True
1063 )
1064
1065 def _renameItem(
1066 self,
1067 service,
1068 node,
1069 item_id,
1070 new_id,
1048 profile_key=C.PROF_KEY_NONE, 1071 profile_key=C.PROF_KEY_NONE,
1049 ): 1072 ):
1050 client = self.host.getClient(profile_key) 1073 client = self.host.getClient(profile_key)
1051 return client.pubsub_client.retractItems( 1074 service = jid.JID(service) if service else None
1052 service, nodeIdentifier, itemIdentifiers, notify=True 1075 return defer.ensureDeferred(self.renameItem(
1053 ) 1076 client, service, node, item_id, new_id
1077 ))
1078
1079 async def renameItem(
1080 self,
1081 client: SatXMPPEntity,
1082 service: Optional[jid.JID],
1083 node: str,
1084 item_id: str,
1085 new_id: str
1086 ) -> None:
1087 """Rename an item by recreating it then deleting it
1088
1089 we have to recreate then delete because there is currently no rename operation
1090 with PubSub
1091 """
1092 if not item_id or not new_id:
1093 raise ValueError("item_id and new_id must not be empty")
1094 # retract must be done last, so if something goes wrong, the exception will stop
1095 # the workflow and no accidental delete should happen
1096 item_elt = (await self.getItems(client, service, node, item_ids=[item_id]))[0][0]
1097 await self.sendItem(client, service, node, item_elt.firstChildElement(), new_id)
1098 await self.retractItems(client, service, node, [item_id])
1054 1099
1055 def _subscribe(self, service, nodeIdentifier, options, profile_key=C.PROF_KEY_NONE): 1100 def _subscribe(self, service, nodeIdentifier, options, profile_key=C.PROF_KEY_NONE):
1056 client = self.host.getClient(profile_key) 1101 client = self.host.getClient(profile_key)
1057 service = None if not service else jid.JID(service) 1102 service = None if not service else jid.JID(service)
1058 d = self.subscribe(client, service, nodeIdentifier, options=options or None) 1103 d = self.subscribe(client, service, nodeIdentifier, options=options or None)