Add support for profile metadata
parent
ff59e49866
commit
e8397f802d
|
@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
|
|||
from typing import Any
|
||||
|
||||
import httpx
|
||||
from markdown import markdown
|
||||
|
||||
from app import config
|
||||
from app.config import AP_CONTENT_TYPE # noqa: F401
|
||||
|
@ -96,7 +97,16 @@ ME = {
|
|||
},
|
||||
"url": config.ID + "/", # XXX: the path is important for Mastodon compat
|
||||
"manuallyApprovesFollowers": config.CONFIG.manually_approves_followers,
|
||||
"attachment": [],
|
||||
"attachment": [
|
||||
{
|
||||
"name": kv.key,
|
||||
"type": "PropertyValue",
|
||||
"value": markdown(kv.value, extensions=["mdx_linkify", "fenced_code"]),
|
||||
}
|
||||
for kv in config.CONFIG.metadata
|
||||
]
|
||||
if config.CONFIG.metadata
|
||||
else [],
|
||||
"icon": {
|
||||
"mediaType": mimetypes.guess_type(config.CONFIG.icon_url)[0],
|
||||
"type": "Image",
|
||||
|
|
|
@ -257,6 +257,14 @@ def _actor_hash(actor: Actor) -> bytes:
|
|||
if actor.icon_url:
|
||||
h.update(actor.icon_url.encode())
|
||||
|
||||
if actor.attachments:
|
||||
for a in actor.attachments:
|
||||
if a.get("type") != "PropertyValue":
|
||||
continue
|
||||
|
||||
h.update(a["name"].encode())
|
||||
h.update(a["value"].encode())
|
||||
|
||||
h.update(actor.public_key_id.encode())
|
||||
h.update(actor.public_key_as_pem.encode())
|
||||
|
||||
|
|
|
@ -36,6 +36,11 @@ class _PrivacyReplace(pydantic.BaseModel):
|
|||
replace_by: str
|
||||
|
||||
|
||||
class _ProfileMetadata(pydantic.BaseModel):
|
||||
key: str
|
||||
value: str
|
||||
|
||||
|
||||
class Config(pydantic.BaseModel):
|
||||
domain: str
|
||||
username: str
|
||||
|
@ -49,6 +54,7 @@ class Config(pydantic.BaseModel):
|
|||
trusted_hosts: list[str] = ["127.0.0.1"]
|
||||
manually_approves_followers: bool = False
|
||||
privacy_replace: list[_PrivacyReplace] | None = None
|
||||
metadata: list[_ProfileMetadata] | None = None
|
||||
code_highlighting_theme = "friendly_grayscale"
|
||||
|
||||
# Config items to make tests easier
|
||||
|
|
|
@ -51,6 +51,26 @@ a {
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
dl {
|
||||
display: flex;
|
||||
dt {
|
||||
width: 200px;
|
||||
flex: 0 0 auto;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
dd {
|
||||
flex: 1 1 auto;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
p {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shared-header {
|
||||
margin-left: 20px;
|
||||
margin-top: 30px;
|
||||
|
|
|
@ -11,6 +11,17 @@
|
|||
{{ local_actor.summary | safe }}
|
||||
</div>
|
||||
|
||||
<div id="profile-props">
|
||||
{% for prop in local_actor.attachments %}
|
||||
<dl>
|
||||
{% if prop.type == "PropertyValue" %}
|
||||
<dt class="muted" title="{{ prop.name }}">{{ prop.name }}</dt>
|
||||
<dd>{{ prop.value | clean_html(local_actor) | safe }}</dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{%- macro header_link(url, text) -%}
|
||||
|
|
|
@ -289,14 +289,14 @@
|
|||
|
||||
{% if actor.attachments %}
|
||||
<div id="profile-props">
|
||||
<dl>
|
||||
{% for prop in actor.attachments %}
|
||||
{% for prop in actor.attachments %}
|
||||
<dl>
|
||||
{% if prop.type == "PropertyValue" %}
|
||||
<dt>{{ prop.name }}</dt>
|
||||
<dd>{{ prop.value | clean_html(actor) | safe }}</dd>
|
||||
<dt class="muted" title="{{ prop.name }}">{{ prop.name }}</dt>
|
||||
<dd>{{ prop.value | clean_html(actor) | safe }}</dd>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</dl>
|
||||
</dl>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
|
Loading…
Reference in New Issue