AP mention finding and marking now also relying on the url property which is expected to be set as the remote_url property of the client app profiles.

Add the url property to some tests.
The get_profile function now expected to OR the query fields.
ap-processing-improvements
Alain St-Denis 2023-07-23 08:50:40 -04:00
rodzic d53db6299f
commit d7e6a56eb6
4 zmienionych plików z 33 dodań i 23 usunięć

Wyświetl plik

@ -35,10 +35,10 @@ from federation.utils.text import with_slash, validate_handle
logger = logging.getLogger("federation")
def get_profile_or_entity(fid):
obj = get_profile(fid=fid)
if not obj:
obj = retrieve_and_parse_document(fid)
def get_profile_or_entity(**kwargs):
obj = get_profile(**kwargs)
if not obj and kwargs.get('fid'):
obj = retrieve_and_parse_document(kwargs['fid'])
return obj
@ -586,6 +586,7 @@ class Person(Object, base.Profile):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._required += ['url']
self._allowed_children += (Note, PropertyValue, IdentityProof)
# Set finger to username@host if not provided by the platform
@ -866,18 +867,22 @@ class Note(Object, RawContentMixin):
def _find_and_mark_mentions(self):
mentions = [mention for mention in self.tag_objects if isinstance(mention, Mention)]
hrefs = []
# There seems to be consensus on using the profile url for
# the link and the profile id for the Mention object href property,
# but some platforms will set mention.href to the profile url, so
# we check both.
for mention in mentions:
hrefs.append(mention.href)
# add Mastodon's form
parsed = urlparse(mention.href)
username = mention.name.lstrip('@').split('@')[0]
hrefs.append(f'{parsed.scheme}://{parsed.netloc}/@{username}')
for href in hrefs:
links = self._soup.find_all(href=href)
for link in links:
profile = get_profile_or_entity(fid=link['href'])
if profile:
hrefs = []
profile = get_profile_or_entity(fid=mention.href, remote_url=mention.href)
if profile and not profile.url:
# This should be removed when we are confident that the remote_url property
# has been populated for most profiles on the client app side.
profile = retrieve_and_parse_profile(profile.id)
if profile:
hrefs.extend([profile.id, profile.url])
for href in hrefs:
links = self._soup.find_all(href=href)
for link in links:
link['data-mention'] = profile.finger
self._mentions.add(profile.finger)
@ -1317,7 +1322,7 @@ def extract_receivers(entity):
profile = None
# don't care about receivers for payloads without an actor_id
if getattr(entity, 'actor_id'):
profile = get_profile_or_entity(entity.actor_id)
profile = get_profile_or_entity(fid=entity.actor_id)
if not isinstance(profile, base.Profile):
return receivers

Wyświetl plik

@ -91,7 +91,8 @@ class TestActivitypubEntityMappersReceive:
assert post.raw_content == ''
assert post.rendered_content == '<p>boom <a class="mention hashtag" data-hashtag="test" href="https://mastodon.social/tags/test" rel="tag">#<span>test</span></a></p>'
@patch("federation.entities.activitypub.models.get_profile_or_entity", return_value=Person(finger="jaywink@dev3.jasonrobinson.me"))
@patch("federation.entities.activitypub.models.get_profile_or_entity",
return_value=Person(finger="jaywink@dev3.jasonrobinson.me",url="https://dev3.jasonrobinson.me/u/jaywink/"))
def test_message_to_objects_simple_post__with_mentions(self, mock_get):
entities = message_to_objects(ACTIVITYPUB_POST_WITH_MENTIONS, "https://mastodon.social/users/jaywink")
assert len(entities) == 1
@ -102,7 +103,8 @@ class TestActivitypubEntityMappersReceive:
assert list(post._mentions)[0] == "jaywink@dev3.jasonrobinson.me"
@patch("federation.entities.activitypub.models.get_profile_or_entity", return_value=Person(finger="jaywink@dev.jasonrobinson.me"))
@patch("federation.entities.activitypub.models.get_profile_or_entity",
return_value=Person(finger="jaywink@dev.jasonrobinson.me",url="https://dev.jasonrobinson.me/u/jaywink/"))
def test_message_to_objects_simple_post__with_source__bbcode(self, mock_get):
entities = message_to_objects(ACTIVITYPUB_POST_WITH_SOURCE_BBCODE, "https://diaspodon.fr/users/jaywink")
assert len(entities) == 1
@ -113,7 +115,8 @@ class TestActivitypubEntityMappersReceive:
'@<span>jaywink</span></a></span> boom</p>'
assert post.raw_content == ''
@patch("federation.entities.activitypub.models.get_profile_or_entity", return_value=Person(finger="jaywink@dev.jasonrobinson.me"))
@patch("federation.entities.activitypub.models.get_profile_or_entity",
return_value=Person(finger="jaywink@dev.jasonrobinson.me",url="https://dev.robinson.me/u/jaywink/"))
def test_message_to_objects_simple_post__with_source__markdown(self, mock_get):
entities = message_to_objects(ACTIVITYPUB_POST_WITH_SOURCE_MARKDOWN, "https://diaspodon.fr/users/jaywink")
assert len(entities) == 1
@ -147,7 +150,8 @@ class TestActivitypubEntityMappersReceive:
assert photo.guid == ""
assert photo.handle == ""
@patch("federation.entities.activitypub.models.get_profile_or_entity", return_value=Person(finger="jaywink@dev.jasonrobinson.me"))
@patch("federation.entities.activitypub.models.get_profile_or_entity",
return_value=Person(finger="jaywink@dev.jasonrobinson.me", url="https://dev.jasonrobinson.me/u/jaywink/"))
def test_message_to_objects_comment(self, mock_get):
entities = message_to_objects(ACTIVITYPUB_COMMENT, "https://diaspodon.fr/users/jaywink")
assert len(entities) == 1

Wyświetl plik

@ -256,7 +256,8 @@ def profile():
inboxes={
"private": "https://example.com/bob/private",
"public": "https://example.com/public",
}, public_key=PUBKEY, to=["https://www.w3.org/ns/activitystreams#Public"]
}, public_key=PUBKEY, to=["https://www.w3.org/ns/activitystreams#Public"],
url="https://example.com/alice"
)

Wyświetl plik

@ -60,7 +60,7 @@ class TestRetrieveAndParseDocument:
entity = retrieve_and_parse_document("https://example.com/foobar")
assert isinstance(entity, Follow)
@patch("federation.entities.activitypub.models.extract_receivers", return_value=[])
@patch("federation.entities.activitypub.models.get_profile_or_entity", return_value=None)
@patch("federation.utils.activitypub.fetch_document", autospec=True, return_value=(
json.dumps(ACTIVITYPUB_POST_OBJECT), None, None),
)
@ -80,7 +80,7 @@ class TestRetrieveAndParseDocument:
"/foobar.jpg"
@patch("federation.entities.activitypub.models.verify_ld_signature", return_value=None)
@patch("federation.entities.activitypub.models.extract_receivers", return_value=[])
@patch("federation.entities.activitypub.models.get_profile_or_entity", return_value=None)
@patch("federation.utils.activitypub.fetch_document", autospec=True, return_value=(
json.dumps(ACTIVITYPUB_POST), None, None),
)