Display Webmention as replies when applicable
This commit is contained in:
parent
ae8029cd22
commit
120f92a9ed
5 changed files with 124 additions and 6 deletions
|
@ -1,5 +1,6 @@
|
|||
import datetime
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
|
||||
from loguru import logger
|
||||
|
@ -7,7 +8,9 @@ from loguru import logger
|
|||
from app import media
|
||||
from app.models import InboxObject
|
||||
from app.models import Webmention
|
||||
from app.models import WebmentionType
|
||||
from app.utils.url import make_abs
|
||||
from app.utils.datetime import parse_isoformat
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -36,7 +39,9 @@ class Face:
|
|||
try:
|
||||
return cls(
|
||||
ap_actor_id=None,
|
||||
url=webmention.source,
|
||||
url=(
|
||||
item["properties"]["url"][0] if item["properties"].get("url") else webmention.source
|
||||
),
|
||||
name=item["properties"]["name"][0],
|
||||
picture_url=media.resized_media_url(
|
||||
make_abs(
|
||||
|
@ -81,3 +86,66 @@ def merge_faces(faces: list[Face]) -> list[Face]:
|
|||
key=lambda f: f.created_at,
|
||||
reverse=True,
|
||||
)[:10]
|
||||
|
||||
|
||||
def _parse_face(webmention: Webmention, items: list[dict[str, Any]]) -> Face | None:
|
||||
for item in items:
|
||||
if item["type"][0] == "h-card":
|
||||
try:
|
||||
return Face(
|
||||
ap_actor_id=None,
|
||||
url=(
|
||||
items["properties"]["url"][0] if item["properties"].get("url") else webmention.source
|
||||
),
|
||||
name=item["properties"]["name"][0],
|
||||
picture_url=media.resized_media_url(
|
||||
make_abs(
|
||||
item["properties"]["photo"][0], webmention.source
|
||||
), # type: ignore
|
||||
50,
|
||||
),
|
||||
created_at=webmention.created_at, # type: ignore
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
f"Failed to build Face for webmention id={webmention.id}"
|
||||
)
|
||||
break
|
||||
|
||||
|
||||
@dataclass
|
||||
class WebmentionReply:
|
||||
face: Face
|
||||
content: str
|
||||
url: str
|
||||
published_at: datetime.datetime
|
||||
|
||||
@classmethod
|
||||
def from_webmention(cls, webmention: Webmention) -> "WebmentionReply":
|
||||
if webmention.webmention_type != WebmentionType.REPLY:
|
||||
raise ValueError(f"Unexpected webmention {webmention.id}")
|
||||
|
||||
items = webmention.source_microformats.get("items", []) # type: ignore
|
||||
for item in items:
|
||||
if item["type"][0] == "h-entry":
|
||||
try:
|
||||
face = _parse_face(webmention, item["properties"].get("author", []))
|
||||
if not face:
|
||||
logger.info(
|
||||
"Failed to build WebmentionReply/Face for "
|
||||
f"webmention id={webmention.id}"
|
||||
)
|
||||
break
|
||||
return cls(
|
||||
face=face,
|
||||
content=item["properties"]["content"][0]["html"],
|
||||
url=item["properties"]["url"][0],
|
||||
published_at=parse_isoformat(
|
||||
item["properties"]["published"][0]
|
||||
).replace(tzinfo=None),
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
f"Failed to build Face for webmention id={webmention.id}"
|
||||
)
|
||||
break
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue