Post-process status.content field to change hashtag URLs
Since the status content already contains rendered HTML when we receive an ActivityPub inbox message it contains links to the mentioned hashtags on the originating instance. To fix this on the receiving instance we need to post-process the status content after successfully storing the status and its many-to-many fields (the one we're is the `mention_hashtags`). Post-processing means that we run a regex against the content to find the anchor tags linking to the originating hashtag and replace the `href` attribute with the URL to the hashtag page on the receiving (local) instance.
This commit is contained in:
parent
0fd49d2aea
commit
276b255f32
2 changed files with 106 additions and 2 deletions
|
@ -1,9 +1,12 @@
|
|||
""" note serializer and children thereof """
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Dict, List
|
||||
from django.apps import apps
|
||||
import re
|
||||
|
||||
from .base_activity import ActivityObject, Link
|
||||
from django.apps import apps
|
||||
from django.db import IntegrityError, transaction
|
||||
|
||||
from .base_activity import ActivityObject, ActivitySerializerError, Link
|
||||
from .image import Document
|
||||
|
||||
|
||||
|
@ -38,6 +41,46 @@ class Note(ActivityObject):
|
|||
updated: str = None
|
||||
type: str = "Note"
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
def to_model(
|
||||
self,
|
||||
model=None,
|
||||
instance=None,
|
||||
allow_create=True,
|
||||
save=True,
|
||||
overwrite=True,
|
||||
allow_external_connections=True,
|
||||
):
|
||||
instance = super().to_model(
|
||||
model, instance, allow_create, save, overwrite, allow_external_connections
|
||||
)
|
||||
|
||||
if instance is None:
|
||||
return instance
|
||||
|
||||
# Replace links to hashtags in content with local URLs
|
||||
changed_content = False
|
||||
for hashtag in instance.mention_hashtags.all():
|
||||
updated_content = re.sub(
|
||||
rf'(<a href=")[^"]*/hashtag/[^"]*(">{hashtag.name}</a>)',
|
||||
rf"\1{hashtag.remote_id}\2",
|
||||
instance.content,
|
||||
)
|
||||
if instance.content != updated_content:
|
||||
instance.content = updated_content
|
||||
changed_content = True
|
||||
|
||||
if not save or not changed_content:
|
||||
return instance
|
||||
|
||||
with transaction.atomic():
|
||||
try:
|
||||
instance.save(broadcast=False, update_fields=["content"])
|
||||
except IntegrityError as e:
|
||||
raise ActivitySerializerError(e)
|
||||
|
||||
return instance
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class Article(Note):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue