kopia lustrzana https://gitlab.com/jaywink/federation
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/572merge-requests/159/merge
rodzic
4c665e8743
commit
c479a42d47
|
@ -2,6 +2,13 @@
|
||||||
|
|
||||||
## [0.20.0-dev] - unreleased
|
## [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
|
### Changed
|
||||||
|
|
||||||
* The NodeInfo2 hostmeta parser now cleans the port out of the host name.
|
* The NodeInfo2 hostmeta parser now cleans the port out of the host name.
|
||||||
|
|
|
@ -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.
|
* ``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_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_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:
|
* ``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:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
|
@ -7,9 +7,9 @@ from typing import List, Set, Union, Dict
|
||||||
from commonmark import commonmark
|
from commonmark import commonmark
|
||||||
|
|
||||||
from federation.entities.activitypub.enums import ActivityType
|
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:
|
class BaseEntity:
|
||||||
_allowed_children: tuple = ()
|
_allowed_children: tuple = ()
|
||||||
_children: List = None
|
_children: List = None
|
||||||
|
@ -206,7 +206,17 @@ class RawContentMixin(BaseEntity):
|
||||||
if self._rendered_content:
|
if self._rendered_content:
|
||||||
return self._rendered_content
|
return self._rendered_content
|
||||||
elif self._media_type == "text/markdown" and self.raw_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
|
return self.raw_content
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import inspect
|
import inspect
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
def get_base_attributes(entity):
|
def get_base_attributes(entity):
|
||||||
|
@ -13,3 +14,25 @@ def get_base_attributes(entity):
|
||||||
if not attr.startswith("_"):
|
if not attr.startswith("_"):
|
||||||
attributes[attr] = getattr(entity, attr)
|
attributes[attr] = getattr(entity, attr)
|
||||||
return attributes
|
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
|
||||||
|
|
|
@ -146,7 +146,7 @@ class TestEntitiesConvertToAS2:
|
||||||
'type': 'Note',
|
'type': 'Note',
|
||||||
'attributedTo': 'http://127.0.0.1:8000/profile/123456/',
|
'attributedTo': 'http://127.0.0.1:8000/profile/123456/',
|
||||||
'content': """<h1>raw_content</h1>
|
'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',
|
'published': '2019-04-27T00:00:00',
|
||||||
'inReplyTo': None,
|
'inReplyTo': None,
|
||||||
'sensitive': False,
|
'sensitive': False,
|
||||||
|
@ -157,6 +157,11 @@ class TestEntitiesConvertToAS2:
|
||||||
"href": "http://127.0.0.1:8000/profile/999999",
|
"href": "http://127.0.0.1:8000/profile/999999",
|
||||||
"name": "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",
|
"type": "Mention",
|
||||||
"href": "jaywink@localhost.local",
|
"href": "jaywink@localhost.local",
|
||||||
|
@ -170,7 +175,7 @@ class TestEntitiesConvertToAS2:
|
||||||
],
|
],
|
||||||
'url': '',
|
'url': '',
|
||||||
'source': {
|
'source': {
|
||||||
'content': '# raw_content\n\n@{someone@localhost.local}',
|
'content': '# raw_content\n\n@{someone@localhost.local} @{http://localhost.local/someone}',
|
||||||
'mediaType': 'text/markdown',
|
'mediaType': 'text/markdown',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -91,7 +91,7 @@ def activitypubpost_images():
|
||||||
def activitypubpost_mentions():
|
def activitypubpost_mentions():
|
||||||
with freeze_time("2019-04-27"):
|
with freeze_time("2019-04-27"):
|
||||||
return ActivitypubPost(
|
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,
|
public=True,
|
||||||
provider_display_name="Socialhome",
|
provider_display_name="Socialhome",
|
||||||
id=f"http://127.0.0.1:8000/post/123456/",
|
id=f"http://127.0.0.1:8000/post/123456/",
|
||||||
|
@ -100,6 +100,7 @@ def activitypubpost_mentions():
|
||||||
_mentions={
|
_mentions={
|
||||||
"http://127.0.0.1:8000/profile/999999",
|
"http://127.0.0.1:8000/profile/999999",
|
||||||
"jaywink@localhost.local",
|
"jaywink@localhost.local",
|
||||||
|
"http://localhost.local/someone",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue