Entities with a `raw_content` field now have URL syntax mentions rendered into a link

If Django is configured, a profile will be retrieved using the configured profile
getter function and the profile name or username will be used for the link.

Refs: https://git.feneas.org/socialhome/socialhome/issues/572
merge-requests/159/merge
Jason Robinson 2020-01-18 01:39:44 +02:00
rodzic 4c665e8743
commit c479a42d47
6 zmienionych plików z 52 dodań i 6 usunięć

Wyświetl plik

@ -2,6 +2,13 @@
## [0.20.0-dev] - unreleased
### Added
* Entities with a `raw_content` field now have URL syntax mentions rendered into a link. ([related issue](https://git.feneas.org/socialhome/socialhome/issues/572))
If Django is configured, a profile will be retrieved using the configured profile
getter function and the profile name or username will be used for the link.
### Changed
* The NodeInfo2 hostmeta parser now cleans the port out of the host name.

Wyświetl plik

@ -218,7 +218,7 @@ Some settings need to be set in Django settings. An example is below:
* ``base_url`` is the base URL of the server, ie protocol://domain.tld.
* ``get_object_function`` should be the full path to a function that will return the object matching the ActivityPub ID for the request object passed to this function.
* ``get_private_key_function`` should be the full path to a function that will accept a federation ID (url, handle or guid) and return the private key of the user (as an RSA object). Required for example to sign outbound messages in some cases.
* ``get_profile_function`` should be the full path to a function that should return a ``Profile`` entity. The function should take the following parameters: ``handle``, ``guid`` and ``request``. It should look up a profile with one or more of the provided parameters.
* ``get_profile_function`` should be the full path to a function that should return a ``Profile`` entity. The function should take one or more of following parameters: ``fid``, ``handle``, ``guid`` or ``request``. It should look up a profile with one or more of the provided parameters.
* ``nodeinfo2_function`` (optional) function that returns data for generating a `NodeInfo2 document <https://github.com/jaywink/nodeinfo2>`_. Once configured the path ``/.well-known/x-nodeinfo2`` will automatically generate a NodeInfo2 document. The function should return a ``dict`` corresponding to the NodeInfo2 schema, with the following minimum items:
::

Wyświetl plik

@ -7,9 +7,9 @@ from typing import List, Set, Union, Dict
from commonmark import commonmark
from federation.entities.activitypub.enums import ActivityType
from federation.entities.utils import get_name_for_profile
# TODO someday, rewrite entities as dataclasses or attr's
class BaseEntity:
_allowed_children: tuple = ()
_children: List = None
@ -206,7 +206,17 @@ class RawContentMixin(BaseEntity):
if self._rendered_content:
return self._rendered_content
elif self._media_type == "text/markdown" and self.raw_content:
return commonmark(self.raw_content).strip()
rendered = commonmark(self.raw_content).strip()
if self._mentions:
for mention in self._mentions:
# Only linkify mentions that are URL's
if not mention.startswith("http"):
continue
display_name = get_name_for_profile(mention)
if not display_name:
display_name = mention
rendered = rendered.replace("@{%s}" % mention, f'@<a href="{mention}">{display_name}</a>')
return rendered
return self.raw_content
@property

Wyświetl plik

@ -1,4 +1,5 @@
import inspect
from typing import Optional
def get_base_attributes(entity):
@ -13,3 +14,25 @@ def get_base_attributes(entity):
if not attr.startswith("_"):
attributes[attr] = getattr(entity, attr)
return attributes
def get_name_for_profile(fid: str) -> Optional[str]:
"""
Get a profile display name from a profile via the configured profile getter.
Currently only works with Django configuration.
"""
try:
from federation.utils.django import get_function_from_config
profile_func = get_function_from_config("get_profile_function")
if not profile_func:
return
profile = profile_func(fid)
if not profile:
return
if profile.name == fid and profile.username:
return profile.username
else:
return profile.name
except ImportError:
pass

Wyświetl plik

@ -146,7 +146,7 @@ class TestEntitiesConvertToAS2:
'type': 'Note',
'attributedTo': 'http://127.0.0.1:8000/profile/123456/',
'content': """<h1>raw_content</h1>
<p>@{someone@localhost.local}</p>""",
<p>@{someone@localhost.local} @<a href="http://localhost.local/someone">Bob Bobértson</a></p>""",
'published': '2019-04-27T00:00:00',
'inReplyTo': None,
'sensitive': False,
@ -157,6 +157,11 @@ class TestEntitiesConvertToAS2:
"href": "http://127.0.0.1:8000/profile/999999",
"name": "http://127.0.0.1:8000/profile/999999",
},
{
"type": "Mention",
"href": "http://localhost.local/someone",
"name": "http://localhost.local/someone",
},
{
"type": "Mention",
"href": "jaywink@localhost.local",
@ -170,7 +175,7 @@ class TestEntitiesConvertToAS2:
],
'url': '',
'source': {
'content': '# raw_content\n\n@{someone@localhost.local}',
'content': '# raw_content\n\n@{someone@localhost.local} @{http://localhost.local/someone}',
'mediaType': 'text/markdown',
},
},

Wyświetl plik

@ -91,7 +91,7 @@ def activitypubpost_images():
def activitypubpost_mentions():
with freeze_time("2019-04-27"):
return ActivitypubPost(
raw_content="""# raw_content\n\n@{someone@localhost.local}""",
raw_content="""# raw_content\n\n@{someone@localhost.local} @{http://localhost.local/someone}""",
public=True,
provider_display_name="Socialhome",
id=f"http://127.0.0.1:8000/post/123456/",
@ -100,6 +100,7 @@ def activitypubpost_mentions():
_mentions={
"http://127.0.0.1:8000/profile/999999",
"jaywink@localhost.local",
"http://localhost.local/someone",
}
)