massive refactoring to switch from camelCase to snake_case:
historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a pre-PEP8 code, to use the same coding style as in Twisted. However, snake_case is more readable and it's better to follow PEP8 best practices, so it has been decided to move on full snake_case. Because Libervia has a huge codebase, this ended with a ugly mix of camelCase and snake_case. To fix that, this patch does a big refactoring by renaming every function and method (including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case. This is a massive change, and may result in some bugs.
This commit is contained in:
parent
d50412c7f7
commit
6a6f15707a
5 changed files with 9945 additions and 9945 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -38,7 +38,7 @@ class APAdHocService:
|
|||
self._c = self.host.plugins["XEP-0050"]
|
||||
|
||||
def init(self, client: SatXMPPEntity) -> None:
|
||||
self._c.addAdHocCommand(
|
||||
self._c.add_ad_hoc_command(
|
||||
client,
|
||||
self.xmpp_jid_node_2_ap_actor,
|
||||
"Convert XMPP JID/Node to AP actor",
|
||||
|
|
@ -82,7 +82,7 @@ class APAdHocService:
|
|||
else:
|
||||
xmpp_jid = jid.JID(command_form["jid"])
|
||||
xmpp_node = command_form.get("node")
|
||||
actor = await self.apg.getAPAccountFromJidAndNode(xmpp_jid, xmpp_node)
|
||||
actor = await self.apg.get_ap_account_from_jid_and_node(xmpp_jid, xmpp_node)
|
||||
note = (self._c.NOTE.INFO, actor)
|
||||
status = self._c.STATUS.COMPLETED
|
||||
payload = None
|
||||
|
|
|
|||
|
|
@ -113,12 +113,12 @@ class APEvents:
|
|||
"""
|
||||
if not event_data.get("id"):
|
||||
event_data["id"] = shortuuid.uuid()
|
||||
ap_account = await self.apg.getAPAccountFromJidAndNode(
|
||||
ap_account = await self.apg.get_ap_account_from_jid_and_node(
|
||||
author_jid,
|
||||
self._events.namespace
|
||||
)
|
||||
url_actor = self.apg.buildAPURL(TYPE_ACTOR, ap_account)
|
||||
url_item = self.apg.buildAPURL(TYPE_ITEM, ap_account, event_data["id"])
|
||||
url_actor = self.apg.build_apurl(TYPE_ACTOR, ap_account)
|
||||
url_item = self.apg.build_apurl(TYPE_ITEM, ap_account, event_data["id"])
|
||||
ap_object = {
|
||||
"actor": url_actor,
|
||||
"attributedTo": url_actor,
|
||||
|
|
@ -246,7 +246,7 @@ class APEvents:
|
|||
"""
|
||||
is_activity = self.apg.is_activity(ap_item)
|
||||
if is_activity:
|
||||
ap_object = await self.apg.apGetObject(ap_item, "object")
|
||||
ap_object = await self.apg.ap_get_object(ap_item, "object")
|
||||
if not ap_object:
|
||||
log.warning(f'No "object" found in AP item {ap_item!r}')
|
||||
raise exceptions.DataError
|
||||
|
|
@ -257,7 +257,7 @@ class APEvents:
|
|||
if "_repeated" in ap_item:
|
||||
# if the event is repeated, we use the original one ID
|
||||
repeated_uri = ap_item["_repeated"]["uri"]
|
||||
parsed_uri = uri.parseXMPPUri(repeated_uri)
|
||||
parsed_uri = uri.parse_xmpp_uri(repeated_uri)
|
||||
object_id = parsed_uri["item"]
|
||||
else:
|
||||
object_id = ap_object.get("id")
|
||||
|
|
@ -268,10 +268,10 @@ class APEvents:
|
|||
raise exceptions.DataError("AP Object is not an event")
|
||||
|
||||
# author
|
||||
actor = await self.apg.apGetSenderActor(ap_object)
|
||||
actor = await self.apg.ap_get_sender_actor(ap_object)
|
||||
|
||||
account = await self.apg.getAPAccountFromId(actor)
|
||||
author_jid = self.apg.getLocalJIDFromAccount(account).full()
|
||||
account = await self.apg.get_ap_account_from_id(actor)
|
||||
author_jid = self.apg.get_local_jid_from_account(account).full()
|
||||
|
||||
# name, start, end
|
||||
event_data = {
|
||||
|
|
@ -370,7 +370,7 @@ class APEvents:
|
|||
# comments
|
||||
|
||||
if ap_object.get("commentsEnabled"):
|
||||
__, comments_node = await self.apg.getCommentsNodes(object_id, None)
|
||||
__, comments_node = await self.apg.get_comments_nodes(object_id, None)
|
||||
event_data["comments"] = {
|
||||
"service": author_jid,
|
||||
"node": comments_node,
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
self._seen_digest = deque(maxlen=50)
|
||||
super().__init__()
|
||||
|
||||
def responseCode(
|
||||
def response_code(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
http_code: int,
|
||||
|
|
@ -77,17 +77,17 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
log.warning(msg)
|
||||
request.setResponseCode(http_code, None if msg is None else msg.encode())
|
||||
|
||||
def _onRequestError(self, failure_: failure.Failure, request: "HTTPRequest") -> None:
|
||||
def _on_request_error(self, failure_: failure.Failure, request: "HTTPRequest") -> None:
|
||||
exc = failure_.value
|
||||
if isinstance(exc, exceptions.NotFound):
|
||||
self.responseCode(
|
||||
self.response_code(
|
||||
request,
|
||||
http.NOT_FOUND,
|
||||
str(exc)
|
||||
)
|
||||
else:
|
||||
log.exception(f"Internal error: {failure_.value}")
|
||||
self.responseCode(
|
||||
self.response_code(
|
||||
request,
|
||||
http.INTERNAL_SERVER_ERROR,
|
||||
f"internal error: {failure_.value}"
|
||||
|
|
@ -107,7 +107,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
http.BAD_REQUEST, "Bad Request" , "Invalid webfinger resource"
|
||||
).render(request)
|
||||
|
||||
actor_url = self.apg.buildAPURL(TYPE_ACTOR, account)
|
||||
actor_url = self.apg.build_apurl(TYPE_ACTOR, account)
|
||||
|
||||
resp = {
|
||||
"aliases": [actor_url],
|
||||
|
|
@ -124,7 +124,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
request.write(json.dumps(resp).encode())
|
||||
request.finish()
|
||||
|
||||
async def handleUndoActivity(
|
||||
async def handle_undo_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -136,7 +136,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
) -> None:
|
||||
if node is None:
|
||||
node = self.apg._m.namespace
|
||||
client = await self.apg.getVirtualClient(signing_actor)
|
||||
client = await self.apg.get_virtual_client(signing_actor)
|
||||
object_ = data.get("object")
|
||||
if isinstance(object_, str):
|
||||
# we check first if it's not a cached object
|
||||
|
|
@ -149,10 +149,10 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
# because we'll undo the activity, we can remove it from cache
|
||||
await self.apg.client._ap_storage.remove(ap_cache_key)
|
||||
else:
|
||||
objects = await self.apg.apGetList(data, "object")
|
||||
objects = await self.apg.ap_get_list(data, "object")
|
||||
for obj in objects:
|
||||
type_ = obj.get("type")
|
||||
actor = await self.apg.apGetSenderActor(obj)
|
||||
actor = await self.apg.ap_get_sender_actor(obj)
|
||||
if actor != signing_actor:
|
||||
log.warning(f"ignoring object not attributed to signing actor: {data}")
|
||||
continue
|
||||
|
|
@ -163,7 +163,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
except KeyError:
|
||||
log.warning(f'ignoring invalid object, missing "object" key: {data}')
|
||||
continue
|
||||
if not self.apg.isLocalURL(target_account):
|
||||
if not self.apg.is_local_url(target_account):
|
||||
log.warning(f"ignoring unfollow request to non local actor: {data}")
|
||||
continue
|
||||
await self.apg._p.unsubscribe(
|
||||
|
|
@ -175,17 +175,17 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
elif type_ == "Announce":
|
||||
# we can use directly the Announce object, as only the "id" field is
|
||||
# needed
|
||||
await self.apg.newAPDeleteItem(client, None, node, obj)
|
||||
await self.apg.new_ap_delete_item(client, None, node, obj)
|
||||
elif type_ == TYPE_LIKE:
|
||||
await self.handleAttachmentItem(client, obj, {"noticed": False})
|
||||
await self.handle_attachment_item(client, obj, {"noticed": False})
|
||||
elif type_ == TYPE_REACTION:
|
||||
await self.handleAttachmentItem(client, obj, {
|
||||
await self.handle_attachment_item(client, obj, {
|
||||
"reactions": {"operation": "update", "remove": [obj["content"]]}
|
||||
})
|
||||
else:
|
||||
log.warning(f"Unmanaged undo type: {type_!r}")
|
||||
|
||||
async def handleFollowActivity(
|
||||
async def handle_follow_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -197,14 +197,14 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
) -> None:
|
||||
if node is None:
|
||||
node = self.apg._m.namespace
|
||||
client = await self.apg.getVirtualClient(signing_actor)
|
||||
client = await self.apg.get_virtual_client(signing_actor)
|
||||
try:
|
||||
subscription = await self.apg._p.subscribe(
|
||||
client,
|
||||
account_jid,
|
||||
node,
|
||||
# subscriptions from AP are always public
|
||||
options=self.apg._pps.setPublicOpt()
|
||||
options=self.apg._pps.set_public_opt()
|
||||
)
|
||||
except pubsub.SubscriptionPending:
|
||||
log.info(f"subscription to node {node!r} of {account_jid} is pending")
|
||||
|
|
@ -213,15 +213,15 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
if subscription.state != "subscribed":
|
||||
# other states should raise an Exception
|
||||
raise exceptions.InternalError('"subscribed" state was expected')
|
||||
inbox = await self.apg.getAPInboxFromId(signing_actor, use_shared=False)
|
||||
actor_id = self.apg.buildAPURL(TYPE_ACTOR, ap_account)
|
||||
inbox = await self.apg.get_ap_inbox_from_id(signing_actor, use_shared=False)
|
||||
actor_id = self.apg.build_apurl(TYPE_ACTOR, ap_account)
|
||||
accept_data = self.apg.create_activity(
|
||||
"Accept", actor_id, object_=data
|
||||
)
|
||||
await self.apg.signAndPost(inbox, actor_id, accept_data)
|
||||
await self.apg.sign_and_post(inbox, actor_id, accept_data)
|
||||
await self.apg._c.synchronise(client, account_jid, node, resync=False)
|
||||
|
||||
async def handleAcceptActivity(
|
||||
async def handle_accept_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -233,12 +233,12 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
) -> None:
|
||||
if node is None:
|
||||
node = self.apg._m.namespace
|
||||
client = await self.apg.getVirtualClient(signing_actor)
|
||||
objects = await self.apg.apGetList(data, "object")
|
||||
client = await self.apg.get_virtual_client(signing_actor)
|
||||
objects = await self.apg.ap_get_list(data, "object")
|
||||
for obj in objects:
|
||||
type_ = obj.get("type")
|
||||
if type_ == "Follow":
|
||||
follow_node = await self.apg.host.memory.storage.getPubsubNode(
|
||||
follow_node = await self.apg.host.memory.storage.get_pubsub_node(
|
||||
client, client.jid, node, with_subscriptions=True
|
||||
)
|
||||
if follow_node is None:
|
||||
|
|
@ -270,7 +270,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
else:
|
||||
log.warning(f"Unmanaged accept type: {type_!r}")
|
||||
|
||||
async def handleDeleteActivity(
|
||||
async def handle_delete_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -282,12 +282,12 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
):
|
||||
if node is None:
|
||||
node = self.apg._m.namespace
|
||||
client = await self.apg.getVirtualClient(signing_actor)
|
||||
objects = await self.apg.apGetList(data, "object")
|
||||
client = await self.apg.get_virtual_client(signing_actor)
|
||||
objects = await self.apg.ap_get_list(data, "object")
|
||||
for obj in objects:
|
||||
await self.apg.newAPDeleteItem(client, account_jid, node, obj)
|
||||
await self.apg.new_ap_delete_item(client, account_jid, node, obj)
|
||||
|
||||
async def handleNewAPItems(
|
||||
async def handle_new_ap_items(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -298,7 +298,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
):
|
||||
"""Helper method to handle workflow for new AP items
|
||||
|
||||
accept globally the same parameter as for handleCreateActivity
|
||||
accept globally the same parameter as for handle_create_activity
|
||||
@param repeated: if True, the item is an item republished from somewhere else
|
||||
"""
|
||||
if "_repeated" in data:
|
||||
|
|
@ -307,25 +307,25 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
f"happen. Ignoring object from {signing_actor}\n{data}"
|
||||
)
|
||||
raise exceptions.DataError("unexpected field in item")
|
||||
client = await self.apg.getVirtualClient(signing_actor)
|
||||
objects = await self.apg.apGetList(data, "object")
|
||||
client = await self.apg.get_virtual_client(signing_actor)
|
||||
objects = await self.apg.ap_get_list(data, "object")
|
||||
for obj in objects:
|
||||
if node is None:
|
||||
if obj.get("type") == TYPE_EVENT:
|
||||
node = self.apg._events.namespace
|
||||
else:
|
||||
node = self.apg._m.namespace
|
||||
sender = await self.apg.apGetSenderActor(obj)
|
||||
sender = await self.apg.ap_get_sender_actor(obj)
|
||||
if repeated:
|
||||
# we don't check sender when item is repeated, as it should be different
|
||||
# from post author in this case
|
||||
sender_jid = await self.apg.getJIDFromId(sender)
|
||||
repeater_jid = await self.apg.getJIDFromId(signing_actor)
|
||||
sender_jid = await self.apg.get_jid_from_id(sender)
|
||||
repeater_jid = await self.apg.get_jid_from_id(signing_actor)
|
||||
repeated_item_id = obj["id"]
|
||||
if self.apg.isLocalURL(repeated_item_id):
|
||||
if self.apg.is_local_url(repeated_item_id):
|
||||
# the repeated object is from XMPP, we need to parse the URL to find
|
||||
# the right ID
|
||||
url_type, url_args = self.apg.parseAPURL(repeated_item_id)
|
||||
url_type, url_args = self.apg.parse_apurl(repeated_item_id)
|
||||
if url_type != "item":
|
||||
raise exceptions.DataError(
|
||||
"local URI is not an item: {repeated_id}"
|
||||
|
|
@ -339,7 +339,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
"local URI is invalid: {repeated_id}"
|
||||
)
|
||||
else:
|
||||
url_jid, url_node = await self.apg.getJIDAndNode(url_account)
|
||||
url_jid, url_node = await self.apg.get_jid_and_node(url_account)
|
||||
if ((url_jid != sender_jid
|
||||
or url_node and url_node != self.apg._m.namespace)):
|
||||
raise exceptions.DataError(
|
||||
|
|
@ -352,7 +352,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
obj["_repeated"] = {
|
||||
"by": repeater_jid.full(),
|
||||
"at": data.get("published"),
|
||||
"uri": uri.buildXMPPUri(
|
||||
"uri": uri.build_xmpp_uri(
|
||||
"pubsub",
|
||||
path=sender_jid.full(),
|
||||
node=self.apg._m.namespace,
|
||||
|
|
@ -369,9 +369,9 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
)
|
||||
continue
|
||||
|
||||
await self.apg.newAPItem(client, account_jid, node, obj)
|
||||
await self.apg.new_ap_item(client, account_jid, node, obj)
|
||||
|
||||
async def handleCreateActivity(
|
||||
async def handle_create_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -381,9 +381,9 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
ap_url: str,
|
||||
signing_actor: str
|
||||
):
|
||||
await self.handleNewAPItems(request, data, account_jid, node, signing_actor)
|
||||
await self.handle_new_ap_items(request, data, account_jid, node, signing_actor)
|
||||
|
||||
async def handleUpdateActivity(
|
||||
async def handle_update_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -395,9 +395,9 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
):
|
||||
# Update is the same as create: the item ID stays the same, thus the item will be
|
||||
# overwritten
|
||||
await self.handleNewAPItems(request, data, account_jid, node, signing_actor)
|
||||
await self.handle_new_ap_items(request, data, account_jid, node, signing_actor)
|
||||
|
||||
async def handleAnnounceActivity(
|
||||
async def handle_announce_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -408,7 +408,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
signing_actor: str
|
||||
):
|
||||
# we create a new item
|
||||
await self.handleNewAPItems(
|
||||
await self.handle_new_ap_items(
|
||||
request,
|
||||
data,
|
||||
account_jid,
|
||||
|
|
@ -417,7 +417,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
repeated=True
|
||||
)
|
||||
|
||||
async def handleAttachmentItem(
|
||||
async def handle_attachment_item(
|
||||
self,
|
||||
client: SatXMPPEntity,
|
||||
data: dict,
|
||||
|
|
@ -447,10 +447,10 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
await client._ap_storage.aset(f"{ST_AP_CACHE}{data['id']}", data)
|
||||
|
||||
for target_id in target_ids:
|
||||
if not self.apg.isLocalURL(target_id):
|
||||
if not self.apg.is_local_url(target_id):
|
||||
log.debug(f"ignoring non local target ID: {target_id}")
|
||||
continue
|
||||
url_type, url_args = self.apg.parseAPURL(target_id)
|
||||
url_type, url_args = self.apg.parse_apurl(target_id)
|
||||
if url_type != TYPE_ITEM:
|
||||
log.warning(f"unexpected local URL for attachment on item {target_id}")
|
||||
continue
|
||||
|
|
@ -458,20 +458,20 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
account, item_id = url_args
|
||||
except ValueError:
|
||||
raise ValueError(f"invalid URL: {target_id}")
|
||||
author_jid, item_node = await self.apg.getJIDAndNode(account)
|
||||
author_jid, item_node = await self.apg.get_jid_and_node(account)
|
||||
if item_node is None:
|
||||
item_node = self.apg._m.namespace
|
||||
attachment_node = self.apg._pa.getAttachmentNodeName(
|
||||
attachment_node = self.apg._pa.get_attachment_node_name(
|
||||
author_jid, item_node, item_id
|
||||
)
|
||||
cached_node = await self.apg.host.memory.storage.getPubsubNode(
|
||||
cached_node = await self.apg.host.memory.storage.get_pubsub_node(
|
||||
client,
|
||||
author_jid,
|
||||
attachment_node,
|
||||
with_subscriptions=True,
|
||||
create=True
|
||||
)
|
||||
found_items, __ = await self.apg.host.memory.storage.getItems(
|
||||
found_items, __ = await self.apg.host.memory.storage.get_items(
|
||||
cached_node, item_ids=[client.jid.userhost()]
|
||||
)
|
||||
if not found_items:
|
||||
|
|
@ -487,16 +487,16 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
None
|
||||
)
|
||||
# we reparse the element, as there can be other attachments
|
||||
attachments_data = self.apg._pa.items2attachmentData(client, [item_elt])
|
||||
attachments_data = self.apg._pa.items_2_attachment_data(client, [item_elt])
|
||||
# and we update the cache
|
||||
await self.apg.host.memory.storage.cachePubsubItems(
|
||||
await self.apg.host.memory.storage.cache_pubsub_items(
|
||||
client,
|
||||
cached_node,
|
||||
[item_elt],
|
||||
attachments_data or [{}]
|
||||
)
|
||||
|
||||
if self.apg.isVirtualJID(author_jid):
|
||||
if self.apg.is_virtual_jid(author_jid):
|
||||
# the attachment is on t a virtual pubsub service (linking to an AP item),
|
||||
# we notify all subscribers
|
||||
for subscription in cached_node.subscriptions:
|
||||
|
|
@ -509,11 +509,11 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
)
|
||||
else:
|
||||
# the attachment is on an XMPP item, we publish it to the attachment node
|
||||
await self.apg._p.sendItems(
|
||||
await self.apg._p.send_items(
|
||||
client, author_jid, attachment_node, [item_elt]
|
||||
)
|
||||
|
||||
async def handleLikeActivity(
|
||||
async def handle_like_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -523,10 +523,10 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
ap_url: str,
|
||||
signing_actor: str
|
||||
) -> None:
|
||||
client = await self.apg.getVirtualClient(signing_actor)
|
||||
await self.handleAttachmentItem(client, data, {"noticed": True})
|
||||
client = await self.apg.get_virtual_client(signing_actor)
|
||||
await self.handle_attachment_item(client, data, {"noticed": True})
|
||||
|
||||
async def handleEmojireactActivity(
|
||||
async def handle_emojireact_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -536,12 +536,12 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
ap_url: str,
|
||||
signing_actor: str
|
||||
) -> None:
|
||||
client = await self.apg.getVirtualClient(signing_actor)
|
||||
await self.handleAttachmentItem(client, data, {
|
||||
client = await self.apg.get_virtual_client(signing_actor)
|
||||
await self.handle_attachment_item(client, data, {
|
||||
"reactions": {"operation": "update", "add": [data["content"]]}
|
||||
})
|
||||
|
||||
async def handleJoinActivity(
|
||||
async def handle_join_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -551,10 +551,10 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
ap_url: str,
|
||||
signing_actor: str
|
||||
) -> None:
|
||||
client = await self.apg.getVirtualClient(signing_actor)
|
||||
await self.handleAttachmentItem(client, data, {"rsvp": {"attending": "yes"}})
|
||||
client = await self.apg.get_virtual_client(signing_actor)
|
||||
await self.handle_attachment_item(client, data, {"rsvp": {"attending": "yes"}})
|
||||
|
||||
async def handleLeaveActivity(
|
||||
async def handle_leave_activity(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: dict,
|
||||
|
|
@ -564,10 +564,10 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
ap_url: str,
|
||||
signing_actor: str
|
||||
) -> None:
|
||||
client = await self.apg.getVirtualClient(signing_actor)
|
||||
await self.handleAttachmentItem(client, data, {"rsvp": {"attending": "no"}})
|
||||
client = await self.apg.get_virtual_client(signing_actor)
|
||||
await self.handle_attachment_item(client, data, {"rsvp": {"attending": "no"}})
|
||||
|
||||
async def APActorRequest(
|
||||
async def ap_actor_request(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
|
|
@ -577,24 +577,24 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
ap_url: str,
|
||||
signing_actor: Optional[str]
|
||||
) -> dict:
|
||||
inbox = self.apg.buildAPURL(TYPE_INBOX, ap_account)
|
||||
shared_inbox = self.apg.buildAPURL(TYPE_SHARED_INBOX)
|
||||
outbox = self.apg.buildAPURL(TYPE_OUTBOX, ap_account)
|
||||
followers = self.apg.buildAPURL(TYPE_FOLLOWERS, ap_account)
|
||||
following = self.apg.buildAPURL(TYPE_FOLLOWING, ap_account)
|
||||
inbox = self.apg.build_apurl(TYPE_INBOX, ap_account)
|
||||
shared_inbox = self.apg.build_apurl(TYPE_SHARED_INBOX)
|
||||
outbox = self.apg.build_apurl(TYPE_OUTBOX, ap_account)
|
||||
followers = self.apg.build_apurl(TYPE_FOLLOWERS, ap_account)
|
||||
following = self.apg.build_apurl(TYPE_FOLLOWING, ap_account)
|
||||
|
||||
# we have to use AP account as preferredUsername because it is used to retrieve
|
||||
# actor handle (see https://socialhub.activitypub.rocks/t/how-to-retrieve-user-server-tld-handle-from-actors-url/2196)
|
||||
preferred_username = ap_account.split("@", 1)[0]
|
||||
|
||||
identity_data = await self.apg._i.getIdentity(self.apg.client, account_jid)
|
||||
identity_data = await self.apg._i.get_identity(self.apg.client, account_jid)
|
||||
if node and node.startswith(self.apg._events.namespace):
|
||||
events = outbox
|
||||
else:
|
||||
events_account = await self.apg.getAPAccountFromJidAndNode(
|
||||
events_account = await self.apg.get_ap_account_from_jid_and_node(
|
||||
account_jid, self.apg._events.namespace
|
||||
)
|
||||
events = self.apg.buildAPURL(TYPE_OUTBOX, events_account)
|
||||
events = self.apg.build_apurl(TYPE_OUTBOX, events_account)
|
||||
|
||||
actor_data = {
|
||||
"@context": [
|
||||
|
|
@ -636,7 +636,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
except KeyError:
|
||||
log.error(f"incomplete avatar data: {identity_data!r}")
|
||||
else:
|
||||
avatar_url = self.apg.buildAPURL("avatar", filename)
|
||||
avatar_url = self.apg.build_apurl("avatar", filename)
|
||||
actor_data["icon"] = {
|
||||
"type": "Image",
|
||||
"url": avatar_url,
|
||||
|
|
@ -645,14 +645,14 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
|
||||
return actor_data
|
||||
|
||||
def getCanonicalURL(self, request: "HTTPRequest") -> str:
|
||||
def get_canonical_url(self, request: "HTTPRequest") -> str:
|
||||
return parse.urljoin(
|
||||
f"https://{self.apg.public_url}",
|
||||
request.path.decode().rstrip("/")
|
||||
# we unescape "@" for the same reason as in [APActorRequest]
|
||||
# we unescape "@" for the same reason as in [ap_actor_request]
|
||||
).replace("%40", "@")
|
||||
|
||||
def queryData2RSMRequest(
|
||||
def query_data_2_rsm_request(
|
||||
self,
|
||||
query_data: Dict[str, List[str]]
|
||||
) -> rsm.RSMRequest:
|
||||
|
|
@ -673,7 +673,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
return rsm.RSMRequest(**kwargs)
|
||||
raise ValueError(f"Invalid query data: {query_data!r}")
|
||||
|
||||
async def APOutboxPageRequest(
|
||||
async def ap_outbox_page_request(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
|
|
@ -690,18 +690,18 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
url_keys = sorted(set(query_data) & {"page", "index", "before", "after"})
|
||||
query_data = {k: query_data[k] for k in url_keys}
|
||||
try:
|
||||
items, metadata = await self.apg._p.getItems(
|
||||
items, metadata = await self.apg._p.get_items(
|
||||
client=self.apg.client,
|
||||
service=account_jid,
|
||||
node=node,
|
||||
rsm_request=self.queryData2RSMRequest(query_data),
|
||||
rsm_request=self.query_data_2_rsm_request(query_data),
|
||||
extra = {C.KEY_USE_CACHE: False}
|
||||
)
|
||||
except error.StanzaError as e:
|
||||
log.warning(f"Can't get data from pubsub node {node} at {account_jid}: {e}")
|
||||
return {}
|
||||
|
||||
base_url = self.getCanonicalURL(request)
|
||||
base_url = self.get_canonical_url(request)
|
||||
url = f"{base_url}?{parse.urlencode(query_data, True)}"
|
||||
if node and node.startswith(self.apg._events.namespace):
|
||||
ordered_items = [
|
||||
|
|
@ -753,7 +753,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
|
||||
return ret_data
|
||||
|
||||
async def APOutboxRequest(
|
||||
async def ap_outbox_request(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
|
|
@ -769,7 +769,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
parsed_url = parse.urlparse(request.uri.decode())
|
||||
query_data = parse.parse_qs(parsed_url.query)
|
||||
if query_data:
|
||||
return await self.APOutboxPageRequest(
|
||||
return await self.ap_outbox_page_request(
|
||||
request, data, account_jid, node, ap_account, ap_url, query_data
|
||||
)
|
||||
|
||||
|
|
@ -779,7 +779,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
# The current workaround is to do a request as if RSM was available, and actually
|
||||
# check its availability according to result.
|
||||
try:
|
||||
__, metadata = await self.apg._p.getItems(
|
||||
__, metadata = await self.apg._p.get_items(
|
||||
client=self.apg.client,
|
||||
service=account_jid,
|
||||
node=node,
|
||||
|
|
@ -799,7 +799,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
)
|
||||
items_count = 20
|
||||
|
||||
url = self.getCanonicalURL(request)
|
||||
url = self.get_canonical_url(request)
|
||||
url_first_page = f"{url}?{parse.urlencode({'page': 'first'})}"
|
||||
url_last_page = f"{url}?{parse.urlencode({'page': 'last'})}"
|
||||
return {
|
||||
|
|
@ -811,7 +811,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
"last": url_last_page,
|
||||
}
|
||||
|
||||
async def APInboxRequest(
|
||||
async def ap_inbox_request(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
|
|
@ -824,26 +824,26 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
assert data is not None
|
||||
if signing_actor is None:
|
||||
raise exceptions.InternalError("signing_actor must be set for inbox requests")
|
||||
await self.checkSigningActor(data, signing_actor)
|
||||
await self.check_signing_actor(data, signing_actor)
|
||||
activity_type = (data.get("type") or "").lower()
|
||||
if not activity_type in ACTIVITY_TYPES_LOWER:
|
||||
return self.responseCode(
|
||||
return self.response_code(
|
||||
request,
|
||||
http.UNSUPPORTED_MEDIA_TYPE,
|
||||
f"request is not an activity, ignoring"
|
||||
)
|
||||
|
||||
if account_jid is None and activity_type not in ACTIVIY_NO_ACCOUNT_ALLOWED:
|
||||
return self.responseCode(
|
||||
return self.response_code(
|
||||
request,
|
||||
http.UNSUPPORTED_MEDIA_TYPE,
|
||||
f"{activity_type.title()!r} activity must target an account"
|
||||
)
|
||||
|
||||
try:
|
||||
method = getattr(self, f"handle{activity_type.title()}Activity")
|
||||
method = getattr(self, f"handle_{activity_type}_activity")
|
||||
except AttributeError:
|
||||
return self.responseCode(
|
||||
return self.response_code(
|
||||
request,
|
||||
http.UNSUPPORTED_MEDIA_TYPE,
|
||||
f"{activity_type.title()} activity is not yet supported"
|
||||
|
|
@ -853,7 +853,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
request, data, account_jid, node, ap_account, ap_url, signing_actor
|
||||
)
|
||||
|
||||
async def APFollowersRequest(
|
||||
async def ap_followers_request(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
|
|
@ -866,20 +866,20 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
if node is None:
|
||||
node = self.apg._m.namespace
|
||||
client = self.apg.client
|
||||
subscribers = await self.apg._pps.getPublicNodeSubscriptions(
|
||||
subscribers = await self.apg._pps.get_public_node_subscriptions(
|
||||
client, account_jid, node
|
||||
)
|
||||
followers = []
|
||||
for subscriber in subscribers.keys():
|
||||
if self.apg.isVirtualJID(subscriber):
|
||||
if self.apg.is_virtual_jid(subscriber):
|
||||
# the subscriber is an AP user subscribed with this gateway
|
||||
ap_account = self.apg._e.unescape(subscriber.user)
|
||||
else:
|
||||
# regular XMPP user
|
||||
ap_account = await self.apg.getAPAccountFromJidAndNode(subscriber, node)
|
||||
ap_account = await self.apg.get_ap_account_from_jid_and_node(subscriber, node)
|
||||
followers.append(ap_account)
|
||||
|
||||
url = self.getCanonicalURL(request)
|
||||
url = self.get_canonical_url(request)
|
||||
return {
|
||||
"@context": ["https://www.w3.org/ns/activitystreams"],
|
||||
"type": "OrderedCollection",
|
||||
|
|
@ -892,7 +892,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
}
|
||||
}
|
||||
|
||||
async def APFollowingRequest(
|
||||
async def ap_following_request(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict],
|
||||
|
|
@ -909,17 +909,17 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
following = []
|
||||
for sub_dict in subscriptions:
|
||||
service = jid.JID(sub_dict["service"])
|
||||
if self.apg.isVirtualJID(service):
|
||||
if self.apg.is_virtual_jid(service):
|
||||
# the subscription is to an AP actor with this gateway
|
||||
ap_account = self.apg._e.unescape(service.user)
|
||||
else:
|
||||
# regular XMPP user
|
||||
ap_account = await self.apg.getAPAccountFromJidAndNode(
|
||||
ap_account = await self.apg.get_ap_account_from_jid_and_node(
|
||||
service, sub_dict["node"]
|
||||
)
|
||||
following.append(ap_account)
|
||||
|
||||
url = self.getCanonicalURL(request)
|
||||
url = self.get_canonical_url(request)
|
||||
return {
|
||||
"@context": ["https://www.w3.org/ns/activitystreams"],
|
||||
"type": "OrderedCollection",
|
||||
|
|
@ -953,7 +953,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
to_log.append(f" headers:\n{headers}")
|
||||
return to_log
|
||||
|
||||
async def APRequest(
|
||||
async def ap_request(
|
||||
self,
|
||||
request: "HTTPRequest",
|
||||
data: Optional[dict] = None,
|
||||
|
|
@ -967,13 +967,13 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
f"https://{self.apg.public_url}",
|
||||
path
|
||||
)
|
||||
request_type, extra_args = self.apg.parseAPURL(ap_url)
|
||||
request_type, extra_args = self.apg.parse_apurl(ap_url)
|
||||
if ((MEDIA_TYPE_AP not in (request.getHeader("accept") or "")
|
||||
and request_type in self.apg.html_redirect)):
|
||||
# this is not a AP request, and we have a redirections for it
|
||||
kw = {}
|
||||
if extra_args:
|
||||
kw["jid"], kw["node"] = await self.apg.getJIDAndNode(extra_args[0])
|
||||
kw["jid"], kw["node"] = await self.apg.get_jid_and_node(extra_args[0])
|
||||
kw["jid_user"] = kw["jid"].user
|
||||
if kw["node"] is None:
|
||||
kw["node"] = self.apg._m.namespace
|
||||
|
|
@ -1007,7 +1007,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
if len(extra_args) == 0:
|
||||
if request_type != "shared_inbox":
|
||||
raise exceptions.DataError(f"Invalid request type: {request_type!r}")
|
||||
ret_data = await self.APInboxRequest(
|
||||
ret_data = await self.ap_inbox_request(
|
||||
request, data, None, None, None, ap_url, signing_actor
|
||||
)
|
||||
elif request_type == "avatar":
|
||||
|
|
@ -1017,14 +1017,14 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
avatar_path = self.apg.host.common_cache.getPath(avatar_filename)
|
||||
return static.File(str(avatar_path)).render(request)
|
||||
elif request_type == "item":
|
||||
ret_data = await self.apg.apGetLocalObject(ap_url)
|
||||
ret_data = await self.apg.ap_get_local_object(ap_url)
|
||||
if "@context" not in ret_data:
|
||||
ret_data["@context"] = [NS_AP]
|
||||
else:
|
||||
if len(extra_args) > 1:
|
||||
log.warning(f"unexpected extra arguments: {extra_args!r}")
|
||||
ap_account = extra_args[0]
|
||||
account_jid, node = await self.apg.getJIDAndNode(ap_account)
|
||||
account_jid, node = await self.apg.get_jid_and_node(ap_account)
|
||||
if request_type not in AP_REQUEST_TYPES.get(
|
||||
request.method.decode().upper(), []
|
||||
):
|
||||
|
|
@ -1046,12 +1046,12 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
log.info("\n".join(to_log))
|
||||
request.finish()
|
||||
|
||||
async def APPostRequest(self, request: "HTTPRequest") -> None:
|
||||
async def ap_post_request(self, request: "HTTPRequest") -> None:
|
||||
try:
|
||||
data = json.load(request.content)
|
||||
if not isinstance(data, dict):
|
||||
log.warning(f"JSON data should be an object (uri={request.uri.decode()})")
|
||||
self.responseCode(
|
||||
self.response_code(
|
||||
request,
|
||||
http.BAD_REQUEST,
|
||||
f"invalid body, was expecting a JSON object"
|
||||
|
|
@ -1059,7 +1059,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
request.finish()
|
||||
return
|
||||
except (json.JSONDecodeError, ValueError) as e:
|
||||
self.responseCode(
|
||||
self.response_code(
|
||||
request,
|
||||
http.BAD_REQUEST,
|
||||
f"invalid json in inbox request: {e}"
|
||||
|
|
@ -1081,14 +1081,14 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
pass
|
||||
|
||||
try:
|
||||
signing_actor = await self.checkSignature(request)
|
||||
signing_actor = await self.check_signature(request)
|
||||
except exceptions.EncryptionError as e:
|
||||
if self.apg.verbose:
|
||||
to_log = self._get_to_log(request)
|
||||
to_log.append(f" body: {request.content.read()!r}")
|
||||
request.content.seek(0)
|
||||
log.info("\n".join(to_log))
|
||||
self.responseCode(
|
||||
self.response_code(
|
||||
request,
|
||||
http.FORBIDDEN,
|
||||
f"invalid signature: {e}"
|
||||
|
|
@ -1096,7 +1096,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
request.finish()
|
||||
return
|
||||
except Exception as e:
|
||||
self.responseCode(
|
||||
self.response_code(
|
||||
request,
|
||||
http.INTERNAL_SERVER_ERROR,
|
||||
f"Can't check signature: {e}"
|
||||
|
|
@ -1115,27 +1115,27 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
|
||||
# default response code, may be changed, e.g. in case of exception
|
||||
try:
|
||||
return await self.APRequest(request, data, signing_actor)
|
||||
return await self.ap_request(request, data, signing_actor)
|
||||
except Exception as e:
|
||||
self._onRequestError(failure.Failure(e), request)
|
||||
self._on_request_error(failure.Failure(e), request)
|
||||
|
||||
async def checkSigningActor(self, data: dict, signing_actor: str) -> None:
|
||||
async def check_signing_actor(self, data: dict, signing_actor: str) -> None:
|
||||
"""That that signing actor correspond to actor declared in data
|
||||
|
||||
@param data: request payload
|
||||
@param signing_actor: actor ID of the signing entity, as returned by
|
||||
checkSignature
|
||||
check_signature
|
||||
@raise exceptions.NotFound: no actor found in data
|
||||
@raise exceptions.EncryptionError: signing actor doesn't match actor in data
|
||||
"""
|
||||
actor = await self.apg.apGetSenderActor(data)
|
||||
actor = await self.apg.ap_get_sender_actor(data)
|
||||
|
||||
if signing_actor != actor:
|
||||
raise exceptions.EncryptionError(
|
||||
f"signing actor ({signing_actor}) doesn't match actor in data ({actor})"
|
||||
)
|
||||
|
||||
async def checkSignature(self, request: "HTTPRequest") -> str:
|
||||
async def check_signature(self, request: "HTTPRequest") -> str:
|
||||
"""Check and validate HTTP signature
|
||||
|
||||
@return: id of the signing actor
|
||||
|
|
@ -1242,7 +1242,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
raise exceptions.EncryptionError(
|
||||
"Only SHA-256 algorithm is currently supported for digest"
|
||||
)
|
||||
__, computed_digest = self.apg.getDigest(body)
|
||||
__, computed_digest = self.apg.get_digest(body)
|
||||
if given_digest != computed_digest:
|
||||
raise exceptions.EncryptionError(
|
||||
f"SHA-256 given and computed digest differ:\n"
|
||||
|
|
@ -1275,7 +1275,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
raise exceptions.EncryptionError("Signature has expired")
|
||||
|
||||
try:
|
||||
return await self.apg.checkSignature(
|
||||
return await self.apg.check_signature(
|
||||
sign_data["signature"],
|
||||
key_id,
|
||||
headers
|
||||
|
|
@ -1287,7 +1287,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
"Using workaround for (request-target) encoding bug in signature, "
|
||||
"see https://github.com/mastodon/mastodon/issues/18871"
|
||||
)
|
||||
return await self.apg.checkSignature(
|
||||
return await self.apg.check_signature(
|
||||
sign_data["signature"],
|
||||
key_id,
|
||||
headers
|
||||
|
|
@ -1303,8 +1303,8 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
defer.ensureDeferred(self.webfinger(request))
|
||||
return server.NOT_DONE_YET
|
||||
elif path.startswith(self.apg.ap_path):
|
||||
d = defer.ensureDeferred(self.APRequest(request))
|
||||
d.addErrback(self._onRequestError, request)
|
||||
d = defer.ensureDeferred(self.ap_request(request))
|
||||
d.addErrback(self._on_request_error, request)
|
||||
return server.NOT_DONE_YET
|
||||
|
||||
return web_resource.NoResource().render(request)
|
||||
|
|
@ -1313,7 +1313,7 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
path = request.path.decode().lstrip("/")
|
||||
if not path.startswith(self.apg.ap_path):
|
||||
return web_resource.NoResource().render(request)
|
||||
defer.ensureDeferred(self.APPostRequest(request))
|
||||
defer.ensureDeferred(self.ap_post_request(request))
|
||||
return server.NOT_DONE_YET
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ from sat.core.log import getLogger
|
|||
from sat.core.constants import Const as C
|
||||
from sat.tools import image
|
||||
from sat.tools.utils import ensure_deferred
|
||||
from sat.tools.web import downloadFile
|
||||
from sat.tools.web import download_file
|
||||
from sat.memory.sqla_mapping import PubsubSub, SubscriptionState
|
||||
|
||||
from .constants import (
|
||||
|
|
@ -74,7 +74,7 @@ class APPubsubService(rsm.PubSubService):
|
|||
"name": "Libervia ActivityPub Gateway",
|
||||
}
|
||||
|
||||
async def getAPActorIdsAndInbox(
|
||||
async def get_ap_actor_ids_and_inbox(
|
||||
self,
|
||||
requestor: jid.JID,
|
||||
recipient: jid.JID,
|
||||
|
|
@ -92,16 +92,16 @@ class APPubsubService(rsm.PubSubService):
|
|||
"item-not-found",
|
||||
text="No user part specified"
|
||||
)
|
||||
requestor_actor_id = self.apg.buildAPURL(TYPE_ACTOR, requestor.userhost())
|
||||
requestor_actor_id = self.apg.build_apurl(TYPE_ACTOR, requestor.userhost())
|
||||
recipient_account = self.apg._e.unescape(recipient.user)
|
||||
recipient_actor_id = await self.apg.getAPActorIdFromAccount(recipient_account)
|
||||
inbox = await self.apg.getAPInboxFromId(recipient_actor_id, use_shared=False)
|
||||
recipient_actor_id = await self.apg.get_ap_actor_id_from_account(recipient_account)
|
||||
inbox = await self.apg.get_ap_inbox_from_id(recipient_actor_id, use_shared=False)
|
||||
return requestor_actor_id, recipient_actor_id, inbox
|
||||
|
||||
|
||||
@ensure_deferred
|
||||
async def publish(self, requestor, service, nodeIdentifier, items):
|
||||
if self.apg.local_only and not self.apg.isLocal(requestor):
|
||||
if self.apg.local_only and not self.apg.is_local(requestor):
|
||||
raise error.StanzaError(
|
||||
"forbidden",
|
||||
"Only local users can publish on this gateway."
|
||||
|
|
@ -118,19 +118,19 @@ class APPubsubService(rsm.PubSubService):
|
|||
f"{ap_account!r} is not a valid ActivityPub actor account."
|
||||
)
|
||||
|
||||
client = self.apg.client.getVirtualClient(requestor)
|
||||
if self.apg._pa.isAttachmentNode(nodeIdentifier):
|
||||
await self.apg.convertAndPostAttachments(
|
||||
client = self.apg.client.get_virtual_client(requestor)
|
||||
if self.apg._pa.is_attachment_node(nodeIdentifier):
|
||||
await self.apg.convert_and_post_attachments(
|
||||
client, ap_account, service, nodeIdentifier, items, publisher=requestor
|
||||
)
|
||||
else:
|
||||
await self.apg.convertAndPostItems(
|
||||
await self.apg.convert_and_post_items(
|
||||
client, ap_account, service, nodeIdentifier, items
|
||||
)
|
||||
cached_node = await self.host.memory.storage.getPubsubNode(
|
||||
cached_node = await self.host.memory.storage.get_pubsub_node(
|
||||
client, service, nodeIdentifier, with_subscriptions=True, create=True
|
||||
)
|
||||
await self.host.memory.storage.cachePubsubItems(
|
||||
await self.host.memory.storage.cache_pubsub_items(
|
||||
client,
|
||||
cached_node,
|
||||
items
|
||||
|
|
@ -144,27 +144,27 @@ class APPubsubService(rsm.PubSubService):
|
|||
[(subscription.subscriber, None, items)]
|
||||
)
|
||||
|
||||
async def apFollowing2Elt(self, ap_item: dict) -> domish.Element:
|
||||
async def ap_following_2_elt(self, ap_item: dict) -> domish.Element:
|
||||
"""Convert actor ID from following collection to XMPP item"""
|
||||
actor_id = ap_item["id"]
|
||||
actor_jid = await self.apg.getJIDFromId(actor_id)
|
||||
subscription_elt = self.apg._pps.buildSubscriptionElt(
|
||||
actor_jid = await self.apg.get_jid_from_id(actor_id)
|
||||
subscription_elt = self.apg._pps.build_subscription_elt(
|
||||
self.apg._m.namespace, actor_jid
|
||||
)
|
||||
item_elt = pubsub.Item(id=actor_id, payload=subscription_elt)
|
||||
return item_elt
|
||||
|
||||
async def apFollower2Elt(self, ap_item: dict) -> domish.Element:
|
||||
async def ap_follower_2_elt(self, ap_item: dict) -> domish.Element:
|
||||
"""Convert actor ID from followers collection to XMPP item"""
|
||||
actor_id = ap_item["id"]
|
||||
actor_jid = await self.apg.getJIDFromId(actor_id)
|
||||
subscriber_elt = self.apg._pps.buildSubscriberElt(actor_jid)
|
||||
actor_jid = await self.apg.get_jid_from_id(actor_id)
|
||||
subscriber_elt = self.apg._pps.build_subscriber_elt(actor_jid)
|
||||
item_elt = pubsub.Item(id=actor_id, payload=subscriber_elt)
|
||||
return item_elt
|
||||
|
||||
async def generateVCard(self, ap_account: str) -> domish.Element:
|
||||
async def generate_v_card(self, ap_account: str) -> domish.Element:
|
||||
"""Generate vCard4 (XEP-0292) item element from ap_account's metadata"""
|
||||
actor_data = await self.apg.getAPActorDataFromAccount(ap_account)
|
||||
actor_data = await self.apg.get_ap_actor_data_from_account(ap_account)
|
||||
identity_data = {}
|
||||
|
||||
summary = actor_data.get("summary")
|
||||
|
|
@ -181,13 +181,13 @@ class APPubsubService(rsm.PubSubService):
|
|||
value = actor_data.get(field)
|
||||
if value:
|
||||
identity_data.setdefault("nicknames", []).append(value)
|
||||
vcard_elt = self.apg._v.dict2VCard(identity_data)
|
||||
vcard_elt = self.apg._v.dict_2_v_card(identity_data)
|
||||
item_elt = domish.Element((pubsub.NS_PUBSUB, "item"))
|
||||
item_elt.addChild(vcard_elt)
|
||||
item_elt["id"] = self.apg._p.ID_SINGLETON
|
||||
return item_elt
|
||||
|
||||
async def getAvatarData(
|
||||
async def get_avatar_data(
|
||||
self,
|
||||
client: SatXMPPEntity,
|
||||
ap_account: str
|
||||
|
|
@ -197,9 +197,9 @@ class APPubsubService(rsm.PubSubService):
|
|||
``cache_uid``, `path``` and ``media_type`` keys are always files
|
||||
``base64`` key is only filled if the file was not already in cache
|
||||
"""
|
||||
actor_data = await self.apg.getAPActorDataFromAccount(ap_account)
|
||||
actor_data = await self.apg.get_ap_actor_data_from_account(ap_account)
|
||||
|
||||
for icon in await self.apg.apGetList(actor_data, "icon"):
|
||||
for icon in await self.apg.ap_get_list(actor_data, "icon"):
|
||||
url = icon.get("url")
|
||||
if icon["type"] != "Image" or not url:
|
||||
continue
|
||||
|
|
@ -221,19 +221,19 @@ class APPubsubService(rsm.PubSubService):
|
|||
if cache_uid is None:
|
||||
cache = None
|
||||
else:
|
||||
cache = self.apg.host.common_cache.getMetadata(cache_uid)
|
||||
cache = self.apg.host.common_cache.get_metadata(cache_uid)
|
||||
|
||||
if cache is None:
|
||||
with tempfile.TemporaryDirectory() as dir_name:
|
||||
dest_path = Path(dir_name, filename)
|
||||
await downloadFile(url, dest_path, max_size=MAX_AVATAR_SIZE)
|
||||
await download_file(url, dest_path, max_size=MAX_AVATAR_SIZE)
|
||||
avatar_data = {
|
||||
"path": dest_path,
|
||||
"filename": filename,
|
||||
'media_type': image.guess_type(dest_path),
|
||||
}
|
||||
|
||||
await self.apg._i.cacheAvatar(
|
||||
await self.apg._i.cache_avatar(
|
||||
self.apg.IMPORT_NAME,
|
||||
avatar_data
|
||||
)
|
||||
|
|
@ -246,7 +246,7 @@ class APPubsubService(rsm.PubSubService):
|
|||
|
||||
return avatar_data
|
||||
|
||||
async def generateAvatarMetadata(
|
||||
async def generate_avatar_metadata(
|
||||
self,
|
||||
client: SatXMPPEntity,
|
||||
ap_account: str
|
||||
|
|
@ -256,14 +256,14 @@ class APPubsubService(rsm.PubSubService):
|
|||
@raise StanzaError("item-not-found"): no avatar is present in actor data (in
|
||||
``icon`` field)
|
||||
"""
|
||||
avatar_data = await self.getAvatarData(client, ap_account)
|
||||
return self.apg._a.buildItemMetadataElt(avatar_data)
|
||||
avatar_data = await self.get_avatar_data(client, ap_account)
|
||||
return self.apg._a.build_item_metadata_elt(avatar_data)
|
||||
|
||||
def _blockingB64EncodeAvatar(self, avatar_data: Dict[str, Any]) -> None:
|
||||
def _blocking_b_6_4_encode_avatar(self, avatar_data: Dict[str, Any]) -> None:
|
||||
with avatar_data["path"].open("rb") as f:
|
||||
avatar_data["base64"] = b64encode(f.read()).decode()
|
||||
|
||||
async def generateAvatarData(
|
||||
async def generate_avatar_data(
|
||||
self,
|
||||
client: SatXMPPEntity,
|
||||
ap_account: str,
|
||||
|
|
@ -274,9 +274,9 @@ class APPubsubService(rsm.PubSubService):
|
|||
@raise StanzaError("item-not-found"): no avatar cached with requested ID
|
||||
"""
|
||||
if not itemIdentifiers:
|
||||
avatar_data = await self.getAvatarData(client, ap_account)
|
||||
avatar_data = await self.get_avatar_data(client, ap_account)
|
||||
if "base64" not in avatar_data:
|
||||
await threads.deferToThread(self._blockingB64EncodeAvatar, avatar_data)
|
||||
await threads.deferToThread(self._blocking_b_6_4_encode_avatar, avatar_data)
|
||||
else:
|
||||
if len(itemIdentifiers) > 1:
|
||||
# only a single item ID is supported
|
||||
|
|
@ -284,16 +284,16 @@ class APPubsubService(rsm.PubSubService):
|
|||
item_id = itemIdentifiers[0]
|
||||
# just to be sure that that we don't have an empty string
|
||||
assert item_id
|
||||
cache_data = self.apg.host.common_cache.getMetadata(item_id)
|
||||
cache_data = self.apg.host.common_cache.get_metadata(item_id)
|
||||
if cache_data is None:
|
||||
raise error.StanzaError("item-not-found")
|
||||
avatar_data = {
|
||||
"cache_uid": item_id,
|
||||
"path": cache_data["path"]
|
||||
}
|
||||
await threads.deferToThread(self._blockingB64EncodeAvatar, avatar_data)
|
||||
await threads.deferToThread(self._blocking_b_6_4_encode_avatar, avatar_data)
|
||||
|
||||
return self.apg._a.buildItemDataElt(avatar_data)
|
||||
return self.apg._a.build_item_data_elt(avatar_data)
|
||||
|
||||
@ensure_deferred
|
||||
async def items(
|
||||
|
|
@ -320,31 +320,31 @@ class APPubsubService(rsm.PubSubService):
|
|||
|
||||
if node == self.apg._pps.subscriptions_node:
|
||||
collection_name = "following"
|
||||
parser = self.apFollowing2Elt
|
||||
parser = self.ap_following_2_elt
|
||||
kwargs["only_ids"] = True
|
||||
use_cache = False
|
||||
elif node.startswith(self.apg._pps.subscribers_node_prefix):
|
||||
collection_name = "followers"
|
||||
parser = self.apFollower2Elt
|
||||
parser = self.ap_follower_2_elt
|
||||
kwargs["only_ids"] = True
|
||||
use_cache = False
|
||||
elif node == self.apg._v.node:
|
||||
# vCard4 request
|
||||
item_elt = await self.generateVCard(ap_account)
|
||||
item_elt = await self.generate_v_card(ap_account)
|
||||
return [item_elt], None
|
||||
elif node == self.apg._a.namespace_metadata:
|
||||
item_elt = await self.generateAvatarMetadata(self.apg.client, ap_account)
|
||||
item_elt = await self.generate_avatar_metadata(self.apg.client, ap_account)
|
||||
return [item_elt], None
|
||||
elif node == self.apg._a.namespace_data:
|
||||
item_elt = await self.generateAvatarData(
|
||||
item_elt = await self.generate_avatar_data(
|
||||
self.apg.client, ap_account, itemIdentifiers
|
||||
)
|
||||
return [item_elt], None
|
||||
elif self.apg._pa.isAttachmentNode(node):
|
||||
elif self.apg._pa.is_attachment_node(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(
|
||||
cached_node = await self.host.memory.storage.get_pubsub_node(
|
||||
client, service, node
|
||||
)
|
||||
if cached_node is None:
|
||||
|
|
@ -365,14 +365,14 @@ class APPubsubService(rsm.PubSubService):
|
|||
|
||||
if use_cache:
|
||||
if cached_node is None:
|
||||
cached_node = await self.host.memory.storage.getPubsubNode(
|
||||
cached_node = await self.host.memory.storage.get_pubsub_node(
|
||||
client, service, node
|
||||
)
|
||||
# TODO: check if node is synchronised
|
||||
if cached_node is not None:
|
||||
# the node is cached, we return items from cache
|
||||
log.debug(f"node {node!r} from {service} is in cache")
|
||||
pubsub_items, metadata = await self.apg._c.getItemsFromCache(
|
||||
pubsub_items, metadata = await self.apg._c.get_items_from_cache(
|
||||
client, cached_node, maxItems, itemIdentifiers, rsm_request=rsm_req
|
||||
)
|
||||
try:
|
||||
|
|
@ -384,7 +384,7 @@ class APPubsubService(rsm.PubSubService):
|
|||
if itemIdentifiers:
|
||||
items = []
|
||||
for item_id in itemIdentifiers:
|
||||
item_data = await self.apg.apGet(item_id)
|
||||
item_data = await self.apg.ap_get(item_id)
|
||||
item_elt = await parser(item_data)
|
||||
items.append(item_elt)
|
||||
return items, None
|
||||
|
|
@ -419,11 +419,11 @@ class APPubsubService(rsm.PubSubService):
|
|||
f"No cache found for node {node} at {service} (AP account {ap_account}), "
|
||||
"using Collection Paging to RSM translation"
|
||||
)
|
||||
if self.apg._m.isCommentNode(node):
|
||||
parent_item = self.apg._m.getParentItem(node)
|
||||
if self.apg._m.is_comment_node(node):
|
||||
parent_item = self.apg._m.get_parent_item(node)
|
||||
try:
|
||||
parent_data = await self.apg.apGet(parent_item)
|
||||
collection = await self.apg.apGetObject(
|
||||
parent_data = await self.apg.ap_get(parent_item)
|
||||
collection = await self.apg.ap_get_object(
|
||||
parent_data.get("object", {}),
|
||||
"replies"
|
||||
)
|
||||
|
|
@ -433,8 +433,8 @@ class APPubsubService(rsm.PubSubService):
|
|||
text=e
|
||||
)
|
||||
else:
|
||||
actor_data = await self.apg.getAPActorDataFromAccount(ap_account)
|
||||
collection = await self.apg.apGetObject(actor_data, collection_name)
|
||||
actor_data = await self.apg.get_ap_actor_data_from_account(ap_account)
|
||||
collection = await self.apg.ap_get_object(actor_data, collection_name)
|
||||
if not collection:
|
||||
raise error.StanzaError(
|
||||
"item-not-found",
|
||||
|
|
@ -442,7 +442,7 @@ class APPubsubService(rsm.PubSubService):
|
|||
)
|
||||
|
||||
kwargs["parser"] = parser
|
||||
return await self.apg.getAPItems(collection, **kwargs)
|
||||
return await self.apg.get_ap_items(collection, **kwargs)
|
||||
|
||||
@ensure_deferred
|
||||
async def retract(self, requestor, service, nodeIdentifier, itemIdentifiers):
|
||||
|
|
@ -459,11 +459,11 @@ class APPubsubService(rsm.PubSubService):
|
|||
sub_state = SubscriptionState.PENDING
|
||||
else:
|
||||
sub_state = SubscriptionState.SUBSCRIBED
|
||||
node = await self.host.memory.storage.getPubsubNode(
|
||||
node = await self.host.memory.storage.get_pubsub_node(
|
||||
client, service, nodeIdentifier, with_subscriptions=True
|
||||
)
|
||||
if node is None:
|
||||
node = await self.host.memory.storage.setPubsubNode(
|
||||
node = await self.host.memory.storage.set_pubsub_node(
|
||||
client,
|
||||
service,
|
||||
nodeIdentifier,
|
||||
|
|
@ -510,13 +510,13 @@ class APPubsubService(rsm.PubSubService):
|
|||
if nodeIdentifier in (self.apg._m.namespace, self.apg._events.namespace):
|
||||
# if we subscribe to microblog or events node, we follow the corresponding
|
||||
# account
|
||||
req_actor_id, recip_actor_id, inbox = await self.getAPActorIdsAndInbox(
|
||||
req_actor_id, recip_actor_id, inbox = await self.get_ap_actor_ids_and_inbox(
|
||||
requestor, service
|
||||
)
|
||||
|
||||
data = self.apg.create_activity("Follow", req_actor_id, recip_actor_id)
|
||||
|
||||
resp = await self.apg.signAndPost(inbox, req_actor_id, data)
|
||||
resp = await self.apg.sign_and_post(inbox, req_actor_id, data)
|
||||
if resp.code >= 300:
|
||||
text = await resp.text()
|
||||
raise error.StanzaError("service-unavailable", text=text)
|
||||
|
|
@ -524,7 +524,7 @@ class APPubsubService(rsm.PubSubService):
|
|||
|
||||
@ensure_deferred
|
||||
async def unsubscribe(self, requestor, service, nodeIdentifier, subscriber):
|
||||
req_actor_id, recip_actor_id, inbox = await self.getAPActorIdsAndInbox(
|
||||
req_actor_id, recip_actor_id, inbox = await self.get_ap_actor_ids_and_inbox(
|
||||
requestor, service
|
||||
)
|
||||
data = self.apg.create_activity(
|
||||
|
|
@ -537,7 +537,7 @@ class APPubsubService(rsm.PubSubService):
|
|||
)
|
||||
)
|
||||
|
||||
resp = await self.apg.signAndPost(inbox, req_actor_id, data)
|
||||
resp = await self.apg.sign_and_post(inbox, req_actor_id, data)
|
||||
if resp.code >= 300:
|
||||
text = await resp.text()
|
||||
raise error.StanzaError("service-unavailable", text=text)
|
||||
|
|
|
|||
Loading…
Reference in a new issue