mirror of
				https://git.sr.ht/~tsileo/microblog.pub
				synced 2025-06-05 21:59:23 +02:00 
			
		
		
		
	Admin fixes and improved OG meta support
This commit is contained in:
		| @@ -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()) | ||||||
|             ) |             ) | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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, | ||||||
|   | |||||||
| @@ -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"> | ||||||
|   | |||||||
| @@ -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 | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user