Microformats support

main
Thomas Sileo 2022-06-26 21:54:07 +02:00
parent 33154b7e01
commit 9c41c68958
8 changed files with 66 additions and 12 deletions

View File

@ -6,6 +6,7 @@ from typing import Any
from urllib.parse import urlparse
import bleach
import html2text
import timeago # type: ignore
from bs4 import BeautifulSoup # type: ignore
from fastapi import Request
@ -32,6 +33,11 @@ from app.utils.highlight import highlight
_templates = Jinja2Templates(directory="app/templates")
H2T = html2text.HTML2Text()
H2T.ignore_links = True
H2T.ignore_images = True
def _filter_domain(text: str) -> str:
hostname = urlparse(text).hostname
if not hostname:
@ -219,6 +225,10 @@ def _replace_custom_emojis(content: str, note: Object) -> str:
return content
def _html2text(content: str) -> str:
return H2T.handle(content)
_templates.env.filters["domain"] = _filter_domain
_templates.env.filters["media_proxy_url"] = _media_proxy_url
_templates.env.filters["clean_html"] = _clean_html
@ -226,3 +236,4 @@ _templates.env.filters["timeago"] = _timeago
_templates.env.filters["format_date"] = _format_date
_templates.env.filters["has_media_type"] = _has_media_type
_templates.env.filters["pluralize"] = _pluralize
_templates.env.filters["html2text"] = _html2text

View File

@ -4,7 +4,7 @@
<data class="u-photo" value="{{ local_actor.icon_url }}"></data>
<a href="{{ local_actor.url }}" class="u-url u-uid no-hover title">
<span style="font-size:1.1em;">{{ local_actor.name }}</span>
<span style="font-size:0.85em;" class="subtitle-username">{{ local_actor.handle }}</span>
<span style="font-size:0.85em;" class="p-name subtitle-username">{{ local_actor.handle }}</span>
</a>
<div class="p-note summary">

View File

@ -1,11 +1,27 @@
{%- import "utils.html" as utils with context -%}
{% extends "layout.html" %}
{% block head %}
<link rel="alternate" href="{{ local_actor.url }}" title="ActivityPub profile" type="application/activity+json">
<meta content="profile" property="og:type" />
<meta content="{{ local_actor.url }}" property="og:url" />
<meta content="{{ local_actor.display_name }}'s microblog" property="og:site_name" />
<meta content="Homepage" property="og:title" />
<meta content="{{ local_actor.summary | html2text }}" property="og:description" />
<meta content="{{ local_actor.url }}" property="og:image" />
<meta content="summary" property="twitter:card" />
<meta content="{{ local_actor.handle }}" property="profile:username" />
{% endblock %}
{% block content %}
{% include "header.html" %}
<div class="h-feed">
<data class="p-name" value="{{ local_actor.display_name}}'s notes"></data>
{% for outbox_object in objects %}
{{ utils.display_object(outbox_object) }}
{% endfor %}
</div>
{% if has_previous_page %}
<a href="{{ url_for("index") }}?page={{ current_page - 1 }}">Previous</a>

View File

@ -8,6 +8,7 @@
<style>
{{ highlight_css }}
</style>
{% block head %}{% endblock %}
</head>
<body>
<div id="main">

View File

@ -1,5 +1,18 @@
{%- import "utils.html" as utils with context -%}
{% extends "layout.html" %}
{% block head %}
<link rel="alternate" href="{{ request.url }}" type="application/activity+json">
<meta name="description" content="{{ outbox_object.content | html2text | trim | truncate(50) }}">
<meta content="article" property="og:type" />
<meta content="{{ outbox_object.url }}" property="og:url" />
<meta content="{{ local_actor.display_name }}'s microblog" property="og:site_name" />
<meta content="Note" property="og:title" />
<meta content="{{ outbox_object.content | html2text | trim | truncate(50) }}" property="og:description" />
<meta content="{{ local_actor.icon_url }}" property="og:image" />
<meta content="summary" property="twitter:card" />
{% endblock %}
{% block content %}
{% include "header.html" %}

View File

