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
This commit is contained in:
parent
f6ccf044da
commit
303e25f72e
2 changed files with 37 additions and 3 deletions
|
|
@ -87,8 +87,8 @@ PLUGIN_INFO = {
|
|||
C.PI_TYPE: C.PLUG_TYPE_ENTRY_POINT,
|
||||
C.PI_PROTOCOLS: [],
|
||||
C.PI_DEPENDENCIES: [
|
||||
"XEP-0060", "XEP-0106", "XEP-0277", "XEP-0329", "XEP-0424", "XEP-0465",
|
||||
"PUBSUB_CACHE", "TEXT_SYNTAXES"
|
||||
"XEP-0060", "XEP-0084", "XEP-0106", "XEP-0277", "XEP-0292", "XEP-0329",
|
||||
"XEP-0424", "XEP-0465", "PUBSUB_CACHE", "TEXT_SYNTAXES", "IDENTITY", "XEP-0054"
|
||||
],
|
||||
C.PI_RECOMMENDATIONS: [],
|
||||
C.PI_MAIN: "APGateway",
|
||||
|
|
|
|||
|
|
@ -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 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
# 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 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
},
|
||||
}
|
||||
|
||||
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 @@ class HTTPAPGServer(web_resource.Resource):
|
|||
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}")
|
||||
|
|
|
|||
Loading…
Reference in a new issue