Mercurial > libervia-backend
diff sat/plugins/plugin_comp_ap_gateway/http_server.py @ 3821:0b1c30ff2cbb
component AP: XMPP identity => AP actor data converstion:
XMPP identity data (coming from various XEPs, notably XEP-0292 (vCard4) and XEP-0084 (User
Avatar)) are now used to complete actor data.
Avatar files can now be delivered with the `avatar` type in URL.
rel 368
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 29 Jun 2022 12:06:21 +0200 |
parents | 2032826cfbcf |
children | 81c79b7cafa7 |
line wrap: on
line diff
--- a/sat/plugins/plugin_comp_ap_gateway/http_server.py Wed Jun 29 11:59:07 2022 +0200 +++ b/sat/plugins/plugin_comp_ap_gateway/http_server.py Wed Jun 29 12:06:21 2022 +0200 @@ -17,14 +17,17 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. import time +import html from typing import Optional, Dict, List, Any import json from urllib import parse from collections import deque import unicodedata +from pathlib import Path from pprint import pformat from twisted.web import http, resource as web_resource, server +from twisted.web import static from twisted.python import failure from twisted.internet import reactor, defer from twisted.words.protocols.jabber import jid, error @@ -300,7 +303,10 @@ # 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] - return { + + identity_data = await self.apg._i.getIdentity(self.apg.client, account_jid) + + actor_data = { "@context": [ "https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1" @@ -323,6 +329,28 @@ }, } + if identity_data.get("nicknames"): + actor_data["name"] = identity_data["nicknames"][0] + if identity_data.get("description"): + # description is plain text while summary expects HTML + actor_data["summary"] = html.escape(identity_data["description"]) + if identity_data.get("avatar"): + avatar_data = identity_data["avatar"] + try: + filename = avatar_data["filename"] + media_type = avatar_data["media_type"] + except KeyError: + log.error(f"incomplete avatar data: {identity_data!r}") + else: + avatar_url = self.apg.buildAPURL("avatar", filename) + actor_data["icon"] = { + "type": "Image", + "url": avatar_url, + "mediaType": media_type + } + + return actor_data + def getCanonicalURL(self, request: "HTTPRequest") -> str: return parse.urljoin( f"https://{self.apg.public_url}", @@ -618,6 +646,12 @@ ret_data = await self.APInboxRequest( request, None, None, None, ap_url, signing_actor ) + elif request_type == "avatar": + if len(extra_args) != 1: + raise exceptions.DataError("avatar argument expected in URL") + avatar_filename = extra_args[0] + avatar_path = self.apg.host.common_cache.getPath(avatar_filename) + return static.File(str(avatar_path)).render(request) else: if len(extra_args) > 1: log.warning(f"unexpected extra arguments: {extra_args!r}")