kopia lustrzana https://gitlab.com/jaywink/federation
Attach mentions in ActivityPub outgoing payloads
Any mentions given in the _mentions list or found in the raw_content are attached as Mention tags before sending. https://git.feneas.org/socialhome/socialhome/issues/522merge-requests/157/merge
rodzic
c5297fd940
commit
8d2bc74556
|
@ -1,7 +1,7 @@
|
|||
import logging
|
||||
import re
|
||||
import uuid
|
||||
from typing import Dict, List, Set
|
||||
from typing import Dict, List
|
||||
|
||||
from federation.entities.activitypub.constants import (
|
||||
CONTEXTS_DEFAULT, CONTEXT_MANUALLY_APPROVES_FOLLOWERS, CONTEXT_SENSITIVE, CONTEXT_HASHTAG,
|
||||
|
@ -13,7 +13,7 @@ from federation.entities.utils import get_base_attributes
|
|||
from federation.outbound import handle_send
|
||||
from federation.types import UserType
|
||||
from federation.utils.django import get_configuration
|
||||
from federation.utils.text import with_slash
|
||||
from federation.utils.text import with_slash, validate_handle
|
||||
|
||||
logger = logging.getLogger("federation")
|
||||
|
||||
|
@ -23,6 +23,7 @@ class AttachImagesMixin(RawContentMixin):
|
|||
"""
|
||||
Attach any embedded images from raw_content.
|
||||
"""
|
||||
super().pre_send()
|
||||
if self._media_type != "text/markdown":
|
||||
return
|
||||
regex = r"!\[([\w ]*)\]\((https?://[\w\d\-\./]+\.[\w]*((?<=jpg)|(?<=gif)|(?<=png)|(?<=jpeg)))\)"
|
||||
|
@ -59,6 +60,7 @@ class CleanContentMixin(RawContentMixin):
|
|||
def cleaner(match):
|
||||
return f"#{match.groups()[0]}"
|
||||
|
||||
super().post_receive()
|
||||
self.raw_content = re.sub(
|
||||
r'\[#([\w\-_]+)\]\(http?s://[a-zA-Z0-9/._-]+\)',
|
||||
cleaner,
|
||||
|
@ -122,6 +124,10 @@ class ActivitypubNoteMixin(AttachImagesMixin, CleanContentMixin, ActivitypubEnti
|
|||
if tag.get('type') == "Mention" and tag.get('href'):
|
||||
self._mentions.add(tag.get('href'))
|
||||
|
||||
def pre_send(self):
|
||||
super().pre_send()
|
||||
self.extract_mentions()
|
||||
|
||||
def to_as2(self) -> Dict:
|
||||
as2 = {
|
||||
"@context": CONTEXTS_DEFAULT + [
|
||||
|
@ -146,15 +152,35 @@ class ActivitypubNoteMixin(AttachImagesMixin, CleanContentMixin, ActivitypubEnti
|
|||
'content': self.raw_content,
|
||||
'mediaType': self._media_type,
|
||||
},
|
||||
"tag": [],
|
||||
},
|
||||
"published": self.created_at.isoformat(),
|
||||
}
|
||||
|
||||
if len(self._children):
|
||||
as2["object"]["attachment"] = []
|
||||
for child in self._children:
|
||||
as2["object"]["attachment"].append(child.to_as2())
|
||||
|
||||
as2["object"]["tag"] = self.add_object_tags()
|
||||
if len(self._mentions):
|
||||
mentions = list(self._mentions)
|
||||
mentions.sort()
|
||||
for mention in mentions:
|
||||
if mention.startswith("http"):
|
||||
as2["object"]["tag"].append({
|
||||
'type': 'Mention',
|
||||
'href': mention,
|
||||
'name': mention,
|
||||
})
|
||||
elif validate_handle(mention):
|
||||
# Look up via WebFinger
|
||||
as2["object"]["tag"].append({
|
||||
'type': 'Mention',
|
||||
'href': mention, # TODO need to implement fetch via webfinger for AP handles first
|
||||
'name': mention,
|
||||
})
|
||||
|
||||
as2["object"]["tag"].extend(self.add_object_tags())
|
||||
return as2
|
||||
|
||||
|
||||
|
@ -172,6 +198,7 @@ class ActivitypubFollow(ActivitypubEntityMixin, Follow):
|
|||
"""
|
||||
Post receive hook - send back follow ack.
|
||||
"""
|
||||
super().post_receive()
|
||||
if not self.following:
|
||||
return
|
||||
|
||||
|
|
|
@ -51,6 +51,18 @@ class BaseEntity:
|
|||
klass = getattr(entities, f"{protocol.title()}{self.__class__.__name__}")
|
||||
return klass.from_base(self)
|
||||
|
||||
def post_receive(self):
|
||||
"""
|
||||
Run any actions after deserializing the payload into an entity.
|
||||
"""
|
||||
pass
|
||||
|
||||
def pre_send(self):
|
||||
"""
|
||||
Run any actions before serializing the entity for sending.
|
||||
"""
|
||||
pass
|
||||
|
||||
def validate(self):
|
||||
"""Do validation.
|
||||
|
||||
|
|
|
@ -127,6 +127,56 @@ class TestEntitiesConvertToAS2:
|
|||
'published': '2019-04-27T00:00:00',
|
||||
}
|
||||
|
||||
def test_post_to_as2__with_mentions(self, activitypubpost_mentions):
|
||||
activitypubpost_mentions.pre_send()
|
||||
result = activitypubpost_mentions.to_as2()
|
||||
assert result == {
|
||||
'@context': [
|
||||
'https://www.w3.org/ns/activitystreams',
|
||||
{"pyfed": "https://docs.jasonrobinson.me/ns/python-federation"},
|
||||
{'Hashtag': 'as:Hashtag'},
|
||||
'https://w3id.org/security/v1',
|
||||
{'sensitive': 'as:sensitive'},
|
||||
],
|
||||
'type': 'Create',
|
||||
'id': 'http://127.0.0.1:8000/post/123456/#create',
|
||||
'actor': 'http://127.0.0.1:8000/profile/123456/',
|
||||
'object': {
|
||||
'id': 'http://127.0.0.1:8000/post/123456/',
|
||||
'type': 'Note',
|
||||
'attributedTo': 'http://127.0.0.1:8000/profile/123456/',
|
||||
'content': """<h1>raw_content</h1>
|
||||
<p>@{someone@localhost.local}</p>""",
|
||||
'published': '2019-04-27T00:00:00',
|
||||
'inReplyTo': None,
|
||||
'sensitive': False,
|
||||
'summary': None,
|
||||
'tag': [
|
||||
{
|
||||
"type": "Mention",
|
||||
"href": "http://127.0.0.1:8000/profile/999999",
|
||||
"name": "http://127.0.0.1:8000/profile/999999",
|
||||
},
|
||||
{
|
||||
"type": "Mention",
|
||||
"href": "jaywink@localhost.local",
|
||||
"name": "jaywink@localhost.local",
|
||||
},
|
||||
{
|
||||
"type": "Mention",
|
||||
"href": "someone@localhost.local",
|
||||
"name": "someone@localhost.local",
|
||||
},
|
||||
],
|
||||
'url': '',
|
||||
'source': {
|
||||
'content': '# raw_content\n\n@{someone@localhost.local}',
|
||||
'mediaType': 'text/markdown',
|
||||
},
|
||||
},
|
||||
'published': '2019-04-27T00:00:00',
|
||||
}
|
||||
|
||||
def test_post_to_as2__with_tags(self, activitypubpost_tags):
|
||||
result = activitypubpost_tags.to_as2()
|
||||
assert result == {
|
||||
|
|
|
@ -87,6 +87,23 @@ def activitypubpost_images():
|
|||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def activitypubpost_mentions():
|
||||
with freeze_time("2019-04-27"):
|
||||
return ActivitypubPost(
|
||||
raw_content="""# raw_content\n\n@{someone@localhost.local}""",
|
||||
public=True,
|
||||
provider_display_name="Socialhome",
|
||||
id=f"http://127.0.0.1:8000/post/123456/",
|
||||
activity_id=f"http://127.0.0.1:8000/post/123456/#create",
|
||||
actor_id=f"http://127.0.0.1:8000/profile/123456/",
|
||||
_mentions={
|
||||
"http://127.0.0.1:8000/profile/999999",
|
||||
"jaywink@localhost.local",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def activitypubpost_tags():
|
||||
with freeze_time("2019-04-27"):
|
||||
|
|
Ładowanie…
Reference in New Issue