Admin fixes and improved OG meta support

This commit is contained in:
Thomas Sileo 2022-06-29 21:38:13 +02:00
parent 1f54a6a6ac
commit f560821be0
5 changed files with 51 additions and 19 deletions

View file

@ -270,6 +270,9 @@ async def admin_outbox(
joinedload(models.OutboxObject.relates_to_inbox_object), joinedload(models.OutboxObject.relates_to_inbox_object),
joinedload(models.OutboxObject.relates_to_outbox_object), joinedload(models.OutboxObject.relates_to_outbox_object),
joinedload(models.OutboxObject.relates_to_actor), 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()) .order_by(models.OutboxObject.ap_published_at.desc())
.limit(page_size) .limit(page_size)
@ -317,7 +320,11 @@ async def get_notifications(
.options( .options(
joinedload(models.Notification.actor), joinedload(models.Notification.actor),
joinedload(models.Notification.inbox_object), 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()) .order_by(models.Notification.created_at.desc())
) )

View file

@ -11,7 +11,6 @@ from app.actor import LOCAL_ACTOR
from app.actor import Actor from app.actor import Actor
from app.actor import RemoteActor from app.actor import RemoteActor
from app.media import proxied_media_url from app.media import proxied_media_url
from app.utils import opengraph
class Object: class Object:
@ -199,13 +198,9 @@ class RemoteObject(Object):
) )
self._og_meta = None self._og_meta = None
if self.ap_type == "Note":
self._og_meta = opengraph.og_meta_from_note(self._raw_object)
@property @property
def og_meta(self) -> list[dict[str, Any]] | None: 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 return None
@property @property

View file

@ -30,6 +30,7 @@ from app.database import now
from app.outgoing_activities import new_outgoing_activity from app.outgoing_activities import new_outgoing_activity
from app.source import markdownify from app.source import markdownify
from app.uploads import upload_to_attachment from app.uploads import upload_to_attachment
from app.utils import opengraph
AnyboxObject = models.InboxObject | models.OutboxObject AnyboxObject = models.InboxObject | models.OutboxObject
@ -60,7 +61,7 @@ async def save_outbox_object(
ap_context=ra.ap_context, ap_context=ra.ap_context,
ap_object=ra.ap_object, ap_object=ra.ap_object,
visibility=ra.visibility, 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_inbox_object_id=relates_to_inbox_object_id,
relates_to_outbox_object_id=relates_to_outbox_object_id, relates_to_outbox_object_id=relates_to_outbox_object_id,
relates_to_actor_id=relates_to_actor_id, relates_to_actor_id=relates_to_actor_id,

View file

@ -168,6 +168,26 @@
{% endmacro %} {% endmacro %}
{% macro display_og_meta(object) %}
{% if object.og_meta %}
{% for og_meta in object.og_meta %}
<div style="display:flex;column-gap: 20px;margin:20px 0;">
{% if og_meta.image %}
<div>
<img src="{{ og_meta.image | media_proxy_url }}" style="max-width:200px;">
</div>
<div>
<a href="{{ og_meta.url }}">{{ og_meta.title }}</a>
{% if og_meta.description %}<p>{{ og_meta.description }}</p>{% endif %}
<small style="display:block;">{{ og_meta.site_name }}</small>
</div>
{% endif %}
</div>
{% endfor %}
{% endif %}
{% endmacro %}
{% macro display_attachments(object) %} {% macro display_attachments(object) %}
{% if object.attachments and object.sensitive and not request.query_params.show_sensitive == object.permalink_id %} {% if object.attachments and object.sensitive and not request.query_params.show_sensitive == object.permalink_id %}
{{ sensitive_button(object.permalink_id )}} {{ sensitive_button(object.permalink_id )}}
@ -206,6 +226,8 @@
</div> </div>
{% endif %} {% endif %}
{{ display_og_meta(object) }}
<a href="{{ object.url }}" class="u-url u-uid"><time class="dt-published" datetime="{{ object.ap_published_at }}">{{ object.ap_published_at | format_date }}</time></a> <a href="{{ object.url }}" class="u-url u-uid"><time class="dt-published" datetime="{{ object.ap_published_at }}">{{ object.ap_published_at | format_date }}</time></a>
{{ object.visibility.value }} {{ object.visibility.value }}
{% if object.is_from_outbox %} {% if object.is_from_outbox %}
@ -248,8 +270,12 @@
</div> </div>
</div> </div>
<div style="padding-left:60px">
{{ display_og_meta(object) }}
</div>
<div class="activity-attachment"> <div class="activity-attachment">
{{ display_attachments(object) }}
{{ display_attachments(object) }}
</div> </div>
<div class="activity-bar"> <div class="activity-bar">

View file

@ -1,5 +1,6 @@
import mimetypes import mimetypes
import re import re
from typing import Any
from urllib.parse import urlparse from urllib.parse import urlparse
import httpx import httpx
@ -60,14 +61,16 @@ def _urls_from_note(note: ap.RawObject) -> set[str]:
return urls return urls
def _og_meta_from_url(url: str) -> OpenGraphMeta | None: async def _og_meta_from_url(url: str) -> OpenGraphMeta | None:
resp = httpx.get( async with httpx.AsyncClient() as client:
url, resp = await client.get(
headers={ url,
"User-Agent": config.USER_AGENT, headers={
}, "User-Agent": config.USER_AGENT,
follow_redirects=True, },
) follow_redirects=True,
)
resp.raise_for_status() resp.raise_for_status()
if not (ct := resp.headers.get("content-type")) or not ct.startswith("text/html"): 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) 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 = [] og_meta = []
urls = _urls_from_note(note) urls = _urls_from_note(note)
for url in urls: for url in urls:
try: try:
maybe_og_meta = _og_meta_from_url(url) maybe_og_meta = await _og_meta_from_url(url)
if maybe_og_meta: if maybe_og_meta:
og_meta.append(maybe_og_meta) og_meta.append(maybe_og_meta.dict())
except httpx.HTTPError: except httpx.HTTPError:
pass pass