Return images and summary in actor

This commit is contained in:
Andrew Godwin 2022-11-17 19:31:00 -07:00
parent 291d7e404e
commit 2a3690d1c1
8 changed files with 54 additions and 9 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
*.psql
*.sqlite3
.venv
/*.env
/media/
notes.md

View File

@ -20,12 +20,13 @@ def sanitize_post(post_html: str) -> str:
Only allows a, br, p and span tags, and class attributes.
"""
cleaner = bleach.Cleaner(
tags=["a", "br", "p", "span"],
tags=["br", "p"],
attributes={ # type:ignore
"a": allow_a,
"p": ["class"],
"span": ["class"],
},
filters=[LinkifyFilter],
strip=True,
)
return mark_safe(cleaner.clean(post_html))

View File

@ -1,4 +1,5 @@
import datetime
import os
import urllib.parse as urllib_parse
from typing import Dict, List, Optional, Union
@ -436,3 +437,19 @@ def parse_ld_date(value: Optional[str]) -> Optional[datetime.datetime]:
return datetime.datetime.strptime(value, DATETIME_FORMAT).replace(
tzinfo=datetime.timezone.utc
)
def media_type_from_filename(filename):
_, extension = os.path.splitext(filename)
if extension == ".png":
return "image/png"
elif extension in [".jpg", ".jpeg"]:
return "image/png"
elif extension == ".gif":
return "image/gif"
elif extension == ".apng":
return "image/apng"
elif extension == ".webp":
return "image/webp"
else:
return "application/octet-stream"

View File

@ -108,5 +108,7 @@ STATICFILES_DIRS = [
ALLOWED_HOSTS = ["*"]
MEDIA_ROOT = BASE_DIR / "media"
MEDIA_URL = "/media/"
# Note that this MUST be a fully qualified URL in production
MEDIA_URL = os.environ.get("TAKAHE_MEDIA_URL", "/media/")
MEDIA_ROOT = os.environ.get("TAKAHE_MEDIA_ROOT", BASE_DIR / "media")

View File

@ -1,5 +1,3 @@
import re
from django.conf import settings as djsettings
from django.contrib import admin as djadmin
from django.urls import path, re_path
@ -99,7 +97,7 @@ urlpatterns = [
path("djadmin/", djadmin.site.urls),
# Media files
re_path(
r"^%s(?P<path>.*)$" % re.escape(djsettings.MEDIA_URL.lstrip("/")),
r"^media/(?P<path>.*)$",
serve,
kwargs={"document_root": djsettings.MEDIA_ROOT},
),

View File

@ -2,7 +2,9 @@
{% load activity_tags %}
<div class="post" data-takahe-id="{{ post.id }}">
<img src="{{ post.author.local_icon_url }}" class="icon">
<a href="{{ post.author.urls.view }}">
<img src="{{ post.author.local_icon_url }}" class="icon">
</a>
<time>
{% if post.visibility == 0 %}

View File

@ -28,6 +28,12 @@
{{ identity.name_or_handle }} <small>@{{ identity.handle }}</small>
</h1>
{% if identity.summary %}
<div class="summary">
{{ identity.safe_summary }}
</div>
{% endif %}
{% if not identity.local %}
{% if identity.outdated and not identity.name %}
<p class="system-note">

View File

@ -8,10 +8,12 @@ from asgiref.sync import async_to_sync, sync_to_async
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from django.db import models
from django.template.defaultfilters import linebreaks_filter
from django.templatetags.static import static
from django.utils import timezone
from core.ld import canonicalise
from core.html import sanitize_post
from core.ld import canonicalise, media_type_from_filename
from core.uploads import upload_namer
from stator.models import State, StateField, StateGraph, StatorModel
from users.models.domain import Domain
@ -139,6 +141,10 @@ class Identity(StatorModel):
elif self.image_uri:
return self.image_uri
@property
def safe_summary(self):
return sanitize_post(self.summary)
### Alternate constructors/fetchers ###
@classmethod
@ -223,7 +229,19 @@ class Identity(StatorModel):
if self.name:
response["name"] = self.name
if self.summary:
response["summary"] = self.summary
response["summary"] = str(linebreaks_filter(self.summary))
if self.icon:
response["icon"] = {
"type": "Image",
"mediaType": media_type_from_filename(self.icon.name),
"url": self.icon.url,
}
if self.image:
response["image"] = {
"type": "Image",
"mediaType": media_type_from_filename(self.image.name),
"url": self.image.url,
}
return response
### ActivityPub (inbound) ###