Return images and summary in actor
This commit is contained in:
		
							parent
							
								
									291d7e404e
								
							
						
					
					
						commit
						2a3690d1c1
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1,5 +1,6 @@
 | 
			
		||||
*.psql
 | 
			
		||||
*.sqlite3
 | 
			
		||||
.venv
 | 
			
		||||
/*.env
 | 
			
		||||
/media/
 | 
			
		||||
notes.md
 | 
			
		||||
 | 
			
		||||
@ -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))
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								core/ld.py
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								core/ld.py
									
									
									
									
									
								
							@ -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"
 | 
			
		||||
 | 
			
		||||
@ -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")
 | 
			
		||||
 | 
			
		||||
@ -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},
 | 
			
		||||
    ),
 | 
			
		||||
 | 
			
		||||
@ -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 %}
 | 
			
		||||
 | 
			
		||||
@ -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">
 | 
			
		||||
 | 
			
		||||
@ -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) ###
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user