# HG changeset patch # User Goffi # Date 1657796130 -7200 # Node ID 943901372eba70c7b0a65d135a34838923b9bee8 # Parent b337d7da72e5192dd507a7a270ecd76edbd7a416 component AP gateway: `apGetObject` and `apGetList` now work with local object: When a local item is linked, it is found from database instead of doing an HTTP request. rel 370 diff -r b337d7da72e5 -r 943901372eba sat/plugins/plugin_comp_ap_gateway/__init__.py --- a/sat/plugins/plugin_comp_ap_gateway/__init__.py Thu Jul 14 12:55:19 2022 +0200 +++ b/sat/plugins/plugin_comp_ap_gateway/__init__.py Thu Jul 14 12:55:30 2022 +0200 @@ -348,12 +348,55 @@ elif isinstance(value, dict): return value elif isinstance(value, str): - return await self.apGet(value) + if self.isLocalURL(value): + return await self.apGetLocalObject(value) + else: + return await self.apGet(value) else: raise NotImplementedError( "was expecting a string or a dict, got {type(value)}: {value!r}}" ) + async def apGetLocalObject( + self, + url: str + ) -> dict: + """Retrieve or generate local object + + for now, only handle XMPP items to convert to AP + """ + url_type, url_args = self.parseAPURL(url) + if url_type == TYPE_ITEM: + try: + account, item_id = url_args + except ValueError: + raise ValueError(f"invalid URL: {url}") + author_jid, node = await self.getJIDAndNode(account) + if node is None: + node = self._m.namespace + cached_node = await self.host.memory.storage.getPubsubNode( + self.client, author_jid, node + ) + if not cached_node: + raise exceptions.NotFound + cached_items, __ = await self.host.memory.storage.getItems( + cached_node, item_ids=[item_id] + ) + if not cached_items: + raise exceptions.NotFound( + f"item {item_id!r} is not found in cache" + ) + mb_data = await self._m.item2mbdata( + self.client, cached_items[0].data, author_jid, node + ) + ap_item = await self.mbdata2APitem(self.client, mb_data) + # the URL must return the object and not the activity + return ap_item["object"] + else: + raise NotImplementedError( + 'only object from "item" URLs can be retrieved for now' + ) + async def apGetList( self, data: dict, @@ -374,7 +417,10 @@ if value is None: return None elif isinstance(value, str): - value = await self.apGet(value) + if self.isLocalURL(value): + value = await self.apGetLocalObject(value) + else: + value = await self.apGet(value) if isinstance(value, dict): return [value] if not isinstance(value, list): @@ -680,7 +726,7 @@ @return: endpoint type and extra arguments """ path = parse.urlparse(url).path.lstrip("/") - type_, *extra_args = path[len(self.ap_path):].lstrip("/").split("/", 1) + type_, *extra_args = path[len(self.ap_path):].lstrip("/").split("/") return type_, [parse.unquote(a) for a in extra_args] def buildAPURL(self, type_:str , *args: str) -> str: