comparison sat/plugins/plugin_comp_ap_gateway/__init__.py @ 3842:943901372eba

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
author Goffi <goffi@goffi.org>
date Thu, 14 Jul 2022 12:55:30 +0200
parents 381340b9a9ee
children 17c757bd74bc
comparison
equal deleted inserted replaced
3841:b337d7da72e5 3842:943901372eba
346 raise ValueError("None can't be used with apGetObject is key is None") 346 raise ValueError("None can't be used with apGetObject is key is None")
347 return None 347 return None
348 elif isinstance(value, dict): 348 elif isinstance(value, dict):
349 return value 349 return value
350 elif isinstance(value, str): 350 elif isinstance(value, str):
351 return await self.apGet(value) 351 if self.isLocalURL(value):
352 return await self.apGetLocalObject(value)
353 else:
354 return await self.apGet(value)
352 else: 355 else:
353 raise NotImplementedError( 356 raise NotImplementedError(
354 "was expecting a string or a dict, got {type(value)}: {value!r}}" 357 "was expecting a string or a dict, got {type(value)}: {value!r}}"
358 )
359
360 async def apGetLocalObject(
361 self,
362 url: str
363 ) -> dict:
364 """Retrieve or generate local object
365
366 for now, only handle XMPP items to convert to AP
367 """
368 url_type, url_args = self.parseAPURL(url)
369 if url_type == TYPE_ITEM:
370 try:
371 account, item_id = url_args
372 except ValueError:
373 raise ValueError(f"invalid URL: {url}")
374 author_jid, node = await self.getJIDAndNode(account)
375 if node is None:
376 node = self._m.namespace
377 cached_node = await self.host.memory.storage.getPubsubNode(
378 self.client, author_jid, node
379 )
380 if not cached_node:
381 raise exceptions.NotFound
382 cached_items, __ = await self.host.memory.storage.getItems(
383 cached_node, item_ids=[item_id]
384 )
385 if not cached_items:
386 raise exceptions.NotFound(
387 f"item {item_id!r} is not found in cache"
388 )
389 mb_data = await self._m.item2mbdata(
390 self.client, cached_items[0].data, author_jid, node
391 )
392 ap_item = await self.mbdata2APitem(self.client, mb_data)
393 # the URL must return the object and not the activity
394 return ap_item["object"]
395 else:
396 raise NotImplementedError(
397 'only object from "item" URLs can be retrieved for now'
355 ) 398 )
356 399
357 async def apGetList( 400 async def apGetList(
358 self, 401 self,
359 data: dict, 402 data: dict,
372 """ 415 """
373 value = data.get(key) 416 value = data.get(key)
374 if value is None: 417 if value is None:
375 return None 418 return None
376 elif isinstance(value, str): 419 elif isinstance(value, str):
377 value = await self.apGet(value) 420 if self.isLocalURL(value):
421 value = await self.apGetLocalObject(value)
422 else:
423 value = await self.apGet(value)
378 if isinstance(value, dict): 424 if isinstance(value, dict):
379 return [value] 425 return [value]
380 if not isinstance(value, list): 426 if not isinstance(value, list):
381 raise ValueError(f"A list was expected, got {type(value)}: {value!r}") 427 raise ValueError(f"A list was expected, got {type(value)}: {value!r}")
382 if only_ids: 428 if only_ids:
678 724
679 @param url: URL to parse (schema is not mandatory) 725 @param url: URL to parse (schema is not mandatory)
680 @return: endpoint type and extra arguments 726 @return: endpoint type and extra arguments
681 """ 727 """
682 path = parse.urlparse(url).path.lstrip("/") 728 path = parse.urlparse(url).path.lstrip("/")
683 type_, *extra_args = path[len(self.ap_path):].lstrip("/").split("/", 1) 729 type_, *extra_args = path[len(self.ap_path):].lstrip("/").split("/")
684 return type_, [parse.unquote(a) for a in extra_args] 730 return type_, [parse.unquote(a) for a in extra_args]
685 731
686 def buildAPURL(self, type_:str , *args: str) -> str: 732 def buildAPURL(self, type_:str , *args: str) -> str:
687 """Build an AP endpoint URL 733 """Build an AP endpoint URL
688 734