diff --git a/app/actor.py b/app/actor.py index a270801..e2caaad 100644 --- a/app/actor.py +++ b/app/actor.py @@ -1,6 +1,7 @@ import hashlib import typing from dataclasses import dataclass +from functools import cached_property from typing import Union from urllib.parse import urlparse @@ -66,8 +67,8 @@ class Actor: return self.ap_actor["inbox"] @property - def shared_inbox_url(self) -> str | None: - return self.ap_actor.get("endpoints", {}).get("sharedInbox") + def shared_inbox_url(self) -> str: + return self.ap_actor.get("endpoints", {}).get("sharedInbox") or self.inbox_url @property def icon_url(self) -> str | None: @@ -107,6 +108,10 @@ class Actor: def followers_collection_id(self) -> str | None: return self.ap_actor.get("followers") + @cached_property + def attachments(self) -> list[ap.RawObject]: + return ap.as_list(self.ap_actor.get("attachment", [])) + class RemoteActor(Actor): def __init__(self, ap_actor: ap.RawObject) -> None: diff --git a/app/boxes.py b/app/boxes.py index 1ecd68f..c59a5fb 100644 --- a/app/boxes.py +++ b/app/boxes.py @@ -577,7 +577,7 @@ async def _compute_recipients( # If we got a local collection, assume it's a collection of actors if r.startswith(BASE_URL): for actor in await fetch_actor_collection(db_session, r): - recipients.add(actor.shared_inbox_url or actor.inbox_url) + recipients.add(actor.shared_inbox_url) continue @@ -588,19 +588,19 @@ async def _compute_recipients( ) ).scalar_one_or_none() # type: ignore if known_actor: - recipients.add(known_actor.shared_inbox_url or known_actor.inbox_url) + recipients.add(known_actor.shared_inbox_url) continue # Fetch the object raw_object = await ap.fetch(r) if raw_object.get("type") in ap.ACTOR_TYPES: saved_actor = await save_actor(db_session, raw_object) - recipients.add(saved_actor.shared_inbox_url or saved_actor.inbox_url) + recipients.add(saved_actor.shared_inbox_url) else: # Assume it's a collection of actors for raw_actor in await ap.parse_collection(payload=raw_object): actor = RemoteActor(raw_actor) - recipients.add(actor.shared_inbox_url or actor.inbox_url) + recipients.add(actor.shared_inbox_url) return recipients @@ -640,7 +640,7 @@ async def _get_followers_recipients( followers = await _get_followers(db_session) return { - follower.actor.shared_inbox_url or follower.actor.inbox_url # type: ignore + follower.actor.shared_inbox_url # type: ignore for follower in followers if follower.actor.ap_id not in actor_ap_ids_to_skip } diff --git a/app/main.py b/app/main.py index 9212af0..793b7f3 100644 --- a/app/main.py +++ b/app/main.py @@ -76,7 +76,6 @@ _RESIZED_CACHE: MutableMapping[tuple[str, int], tuple[bytes, str, Any]] = LFUCac # TODO(ts): # # Next: -# - share nginx config in doc # - prevent double accept/double follow # - UI support for updating posts # - indieauth tweaks diff --git a/app/templates/utils.html b/app/templates/utils.html index 5c1726c..ba93ed2 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -196,13 +196,6 @@ -{% if with_details and actor.summary %} -
- {{ actor.summary | clean_html(actor) | safe }} -
-{% endif %} - - {% if is_admin and metadata %}
{% endif %} +{% if with_details %} + {% if actor.summary %} +
+ {{ actor.summary | clean_html(actor) | safe }} +
+ {% endif %} + + {% if actor.attachments %} +
+
+ {% for prop in actor.attachments %} + {% if prop.type == "PropertyValue" %} +
{{ prop.name }}
+
{{ prop.value | clean_html(actor) | safe }}
+ {% endif %} + {% endfor %} +
+
+ {% endif %} +{% endif %} + {% if not embedded %} {% endif %}