Extract mentions from ActivityPub payload content

merge-requests/157/merge
Jason Robinson 2019-09-08 02:21:08 +03:00
rodzic 7e93dc3da3
commit c3fd773f78
5 zmienionych plików z 76 dodań i 6 usunięć

Wyświetl plik

@ -1,7 +1,7 @@
import logging
import re
import uuid
from typing import Dict, List
from typing import Dict, List, Set
from federation.entities.activitypub.constants import (
CONTEXTS_DEFAULT, CONTEXT_MANUALLY_APPROVES_FOLLOWERS, CONTEXT_SENSITIVE, CONTEXT_HASHTAG,
@ -109,6 +109,20 @@ class ActivitypubNoteMixin(AttachImagesMixin, CleanContentMixin, ActivitypubEnti
tags.append(_tag)
return tags
def extract_mentions(self) -> Set:
"""
Extract mentions from the source object.
"""
if not isinstance(self._source_object, dict):
return set()
_mentions = set()
source = self._source_object.get('object') if isinstance(self._source_object.get('object'), dict) else \
self._source_object
for tag in source.get('tag', []):
if tag.get('type') == "Mention" and tag.get('href'):
_mentions.add(tag.get('href'))
return _mentions
def to_as2(self) -> Dict:
as2 = {
"@context": CONTEXTS_DEFAULT + [

Wyświetl plik

@ -1,4 +1,5 @@
import re
from typing import Set
from Crypto.PublicKey import RSA
from lxml import etree
@ -14,7 +15,7 @@ class DiasporaEntityMixin(BaseEntity):
# Normally outbound document is generated from entity. Store one here if at some point we already have a doc
outbound_doc = None
def extract_mentions(self):
def extract_mentions(self) -> Set:
"""
Extract mentions from an entity with ``raw_content``.

Wyświetl plik

@ -1,7 +1,7 @@
import datetime
import importlib
import warnings
from typing import List, Set
from typing import List, Set, Union, Dict
from commonmark import commonmark
@ -16,7 +16,7 @@ class BaseEntity:
_receivers: List = None
_source_protocol: str = ""
# Contains the original object from payload as a string
_source_object: str = None
_source_object: Union[str, Dict] = None
_sender_key: str = ""
# ActivityType
activity: ActivityType = None
@ -50,7 +50,7 @@ class BaseEntity:
klass = getattr(entities, f"{protocol.title()}{self.__class__.__name__}")
return klass.from_base(self)
def extract_mentions(self):
def extract_mentions(self) -> Set:
return set()
def validate(self):
@ -178,10 +178,12 @@ class CreatedAtMixin(BaseEntity):
class RawContentMixin(BaseEntity):
_media_type: str = "text/markdown"
_mentions: List = None
_rendered_content: str = ""
raw_content: str = ""
def __init__(self, *args, **kwargs):
self._mentions = []
super().__init__(*args, **kwargs)
self._required += ["raw_content"]

Wyświetl plik

@ -11,7 +11,7 @@ from federation.tests.fixtures.payloads import (
ACTIVITYPUB_FOLLOW, ACTIVITYPUB_PROFILE, ACTIVITYPUB_PROFILE_INVALID, ACTIVITYPUB_UNDO_FOLLOW, ACTIVITYPUB_POST,
ACTIVITYPUB_COMMENT, ACTIVITYPUB_RETRACTION, ACTIVITYPUB_SHARE, ACTIVITYPUB_RETRACTION_SHARE,
ACTIVITYPUB_POST_IMAGES, ACTIVITYPUB_POST_WITH_SOURCE_MARKDOWN, ACTIVITYPUB_POST_WITH_TAGS,
ACTIVITYPUB_POST_WITH_SOURCE_BBCODE)
ACTIVITYPUB_POST_WITH_SOURCE_BBCODE, ACTIVITYPUB_POST_WITH_MENTIONS)
from federation.types import UserType, ReceiverVariant
@ -83,6 +83,15 @@ class TestActivitypubEntityMappersReceive:
assert isinstance(post, Post)
assert post.raw_content == 'boom #test'
def test_message_to_objects_simple_post__with_mentions(self):
entities = message_to_objects(ACTIVITYPUB_POST_WITH_MENTIONS, "https://mastodon.social/users/jaywink")
assert len(entities) == 1
post = entities[0]
assert isinstance(post, ActivitypubPost)
assert isinstance(post, Post)
assert len(post._mentions) == 1
assert list(post._mentions)[0] == "https://dev3.jasonrobinson.me/u/jaywink/"
def test_message_to_objects_simple_post__with_source__bbcode(self):
entities = message_to_objects(ACTIVITYPUB_POST_WITH_SOURCE_BBCODE, "https://diaspodon.fr/users/jaywink")
assert len(entities) == 1

Wyświetl plik

@ -341,6 +341,50 @@ ACTIVITYPUB_POST_WITH_TAGS = {
'signatureValue': 'SjDACS7Z/Cb1SEC3AtxEokID5SHAYl7kpys/hhmaRbpXuFKCxfj2P9BmH8QhLnuam3sENZlrnBOcB5NlcBhIfwo/Xh242RZBmPQf+edTVYVCe1j19dihcftNCHtnqAcKwp/51dNM/OlKu2730FrwvOUXVIPtB7iVqkseO9TRzDYIDj+zBTksnR/NAYtq6SUpmefXfON0uW3N3Uq6PGfExJaS+aeqRf8cPGkZFSIUQZwOLXbIpb7BFjJ1+y1OMOAJueqvikUprAit3v6BiNWurAvSQpC7WWMFUKyA79/xtkO9kIPA/Q4C9ryqdzxZJ0jDhXiaIIQj2JZfIADdjLZHJA=='}
}
ACTIVITYPUB_POST_WITH_MENTIONS = {'@context': ['https://www.w3.org/ns/activitystreams',
{'ostatus': 'http://ostatus.org#',
'atomUri': 'ostatus:atomUri',
'inReplyToAtomUri': 'ostatus:inReplyToAtomUri',
'conversation': 'ostatus:conversation',
'sensitive': 'as:sensitive'}],
'id': 'https://mastodon.social/users/jaywink/statuses/102750454691863505/activity',
'type': 'Create',
'actor': 'https://mastodon.social/users/jaywink',
'published': '2019-09-07T09:11:54Z',
'to': ['https://www.w3.org/ns/activitystreams#Public'],
'cc': ['https://mastodon.social/users/jaywink/followers',
'https://dev3.jasonrobinson.me/u/jaywink/'],
'object': {'id': 'https://mastodon.social/users/jaywink/statuses/102750454691863505',
'type': 'Note',
'summary': None,
'inReplyTo': None,
'published': '2019-09-07T09:11:54Z',
'url': 'https://mastodon.social/@jaywink/102750454691863505',
'attributedTo': 'https://mastodon.social/users/jaywink',
'to': ['https://www.w3.org/ns/activitystreams#Public'],
'cc': ['https://mastodon.social/users/jaywink/followers',
'https://dev3.jasonrobinson.me/u/jaywink/'],
'sensitive': False,
'atomUri': 'https://mastodon.social/users/jaywink/statuses/102750454691863505',
'inReplyToAtomUri': None,
'conversation': 'tag:mastodon.social,2019-09-07:objectId=123339599:objectType=Conversation',
'content': '<p><span class="h-card"><a href="https://dev3.jasonrobinson.me/u/jaywink/" class="u-url mention">@<span>jaywink</span></a></span> need a mention payload - here!</p>',
'contentMap': {'en': '<p><span class="h-card"><a href="https://dev3.jasonrobinson.me/u/jaywink/" class="u-url mention">@<span>jaywink</span></a></span> need a mention payload - here!</p>'},
'attachment': [],
'tag': [{'type': 'Mention',
'href': 'https://dev3.jasonrobinson.me/u/jaywink/',
'name': '@jaywink@dev3.jasonrobinson.me'}],
'replies': {'id': 'https://mastodon.social/users/jaywink/statuses/102750454691863505/replies',
'type': 'Collection',
'first': {'type': 'CollectionPage',
'next': 'https://mastodon.social/users/jaywink/statuses/102750454691863505/replies?only_other_accounts=true&page=true',
'partOf': 'https://mastodon.social/users/jaywink/statuses/102750454691863505/replies',
'items': []}}},
'signature': {'type': 'RsaSignature2017',
'creator': 'https://mastodon.social/users/jaywink#main-key',
'created': '2019-09-07T09:11:54Z',
'signatureValue': 'FOO'}}
ACTIVITYPUB_POST_WITH_SOURCE_MARKDOWN = {
'@context': ['https://www.w3.org/ns/activitystreams',
{'ostatus': 'http://ostatus.org#',