component AP gateway: handle Like and Undo/Like activities:
rel 370
This commit is contained in:
parent
a945d3cb67
commit
9089a6494e
1 changed files with 246 additions and 60 deletions
|
|
@ -61,7 +61,7 @@ class PubsubAttachments:
|
|||
host.registerNamespace("pubsub-attachments", NS_PUBSUB_ATTACHMENTS)
|
||||
self.host = host
|
||||
self._p = host.plugins["XEP-0060"]
|
||||
self.handlers = {}
|
||||
self.handlers: Dict[Tuple[str, str], dict[str, Any]] = {}
|
||||
host.trigger.add("XEP-0277_send", self.onMBSend)
|
||||
self.registerAttachmentHandler(
|
||||
"noticed", NS_PUBSUB_ATTACHMENTS, self.noticedGet, self.noticedSet
|
||||
|
|
@ -270,46 +270,34 @@ class PubsubAttachments:
|
|||
) -> None:
|
||||
client = self.host.getClient(profile_key)
|
||||
attachments = data_format.deserialise(attachments_s) or {}
|
||||
return defer.ensureDeferred(self.setAttachments( client, attachments))
|
||||
return defer.ensureDeferred(self.setAttachments(client, attachments))
|
||||
|
||||
async def setAttachments(
|
||||
def applySetHandler(
|
||||
self,
|
||||
client: SatXMPPEntity,
|
||||
data: Dict[str, Any]
|
||||
) -> None:
|
||||
"""Set or update attachments
|
||||
attachments_data: dict,
|
||||
item_elt: Optional[domish.Element],
|
||||
handlers: Optional[List[Tuple[str, str]]] = None,
|
||||
from_jid: Optional[jid.JID] = None,
|
||||
) -> domish.Element:
|
||||
"""Apply all ``set`` callbacks to an attachments item
|
||||
|
||||
Former <attachments> element will be retrieved and updated. Individual
|
||||
attachments replace or update their elements individually, according to the
|
||||
"operation" key.
|
||||
|
||||
"operation" key may be "update" or "replace", and defaults to update, it is only
|
||||
used in attachments where "update" makes sense (e.g. it's used for "reactions"
|
||||
but not for "noticed").
|
||||
|
||||
@param data: microblog data data. Various keys (usually stored in
|
||||
data["extra"]) may be used depending on the attachments handlers
|
||||
registered. The keys "service", "node" and "id" MUST be set.
|
||||
@param attachments_data: data describing the attachments
|
||||
``extra`` key will be used, and created if not found
|
||||
@param from_jid: jid of the author of the attachments
|
||||
``client.jid.userhostJID()`` will be used if not specified
|
||||
@param item_elt: item containing an <attachments> element
|
||||
will be modified in place
|
||||
if None, a new element will be created
|
||||
@param handlers: list of (name, namespace) of handlers to use.
|
||||
if None, all registered handlers will be used.
|
||||
@return: updated item_elt if given, otherwise a new item_elt
|
||||
"""
|
||||
data.setdefault("extra", {})
|
||||
try:
|
||||
service = jid.JID(data["service"])
|
||||
node = data["node"]
|
||||
item = data["id"]
|
||||
except (KeyError, RuntimeError):
|
||||
raise ValueError(
|
||||
'data must have "service", "node" and "id" set'
|
||||
)
|
||||
attachment_node = self.getAttachmentNodeName(service, node, item)
|
||||
items, __ = await self._p.getItems(
|
||||
client, service, attachment_node, item_ids=[client.jid.userhost()]
|
||||
)
|
||||
if not items:
|
||||
# the item doesn't exist, we create a new one
|
||||
item_elt = pubsub.Item(client.jid.userhost())
|
||||
attachments_data.setdefault("extra", {})
|
||||
if item_elt is None:
|
||||
item_id = client.jid.userhost() if from_jid is None else from_jid.userhost()
|
||||
item_elt = pubsub.Item(item_id)
|
||||
item_elt.addElement((NS_PUBSUB_ATTACHMENTS, "attachments"))
|
||||
else:
|
||||
item_elt = items[0]
|
||||
|
||||
try:
|
||||
attachments_elt = next(
|
||||
|
|
@ -321,17 +309,78 @@ class PubsubAttachments:
|
|||
)
|
||||
attachments_elt = item_elt.addElement((NS_PUBSUB_ATTACHMENTS, "attachments"))
|
||||
|
||||
for (name, namespace), handler in self.handlers.items():
|
||||
if handlers is None:
|
||||
handlers = list(self.handlers.keys())
|
||||
|
||||
for name, namespace in handlers:
|
||||
try:
|
||||
handler = self.handlers[(name, namespace)]
|
||||
except KeyError:
|
||||
log.error(
|
||||
f"unregistered handler ({name!r}, {namespace!r}) is requested, "
|
||||
"ignoring"
|
||||
)
|
||||
continue
|
||||
try:
|
||||
former_elt = next(attachments_elt.elements(namespace, name))
|
||||
except StopIteration:
|
||||
former_elt = None
|
||||
new_elt = handler["set"](client, data, former_elt)
|
||||
new_elt = handler["set"](client, attachments_data, former_elt)
|
||||
if new_elt != former_elt:
|
||||
if former_elt is not None:
|
||||
attachments_elt.children.remove(former_elt)
|
||||
if new_elt is not None:
|
||||
attachments_elt.addChild(new_elt)
|
||||
return item_elt
|
||||
|
||||
async def setAttachments(
|
||||
self,
|
||||
client: SatXMPPEntity,
|
||||
attachments_data: Dict[str, Any]
|
||||
) -> None:
|
||||
"""Set or update attachments
|
||||
|
||||
Former <attachments> element will be retrieved and updated. Individual
|
||||
attachments replace or update their elements individually, according to the
|
||||
"operation" key.
|
||||
|
||||
"operation" key may be "update" or "replace", and defaults to update, it is only
|
||||
used in attachments where "update" makes sense (e.g. it's used for "reactions"
|
||||
but not for "noticed").
|
||||
|
||||
@param attachments_data: data describing attachments. Various keys (usually stored
|
||||
in attachments_data["extra"]) may be used depending on the attachments
|
||||
handlers registered. The keys "service", "node" and "id" MUST be set.
|
||||
``attachments_data`` is thought to be compatible with microblog data.
|
||||
|
||||
"""
|
||||
try:
|
||||
service = jid.JID(attachments_data["service"])
|
||||
node = attachments_data["node"]
|
||||
item = attachments_data["id"]
|
||||
except (KeyError, RuntimeError):
|
||||
raise ValueError(
|
||||
'data must have "service", "node" and "id" set'
|
||||
)
|
||||
attachment_node = self.getAttachmentNodeName(service, node, item)
|
||||
try:
|
||||
items, __ = await self._p.getItems(
|
||||
client, service, attachment_node, item_ids=[client.jid.userhost()]
|
||||
)
|
||||
except exceptions.NotFound:
|
||||
item_elt = None
|
||||
else:
|
||||
if not items:
|
||||
item_elt = None
|
||||
else:
|
||||
item_elt = items[0]
|
||||
|
||||
item_elt = self.applySetHandler(
|
||||
client,
|
||||
attachments_data,
|
||||
item_elt=item_elt,
|
||||
)
|
||||
|
||||
try:
|
||||
await self._p.sendItems(client, service, attachment_node, [item_elt])
|
||||
except error.StanzaError as e:
|
||||
|
|
|
|||
Loading…
Reference in a new issue