diff sat/plugins/plugin_comp_ap_gateway/pubsub_service.py @ 3865:59fbb66b2923

component AP gateway: handle XMPP attachments -> AP likes conversion: convert `noticed` attachments coming from XMPP to suitable `Like` activities. Virtual node is created in cache when necessary, and virtual items published to virtual JID mapping AP accounts are cached too. rel 370
author Goffi <goffi@goffi.org>
date Wed, 20 Jul 2022 17:53:12 +0200
parents 6329ee6b6df4
children 37d2c0282304
line wrap: on
line diff
--- a/sat/plugins/plugin_comp_ap_gateway/pubsub_service.py	Wed Jul 20 17:49:51 2022 +0200
+++ b/sat/plugins/plugin_comp_ap_gateway/pubsub_service.py	Wed Jul 20 17:53:12 2022 +0200
@@ -119,9 +119,14 @@
             )
 
         client = self.apg.client.getVirtualClient(requestor)
-        await self.apg.convertAndPostItems(
-            client, ap_account, service, nodeIdentifier, items
-        )
+        if self.apg._pa.isAttachmentNode(nodeIdentifier):
+            await self.apg.convertAndPostAttachments(
+                client, ap_account, service, nodeIdentifier, items, publisher=requestor
+            )
+        else:
+            await self.apg.convertAndPostItems(
+                client, ap_account, service, nodeIdentifier, items
+            )
 
     async def apFollowing2Elt(self, ap_item: dict) -> domish.Element:
         """Convert actor ID from following collection to XMPP item"""
@@ -291,6 +296,10 @@
             log.warning(f"Invalid AP account used by {requestor}: {ap_account!r}")
             return [], None
 
+        # cached_node may be pre-filled with some nodes (e.g. attachments nodes),
+        # otherwise it is filled when suitable
+        cached_node = None
+        client = self.apg.client
         kwargs = {}
 
         if node == self.apg._pps.subscriptions_node:
@@ -315,6 +324,15 @@
                 self.apg.client, ap_account, itemIdentifiers
             )
             return [item_elt], None
+        elif self.apg._pa.isAttachmentNode(node):
+            use_cache = True
+            # we check cache here because we emit an item-not-found error if the node is
+            # not in cache, as we are not dealing with real AP items
+            cached_node = await self.host.memory.storage.getPubsubNode(
+                client, service, node
+            )
+            if cached_node is None:
+                raise error.StanzaError("item-not-found")
         else:
             if not node.startswith(self.apg._m.namespace):
                 raise error.StanzaError(
@@ -326,11 +344,11 @@
             parser = self.apg.apItem2Elt
             use_cache = True
 
-        client = self.apg.client
         if use_cache:
-            cached_node = await self.host.memory.storage.getPubsubNode(
-                client, service, node
-            )
+            if cached_node is None:
+                cached_node = await self.host.memory.storage.getPubsubNode(
+                    client, service, node
+                )
             # TODO: check if node is synchronised
             if cached_node is not None:
                 # the node is cached, we return items from cache
@@ -467,7 +485,7 @@
         data = self.apg.createActivity("Follow", req_actor_id, recip_actor_id)
 
         resp = await self.apg.signAndPost(inbox, req_actor_id, data)
-        if resp.code >= 400:
+        if resp.code >= 300:
             text = await resp.text()
             raise error.StanzaError("service-unavailable", text=text)
         return pubsub.Subscription(nodeIdentifier, requestor, "subscribed")
@@ -488,7 +506,7 @@
         )
 
         resp = await self.apg.signAndPost(inbox, req_actor_id, data)
-        if resp.code >= 400:
+        if resp.code >= 300:
             text = await resp.text()
             raise error.StanzaError("service-unavailable", text=text)