changeset 3855:54305ebf5b94

component AP gateway: "repeat" to "Announce" conversion: when an XMPP blog post is marked as repeated, it is converted to an AP Announce activity rel 370
author Goffi <goffi@goffi.org>
date Thu, 14 Jul 2022 12:55:30 +0200
parents 8a2c46122a11
children bc7f9d0a404f
files sat/plugins/plugin_comp_ap_gateway/__init__.py
diffstat 1 files changed, 67 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/sat/plugins/plugin_comp_ap_gateway/__init__.py	Thu Jul 14 12:55:30 2022 +0200
+++ b/sat/plugins/plugin_comp_ap_gateway/__init__.py	Thu Jul 14 12:55:30 2022 +0200
@@ -1554,6 +1554,69 @@
             TYPE_ITEM, parent_ap_account, parent_item
         )
 
+    async def repeatedMB2APItem(
+        self,
+        mb_data: dict
+    ) -> dict:
+        """Convert repeated blog item to suitable AP Announce activity
+
+        @param mb_data: microblog metadata of an item repeating an other blog post
+        @return: Announce activity linking to the repeated item
+        """
+        repeated = mb_data["extra"]["repeated"]
+        repeater = jid.JID(repeated["by"])
+        repeater_account = await self.getAPAccountFromJidAndNode(
+            repeater,
+            None
+        )
+        repeater_id = self.buildAPURL(TYPE_ACTOR, repeater_account)
+        repeated_uri = repeated["uri"]
+
+        if not repeated_uri.startswith("xmpp:"):
+            log.warning(
+                "Only xmpp: URL are handled for repeated item at the moment, ignoring "
+                f"item {mb_data}"
+            )
+            raise NotImplementedError
+        parsed_url = uri.parseXMPPUri(repeated_uri)
+        if parsed_url["type"] != "pubsub":
+            log.warning(
+                "Only pubsub URL are handled for repeated item at the moment, ignoring "
+                f"item {mb_data}"
+            )
+            raise NotImplementedError
+        rep_service = jid.JID(parsed_url["path"])
+        rep_item = parsed_url["item"]
+        activity_id = self.buildAPURL("item", repeater.userhost(), mb_data["id"])
+
+        if rep_service.host == self.client.jid.userhost():
+            # it's an AP actor linked through this gateway
+            # in this case we can simply use the item ID
+            if not rep_item.startswith("https:"):
+                log.warning(
+                    f"Was expecting an HTTPS url as item ID and got {rep_item!r}\n"
+                    f"{mb_data}"
+                )
+            announced_uri = rep_item
+            repeated_account = self._e.unescape(rep_service.user)
+        else:
+            # the repeated item is an XMPP publication, we build the corresponding ID
+            rep_node = parsed_url["node"]
+            repeated_account = await self.getAPAccountFromJidAndNode(
+                rep_service, rep_node
+            )
+            announced_uri = self.buildAPURL("item", repeated_account, rep_item)
+
+        announce = self.createActivity(
+            "Announce", repeater_id, announced_uri, activity_id=activity_id
+        )
+        announce["to"] = [NS_AP_PUBLIC]
+        announce["cc"] = [
+            self.buildAPURL(TYPE_FOLLOWERS, repeater_account),
+            await self.getAPActorIdFromAccount(repeated_account)
+        ]
+        return announce
+
     async def mbdata2APitem(
         self,
         client: SatXMPPEntity,
@@ -1571,8 +1634,11 @@
             ``inReplyTo`` will also be set if suitable
             if False, no destinee will be set (i.e., no ``to`` or ``cc`` or public flag).
             This is usually used for direct messages.
-        @return: AP item
+        @return: Activity item
         """
+        extra = mb_data.get("extra", {})
+        if "repeated" in extra:
+            return await self.repeatedMB2APItem(mb_data)
         if not mb_data.get("id"):
             mb_data["id"] = shortuuid.uuid()
         if not mb_data.get("author_jid"):