@ -111,13 +111,13 @@
{% macro display_actor(actor, actors_metadata) %}
{% set metadata = actors_metadata.get(actor.ap_id) %}
<div style="display: flex;column-gap: 20px;margin:20px 0 10px 0;" class="actor-box">
<div style="display: flex;column-gap: 20px;margin:20px 0 10px 0;" class="actor-box h-card p-author">
<div style="flex: 0 0 48px;">
<img src="{{ actor.resized_icon_url }}" style="max-width:45px;">
</div>
<a href="{{ actor.url }}" style="">
<a href="{{ actor.url }}" class="u-url" style="">
<div><strong>{{ actor.display_name | clean_html(actor) | safe }}</strong></div>
<div>{{ actor.handle }}</div>
<div class="p-name">{{ actor.handle }}</div>
</a>
</div>
{% if is_admin and metadata %}
@ -145,15 +145,15 @@
{% macro display_object_expanded(object) %}
<div class="activity-expanded">
<div class="activity-expanded h-entry">
{{ display_actor(object.actor, {}) }}
<div>
<div class="e-content">
{{ object.content | clean_html(object) | safe }}
</div>
<a href="{{ object.url }}">{{ object.ap_published_at | format_date }}</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 }}
{% if object.is_from_outbox %}
{{ object.likes_count }} likes
@ -170,17 +170,17 @@
{% macro display_object(object) %}
{% if object.ap_type in ["Note", "Article", "Video"] %}
<div class="activity-wrap" id="{{ object.permalink_id }}">
<div class="activity-wrap h-entry" id="{{ object.permalink_id }}">
<div class="activity-content">
<img src="{{ object.actor.resized_icon_url }}" alt="" class="actor-icon">
<div class="activity-header">
<strong>{{ object.actor.display_name }}</strong>
<span>{{ object.actor.handle }}</span>
<a href="{{ object.actor.url}}" class="p-author h-card">{{ object.actor.handle }}</a>
<span class="activity-date" title="{{ object.ap_published_at.isoformat() }}">
{{ object.visibility.value }}
<a href="{{ object.url }}">{{ object.ap_published_at | timeago }}</a>
<a href="{{ object.url }}" class="u-url u-uid"><time class="dt-published" datetime="{{ object.ap_published_at }}">{{ object.ap_published_at | timeago }}</time></a>
</span>
<div class="activity-main">
<div class="activity-main e-content">
{{ object.content | clean_html(object) | safe }}
</div>
</div>

14
poetry.lock generated
View File

@ -315,6 +315,14 @@ category = "main"
optional = false
python-versions = ">=3.6"
[[package]]
name = "html2text"
version = "2020.1.16"
description = "Turn HTML into equivalent Markdown-structured text."
category = "main"
optional = false
python-versions = ">=3.5"
[[package]]
name = "html5lib"
version = "1.1"
@ -1046,7 +1054,7 @@ dev = ["pytest (>=4.6.2)", "black (>=19.3b0)"]
[metadata]
lock-version = "1.1"
python-versions = "^3.10"
content-hash = "2ac30190905e28cfb50e57e23142f0508522727ca7eca010904792c549501698"
content-hash = "ecb1ed5abd25037b2ba0154e079d813607ae59a29e9a6d544dc47c249d382af1"
[metadata.files]
alembic = [
@ -1283,6 +1291,10 @@ h11 = [
{file = "h11-0.12.0-py3-none-any.whl", hash = "sha256:36a3cb8c0a032f56e2da7084577878a035d3b61d104230d4bd49c0c6b555a9c6"},
{file = "h11-0.12.0.tar.gz", hash = "sha256:47222cb6067e4a307d535814917cd98fd0a57b6788ce715755fa2b6c28b56042"},
]
html2text = [
{file = "html2text-2020.1.16-py3-none-any.whl", hash = "sha256:c7c629882da0cf377d66f073329ccf34a12ed2adf0169b9285ae4e63ef54c82b"},
{file = "html2text-2020.1.16.tar.gz", hash = "sha256:e296318e16b059ddb97f7a8a1d6a5c1d7af4544049a01e261731d2d5cc277bbb"},
]
html5lib = [
{file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"},
{file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"},

View File

@ -34,6 +34,7 @@ loguru = "^0.6.0"
mdx-linkify = "^2.1"
Pillow = "^9.1.1"
blurhash-python = "^1.1.3"
html2text = "^2020.1.16"
[tool.poetry.dev-dependencies]
black = "^22.3.0"