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.
This commit is contained in:
Goffi 2021-05-01 18:37:57 +02:00
commit 435027c1c9
2 changed files with 85 additions and 4 deletions

View file

@ -17,6 +17,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional
from collections import namedtuple
import urllib.request, urllib.parse, urllib.error
from functools import reduce
@ -34,6 +35,7 @@ from wokkel import mam
from sat.core.i18n import _
from sat.core.constants import Const as C
from sat.core.log import getLogger
from sat.core.xmpp import SatXMPPEntity
from sat.core import exceptions
from sat.tools import sat_defer
from sat.tools import xml_tools
@ -232,6 +234,14 @@ class XEP_0060(object):
method=self._retractItems,
async_=True,
)
host.bridge.addMethod(
"psItemRename",
".plugin",
in_sign="sssss",
out_sign="",
method=self._renameItem,
async_=True,
)
host.bridge.addMethod(
"psSubscribe",
".plugin",
@ -1031,27 +1041,62 @@ class XEP_0060(object):
def _retractItems(
self, service_s, nodeIdentifier, itemIdentifiers, notify, profile_key
):
client = self.host.getClient(profile_key)
return self.retractItems(
client,
jid.JID(service_s) if service_s else None,
nodeIdentifier,
itemIdentifiers,
notify,
profile_key,
)
def retractItems(
self,
client,
service,
nodeIdentifier,
itemIdentifiers,
notify=True,
profile_key=C.PROF_KEY_NONE,
):
client = self.host.getClient(profile_key)
return client.pubsub_client.retractItems(
service, nodeIdentifier, itemIdentifiers, notify=True
)
def _renameItem(
self,
service,
node,
item_id,
new_id,
profile_key=C.PROF_KEY_NONE,
):
client = self.host.getClient(profile_key)
service = jid.JID(service) if service else None
return defer.ensureDeferred(self.renameItem(
client, service, node, item_id, new_id
))
async def renameItem(
self,
client: SatXMPPEntity,
service: Optional[jid.JID],
node: str,
item_id: str,
new_id: str
) -> None:
"""Rename an item by recreating it then deleting it
we have to recreate then delete because there is currently no rename operation
with PubSub
"""
if not item_id or not new_id:
raise ValueError("item_id and new_id must not be empty")
# retract must be done last, so if something goes wrong, the exception will stop
# the workflow and no accidental delete should happen
item_elt = (await self.getItems(client, service, node, item_ids=[item_id]))[0][0]
await self.sendItem(client, service, node, item_elt.firstChildElement(), new_id)
await self.retractItems(client, service, node, [item_id])
def _subscribe(self, service, nodeIdentifier, options, profile_key=C.PROF_KEY_NONE):
client = self.host.getClient(profile_key)
service = None if not service else jid.JID(service)

View file

@ -123,6 +123,14 @@ class XEP_0277(object):
method=self._mbGet,
async_=True,
)
host.bridge.addMethod(
"mbRename",
".plugin",
in_sign="sssss",
out_sign="",
method=self._mbRename,
async_=True,
)
host.bridge.addMethod(
"mbSetAccess",
".plugin",
@ -813,7 +821,14 @@ class XEP_0277(object):
def friendlyId(self, data):
"""Generate a user friendly id from title or content"""
id_base = regex.urlFriendlyText(data.get('title') or data.get('content', ''))
# TODO: rich content should be converted to plain text
id_base = regex.urlFriendlyText(
data.get('title')
or data.get('title_rich')
or data.get('content')
or data.get('content_rich')
or ''
)
return f"{id_base}-{token_urlsafe(3)}"
def _mbSend(self, service, node, data, profile_key):
@ -954,6 +969,27 @@ class XEP_0277(object):
items_data, partial(self.item2mbdata, client, service=service, node=node))
defer.returnValue(mb_data)
def _mbRename(self, service, node, item_id, new_id, profile_key):
return defer.ensureDeferred(self.mbRename(
self.host.getClient(profile_key),
jid.JID(service) if service else None,
node or None,
item_id,
new_id
))
async def mbRename(
self,
client: SatXMPPEntity,
service: Optional[jid.JID],
node: Optional[str],
item_id: str,
new_id: str
) -> None:
if not node:
node = NS_MICROBLOG
await self._p.renameItem(client, service, node, item_id, new_id)
def parseCommentUrl(self, node_url):
"""Parse a XMPP URI