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
This commit is contained in:
parent
b533b3e56c
commit
fe4dc35f5c
1 changed files with 49 additions and 3 deletions
|
|
@ -348,12 +348,55 @@ class APGateway:
|
|||
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 @@ class APGateway:
|
|||
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 @@ class APGateway:
|
|||
@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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue