diff --git a/app/admin.py b/app/admin.py index 49fa650..ffe6215 100644 --- a/app/admin.py +++ b/app/admin.py @@ -270,6 +270,9 @@ async def admin_outbox( joinedload(models.OutboxObject.relates_to_inbox_object), joinedload(models.OutboxObject.relates_to_outbox_object), joinedload(models.OutboxObject.relates_to_actor), + joinedload(models.OutboxObject.outbox_object_attachments).options( + joinedload(models.OutboxObjectAttachment.upload) + ), ) .order_by(models.OutboxObject.ap_published_at.desc()) .limit(page_size) @@ -317,7 +320,11 @@ async def get_notifications( .options( joinedload(models.Notification.actor), joinedload(models.Notification.inbox_object), - joinedload(models.Notification.outbox_object), + joinedload(models.Notification.outbox_object).options( + joinedload( + models.OutboxObject.outbox_object_attachments + ).options(joinedload(models.OutboxObjectAttachment.upload)), + ), ) .order_by(models.Notification.created_at.desc()) ) diff --git a/app/ap_object.py b/app/ap_object.py index 5c2224c..92b6920 100644 --- a/app/ap_object.py +++ b/app/ap_object.py @@ -11,7 +11,6 @@ from app.actor import LOCAL_ACTOR from app.actor import Actor from app.actor import RemoteActor from app.media import proxied_media_url -from app.utils import opengraph class Object: @@ -199,13 +198,9 @@ class RemoteObject(Object): ) self._og_meta = None - if self.ap_type == "Note": - self._og_meta = opengraph.og_meta_from_note(self._raw_object) @property def og_meta(self) -> list[dict[str, Any]] | None: - if self._og_meta: - return [og_meta.dict() for og_meta in self._og_meta] return None @property diff --git a/app/boxes.py b/app/boxes.py index f68f5cb..bd11431 100644 --- a/app/boxes.py +++ b/app/boxes.py @@ -30,6 +30,7 @@ from app.database import now from app.outgoing_activities import new_outgoing_activity from app.source import markdownify from app.uploads import upload_to_attachment +from app.utils import opengraph AnyboxObject = models.InboxObject | models.OutboxObject @@ -60,7 +61,7 @@ async def save_outbox_object( ap_context=ra.ap_context, ap_object=ra.ap_object, visibility=ra.visibility, - og_meta=ra.og_meta, + og_meta=await opengraph.og_meta_from_note(ra.ap_object), relates_to_inbox_object_id=relates_to_inbox_object_id, relates_to_outbox_object_id=relates_to_outbox_object_id, relates_to_actor_id=relates_to_actor_id, diff --git a/app/templates/utils.html b/app/templates/utils.html index 61649c2..6284c10 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -168,6 +168,26 @@ {% endmacro %} +{% macro display_og_meta(object) %} +{% if object.og_meta %} +{% for og_meta in object.og_meta %} +
+ {% if og_meta.image %} +
+ +
+
+ {{ og_meta.title }} + {% if og_meta.description %}

{{ og_meta.description }}

{% endif %} + {{ og_meta.site_name }} +
+ {% endif %} +
+{% endfor %} +{% endif %} +{% endmacro %} + + {% macro display_attachments(object) %} {% if object.attachments and object.sensitive and not request.query_params.show_sensitive == object.permalink_id %} {{ sensitive_button(object.permalink_id )}} @@ -206,6 +226,8 @@ {% endif %} +{{ display_og_meta(object) }} + {{ object.visibility.value }} {% if object.is_from_outbox %} @@ -248,8 +270,12 @@ +
+ {{ display_og_meta(object) }} +
- {{ display_attachments(object) }} + + {{ display_attachments(object) }}
diff --git a/app/utils/opengraph.py b/app/utils/opengraph.py index 1e29919..f75a022 100644 --- a/app/utils/opengraph.py +++ b/app/utils/opengraph.py @@ -1,5 +1,6 @@ import mimetypes import re +from typing import Any from urllib.parse import urlparse import httpx @@ -60,14 +61,16 @@ def _urls_from_note(note: ap.RawObject) -> set[str]: return urls -def _og_meta_from_url(url: str) -> OpenGraphMeta | None: - resp = httpx.get( - url, - headers={ - "User-Agent": config.USER_AGENT, - }, - follow_redirects=True, - ) +async def _og_meta_from_url(url: str) -> OpenGraphMeta | None: + async with httpx.AsyncClient() as client: + resp = await client.get( + url, + headers={ + "User-Agent": config.USER_AGENT, + }, + follow_redirects=True, + ) + resp.raise_for_status() if not (ct := resp.headers.get("content-type")) or not ct.startswith("text/html"): @@ -76,14 +79,14 @@ def _og_meta_from_url(url: str) -> OpenGraphMeta | None: return _scrap_og_meta(resp.text) -def og_meta_from_note(note: ap.RawObject) -> list[OpenGraphMeta]: +async def og_meta_from_note(note: ap.RawObject) -> list[dict[str, Any]]: og_meta = [] urls = _urls_from_note(note) for url in urls: try: - maybe_og_meta = _og_meta_from_url(url) + maybe_og_meta = await _og_meta_from_url(url) if maybe_og_meta: - og_meta.append(maybe_og_meta) + og_meta.append(maybe_og_meta.dict()) except httpx.HTTPError: pass