Support parsing Comment entities for incoming ActivityPub payloads

Basically a Note with an inReplyTo.
merge-requests/148/head
Jason Robinson 2019-06-30 01:02:27 +03:00
rodzic 471d40f05e
commit a333f7a9aa
4 zmienionych plików z 83 dodań i 26 usunięć

Wyświetl plik

@ -10,7 +10,7 @@ from federation.entities.activitypub.constants import (
from federation.entities.activitypub.enums import ActorType, ObjectType, ActivityType
from federation.entities.activitypub.mixins import ActivitypubObjectMixin, ActivitypubActorMixin
from federation.entities.activitypub.objects import ImageObject
from federation.entities.base import Profile, Post, Follow, Accept
from federation.entities.base import Profile, Post, Follow, Accept, Comment
from federation.outbound import handle_send
from federation.types import UserType
from federation.utils.text import with_slash
@ -138,6 +138,13 @@ class ActivitypubPost(ActivitypubObjectMixin, Post):
return as2
class ActivitypubComment(ActivitypubPost, Comment):
def to_as2(self) -> Dict:
as2 = super().to_as2()
as2["object"]["inReplyTo"] = self.target_id
return as2
class ActivitypubProfile(ActivitypubActorMixin, Profile):
_type = ActorType.PERSON.value
public = True

Wyświetl plik

@ -3,7 +3,7 @@ from typing import List, Callable, Dict, Union
from federation.entities.activitypub.constants import NAMESPACE_PUBLIC
from federation.entities.activitypub.entities import (
ActivitypubFollow, ActivitypubProfile, ActivitypubAccept, ActivitypubPost)
ActivitypubFollow, ActivitypubProfile, ActivitypubAccept, ActivitypubPost, ActivitypubComment)
from federation.entities.base import Follow, Profile, Accept, Post
from federation.entities.mixins import BaseEntity
from federation.types import UserType
@ -28,10 +28,12 @@ def element_to_objects(payload: Dict) -> List:
"""
entities = []
if isinstance(payload.get('object'), dict) and payload["object"].get('type'):
as2_type = payload["object"]["type"]
if payload["object"]["type"] == "Note" and payload["object"].get("inReplyTo"):
cls = ActivitypubComment
else:
as2_type = payload.get('type')
cls = MAPPINGS.get(as2_type)
cls = MAPPINGS.get(payload["object"]["type"])
else:
cls = MAPPINGS.get(payload.get('type'))
if not cls:
return []
@ -151,6 +153,8 @@ def transform_attribute(key: str, value: Union[str, Dict, int], transformed: Dic
transformed["inboxes"]["private"] = value
if not transformed["inboxes"]["public"]:
transformed["inboxes"]["public"] = value
elif key == "inReplyTo":
transformed["target_id"] = value
elif key == "name":
transformed["name"] = value
elif key == "object":

Wyświetl plik

@ -3,11 +3,12 @@ from unittest.mock import patch
import pytest
from federation.entities.activitypub.entities import (
ActivitypubFollow, ActivitypubAccept, ActivitypubProfile, ActivitypubPost)
ActivitypubFollow, ActivitypubAccept, ActivitypubProfile, ActivitypubPost, ActivitypubComment)
from federation.entities.activitypub.mappers import message_to_objects, get_outbound_entity
from federation.entities.base import Accept, Follow, Profile, Post
from federation.entities.base import Accept, Follow, Profile, Post, Comment
from federation.tests.fixtures.payloads import (
ACTIVITYPUB_FOLLOW, ACTIVITYPUB_PROFILE, ACTIVITYPUB_PROFILE_INVALID, ACTIVITYPUB_UNDO_FOLLOW, ACTIVITYPUB_POST)
ACTIVITYPUB_FOLLOW, ACTIVITYPUB_PROFILE, ACTIVITYPUB_PROFILE_INVALID, ACTIVITYPUB_UNDO_FOLLOW, ACTIVITYPUB_POST,
ACTIVITYPUB_COMMENT)
class TestActivitypubEntityMappersReceive:
@ -53,7 +54,8 @@ class TestActivitypubEntityMappersReceive:
'class="u-url mention">@<span>jaywink</span></a></span> boom</p>'
assert post.id == "https://diaspodon.fr/users/jaywink/statuses/102356911717767237"
assert post.actor_id == "https://diaspodon.fr/users/jaywink"
assert post.public == True
assert post.public is True
assert getattr(post, "target_id", None) is None
@pytest.mark.skip
def test_message_to_objects_post_with_photos(self):
@ -75,24 +77,18 @@ class TestActivitypubEntityMappersReceive:
assert photo.public == False
assert photo.created_at == datetime(2011, 7, 20, 1, 36, 7)
@pytest.mark.skip
def test_message_to_objects_comment(self, mock_validate):
entities = message_to_objects(DIASPORA_POST_COMMENT, "alice@alice.diaspora.example.org",
sender_key_fetcher=Mock())
def test_message_to_objects_comment(self):
entities = message_to_objects(ACTIVITYPUB_COMMENT, "https://diaspodon.fr/users/jaywink")
assert len(entities) == 1
comment = entities[0]
assert isinstance(comment, DiasporaComment)
assert isinstance(comment, ActivitypubComment)
assert isinstance(comment, Comment)
assert comment.target_guid == "((parent_guidparent_guidparent_guidparent_guid))"
assert comment.guid == "((guidguidguidguidguidguid))"
assert comment.handle == "alice@alice.diaspora.example.org"
assert comment.participation == "comment"
assert comment.raw_content == "((text))"
assert comment.signature == "((signature))"
assert comment._xml_tags == [
"guid", "parent_guid", "text", "author",
]
mock_validate.assert_called_once_with()
assert comment.raw_content == '<p><span class="h-card"><a href="https://dev.jasonrobinson.me/u/jaywink/" ' \
'class="u-url mention">@<span>jaywink</span></a></span> boom</p>'
assert comment.id == "https://diaspodon.fr/users/jaywink/statuses/102356911717767237"
assert comment.actor_id == "https://diaspodon.fr/users/jaywink"
assert comment.public is True
assert comment.target_id == "https://dev.jasonrobinson.me/content/653bad70-41b3-42c9-89cb-c4ee587e68e4/"
@pytest.mark.skip
def test_message_to_objects_like(self, mock_validate):

Wyświetl plik

@ -1,3 +1,53 @@
ACTIVITYPUB_COMMENT = {
'@context': ['https://www.w3.org/ns/activitystreams',
{'ostatus': 'http://ostatus.org#',
'atomUri': 'ostatus:atomUri',
'inReplyToAtomUri': 'ostatus:inReplyToAtomUri',
'conversation': 'ostatus:conversation',
'sensitive': 'as:sensitive',
'Hashtag': 'as:Hashtag',
'toot': 'http://joinmastodon.org/ns#',
'Emoji': 'toot:Emoji',
'focalPoint': {'@container': '@list', '@id': 'toot:focalPoint'},
'blurhash': 'toot:blurhash'}],
'id': 'https://diaspodon.fr/users/jaywink/statuses/102356911717767237/activity',
'type': 'Create',
'actor': 'https://diaspodon.fr/users/jaywink',
'published': '2019-06-29T21:08:45Z',
'to': ['https://www.w3.org/ns/activitystreams#Public'],
'cc': ['https://diaspodon.fr/users/jaywink/followers',
'https://dev.jasonrobinson.me/p/d4574854-a5d7-42be-bfac-f70c16fcaa97/'],
'object': {'id': 'https://diaspodon.fr/users/jaywink/statuses/102356911717767237',
'type': 'Note',
'summary': None,
'inReplyTo': 'https://dev.jasonrobinson.me/content/653bad70-41b3-42c9-89cb-c4ee587e68e4/',
'published': '2019-06-29T21:08:45Z',
'url': 'https://diaspodon.fr/@jaywink/102356911717767237',
'attributedTo': 'https://diaspodon.fr/users/jaywink',
'to': ['https://www.w3.org/ns/activitystreams#Public'],
'cc': ['https://diaspodon.fr/users/jaywink/followers',
'https://dev.jasonrobinson.me/p/d4574854-a5d7-42be-bfac-f70c16fcaa97/'],
'sensitive': False,
'atomUri': 'https://diaspodon.fr/users/jaywink/statuses/102356911717767237',
'inReplyToAtomUri': 'https://dev.jasonrobinson.me/content/653bad70-41b3-42c9-89cb-c4ee587e68e4/',
'conversation': 'tag:diaspodon.fr,2019-06-28:objectId=2347687:objectType=Conversation',
'content': '<p><span class="h-card"><a href="https://dev.jasonrobinson.me/u/jaywink/" class="u-url mention">@<span>jaywink</span></a></span> boom</p>',
'contentMap': {'en': '<p><span class="h-card"><a href="https://dev.jasonrobinson.me/u/jaywink/" class="u-url mention">@<span>jaywink</span></a></span> boom</p>'},
'attachment': [],
'tag': [{'type': 'Mention',
'href': 'https://dev.jasonrobinson.me/p/d4574854-a5d7-42be-bfac-f70c16fcaa97/',
'name': '@jaywink@dev.jasonrobinson.me'}],
'replies': {'id': 'https://diaspodon.fr/users/jaywink/statuses/102356911717767237/replies',
'type': 'Collection',
'first': {'type': 'CollectionPage',
'partOf': 'https://diaspodon.fr/users/jaywink/statuses/102356911717767237/replies',
'items': []}}},
'signature': {'type': 'RsaSignature2017',
'creator': 'https://diaspodon.fr/users/jaywink#main-key',
'created': '2019-06-29T21:08:45Z',
'signatureValue': 'SjDACS7Z/Cb1SEC3AtxEokID5SHAYl7kpys/hhmaRbpXuFKCxfj2P9BmH8QhLnuam3sENZlrnBOcB5NlcBhIfwo/Xh242RZBmPQf+edTVYVCe1j19dihcftNCHtnqAcKwp/51dNM/OlKu2730FrwvOUXVIPtB7iVqkseO9TRzDYIDj+zBTksnR/NAYtq6SUpmefXfON0uW3N3Uq6PGfExJaS+aeqRf8cPGkZFSIUQZwOLXbIpb7BFjJ1+y1OMOAJueqvikUprAit3v6BiNWurAvSQpC7WWMFUKyA79/xtkO9kIPA/Q4C9ryqdzxZJ0jDhXiaIIQj2JZfIADdjLZHJA=='}
}
ACTIVITYPUB_FOLLOW = {
"@context": [
"https://www.w3.org/ns/activitystreams",
@ -132,7 +182,7 @@ ACTIVITYPUB_POST = {
'object': {'id': 'https://diaspodon.fr/users/jaywink/statuses/102356911717767237',
'type': 'Note',
'summary': None,
'inReplyTo': 'https://dev.jasonrobinson.me/content/653bad70-41b3-42c9-89cb-c4ee587e68e4/',
'inReplyTo': None,
'published': '2019-06-29T21:08:45Z',
'url': 'https://diaspodon.fr/@jaywink/102356911717767237',
'attributedTo': 'https://diaspodon.fr/users/jaywink',
@ -141,7 +191,7 @@ ACTIVITYPUB_POST = {
'https://dev.jasonrobinson.me/p/d4574854-a5d7-42be-bfac-f70c16fcaa97/'],
'sensitive': False,
'atomUri': 'https://diaspodon.fr/users/jaywink/statuses/102356911717767237',
'inReplyToAtomUri': 'https://dev.jasonrobinson.me/content/653bad70-41b3-42c9-89cb-c4ee587e68e4/',
'inReplyToAtomUri': None,
'conversation': 'tag:diaspodon.fr,2019-06-28:objectId=2347687:objectType=Conversation',
'content': '<p><span class="h-card"><a href="https://dev.jasonrobinson.me/u/jaywink/" class="u-url mention">@<span>jaywink</span></a></span> boom</p>',
'contentMap': {'en': '<p><span class="h-card"><a href="https://dev.jasonrobinson.me/u/jaywink/" class="u-url mention">@<span>jaywink</span></a></span> boom</p>'},