From 626a165411e6ebf5000b1f86e00940483f838eff Mon Sep 17 00:00:00 2001 From: Thomas Sileo Date: Tue, 28 Jun 2022 21:10:22 +0200 Subject: [PATCH] Improved CW/sensitive support --- app/admin.py | 14 ++++++ app/ap_object.py | 4 ++ app/boxes.py | 19 ++++++-- app/templates/admin_inbox.html | 6 ++- app/templates/admin_new.html | 6 +++ app/templates/utils.html | 84 +++++++++++++++++++++------------- 6 files changed, 97 insertions(+), 36 deletions(-) diff --git a/app/admin.py b/app/admin.py index e2057b8..f1c0409 100644 --- a/app/admin.py +++ b/app/admin.py @@ -199,12 +199,22 @@ def admin_inbox( else None ) + actors_metadata = get_actors_metadata( + db, + [ + inbox_object.actor + for inbox_object in inbox + if inbox_object.ap_type == "Follow" + ], + ) + return templates.render_template( db, request, "admin_inbox.html", { "inbox": inbox, + "actors_metadata": actors_metadata, "next_cursor": next_cursor, }, ) @@ -475,6 +485,8 @@ def admin_actions_new( content: str = Form(), redirect_url: str = Form(), in_reply_to: str | None = Form(None), + content_warning: str | None = Form(None), + is_sensitive: bool = Form(False), visibility: str = Form(), csrf_check: None = Depends(verify_csrf_token), db: Session = Depends(get_db), @@ -491,6 +503,8 @@ def admin_actions_new( uploads=uploads, in_reply_to=in_reply_to or None, visibility=ap.VisibilityEnum[visibility], + content_warning=content_warning or None, + is_sensitive=True if content_warning else is_sensitive, ) return RedirectResponse( request.url_for("outbox_by_public_id", public_id=public_id), diff --git a/app/ap_object.py b/app/ap_object.py index 59d0187..5c2224c 100644 --- a/app/ap_object.py +++ b/app/ap_object.py @@ -131,6 +131,10 @@ class Object: return content + @property + def summary(self) -> str | None: + return self.ap_object.get("summary") + @property def permalink_id(self) -> str: return ( diff --git a/app/boxes.py b/app/boxes.py index 7f64723..a89e24d 100644 --- a/app/boxes.py +++ b/app/boxes.py @@ -231,6 +231,8 @@ def send_create( uploads: list[tuple[models.Upload, str]], in_reply_to: str | None, visibility: ap.VisibilityEnum, + content_warning: str | None = None, + is_sensitive: bool = False, ) -> str: note_id = allocate_outbox_id() published = now().replace(microsecond=0).isoformat().replace("+00:00", "Z") @@ -285,9 +287,9 @@ def send_create( "conversation": context, "url": outbox_object_id(note_id), "tag": tags, - "summary": None, + "summary": content_warning, "inReplyTo": in_reply_to, - "sensitive": False, + "sensitive": is_sensitive, "attachment": attachments, } outbox_object = save_outbox_object(db, note_id, note, source=source) @@ -550,10 +552,9 @@ def _handle_create_activity( def save_to_inbox(db: Session, raw_object: ap.RawObject) -> None: try: - actor = fetch_actor(db, raw_object["actor"]) + actor = fetch_actor(db, ap.get_id(raw_object["actor"])) except httpx.HTTPStatusError: logger.exception("Failed to fetch actor") - # XXX: Delete 410 when we never seen the actor return ap_published_at = now() @@ -561,6 +562,16 @@ def save_to_inbox(db: Session, raw_object: ap.RawObject) -> None: ap_published_at = isoparse(raw_object["published"]) ra = RemoteObject(ap.unwrap_activity(raw_object), actor=actor) + + if ( + db.query(models.InboxObject) + .filter(models.InboxObject.ap_id == ra.ap_id) + .count() + > 0 + ): + logger.info(f"Received duplicate {ra.ap_type} activity: {ra.ap_id}") + return + relates_to_inbox_object: models.InboxObject | None = None relates_to_outbox_object: models.OutboxObject | None = None if ra.activity_object_ap_id: diff --git a/app/templates/admin_inbox.html b/app/templates/admin_inbox.html index 632b3f1..d808ca2 100644 --- a/app/templates/admin_inbox.html +++ b/app/templates/admin_inbox.html @@ -10,7 +10,11 @@ {% elif inbox_object.ap_type in ["Article", "Note", "Video"] %} {{ utils.display_object(inbox_object) }} {% elif inbox_object.ap_type == "Follow" %} - {{ utils.display_object(inbox_object) }} +
+ {{ inbox_object.actor.display_name }} followed you + {{ inbox_object.ap_published_at | timeago }} +
+ {{ utils.display_actor(inbox_object.actor, actors_metadata) }} {% else %} Implement {{ inbox_object.ap_type }} {% endif %} diff --git a/app/templates/admin_new.html b/app/templates/admin_new.html index faa694f..0c3b49b 100644 --- a/app/templates/admin_new.html +++ b/app/templates/admin_new.html @@ -25,6 +25,12 @@ {% endfor %} +

+ +

+

+ +

diff --git a/app/templates/utils.html b/app/templates/utils.html index bd3cef6..61649c2 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -88,6 +88,17 @@ {% endmacro %} +{% macro show_more_button(permalink_id) %} +

+ +{% for k, v in request.query_params.items() %} + +{% endfor %} + +
+{% endmacro %} + + {% macro admin_reply_button(ap_object_id) %}
@@ -157,15 +168,43 @@ {% 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 )}} + {% endif %} + + {% if object.attachments and (not object.sensitive or (object.sensitive and request.query_params["show_sensitive"] == object.permalink_id)) %} + {% for attachment in object.attachments %} + {% if attachment.type == "Image" or (attachment | has_media_type("image")) %} + {{ attachment.name }} + {% elif attachment.type == "Video" or (attachment | has_media_type("video")) %} + + {% elif attachment.type == "Audio" or (attachment | has_media_type("audio")) %} + + {% else %} + {{ attachment.url }} + {% endif %} + {% endfor %} + {% endif %} +{% endmacro %} + {% macro display_object_expanded(object) %}
{{ display_actor(object.actor, {}) }} -
-{{ object.content | clean_html(object) | safe }} -
+{% if object.summary %} +

{{ object.summary | clean_html(object) | safe }}

+{% endif %} +{% if object.sensitive and object.summary and not request.query_params.show_more == object.permalink_id %} +{{ show_more_button(object.permalink_id) }} +{% endif %} +{% if not object.sensitive or (object.sensitive and object.summary and request.query_params.show_more == object.permalink_id) %} +
+ {{ object.content | clean_html(object) | safe }} +
+{% endif %} {{ object.visibility.value }} @@ -177,6 +216,7 @@ {{ object.announces_count }} shares {% endif %} +{{ display_attachments(object) }}
@@ -194,32 +234,24 @@ {{ object.visibility.value }} + {% if object.summary %} +

{{ object.summary | clean_html(object) | safe }}

+ {% endif %} + {% if object.sensitive and object.summary and not request.query_params.show_more == object.permalink_id %} + {{ show_more_button(object.permalink_id) }} + {% endif %} + {% if not object.sensitive or (object.sensitive and object.summary and request.query_params.show_more == object.permalink_id) %}
{{ object.content | clean_html(object) | safe }}
+ {% endif %} - {% if object.attachments and object.sensitive and not request.query_params["show_sensitive"] == object.permalink_id %} -
- {{ sensitive_button(object.permalink_id )}} -
- {% endif %} - {% if object.attachments and (not object.sensitive or (object.sensitive and request.query_params["show_sensitive"] == object.permalink_id)) %}
- {% for attachment in object.attachments %} - {% if attachment.type == "Image" or (attachment | has_media_type("image")) %} - {{ attachment.name }} - {% elif attachment.type == "Video" or (attachment | has_media_type("video")) %} - - {% elif attachment.type == "Audio" or (attachment | has_media_type("audio")) %} - - {% else %} - {{ attachment.url }} - {% endif %} - {% endfor %} + {{ display_attachments(object) }}
- {% endif %} +
{% if object.is_from_outbox %}
@@ -285,15 +317,5 @@
-{% elif object.ap_type == "Follow" %} - - {% if object.is_from_inbox %} -
- {{ object.actor.display_name }} followed you - {{ object.ap_published_at | timeago }} -
- {{ display_actor(object.actor, {}) }} - {% endif %} - {% endif %} {% endmacro %}