kopia lustrzana https://gitlab.com/jaywink/federation
Add `process_text_links` text utility to linkify URL's in text
Moved from Socialhome.merge-requests/159/merge
rodzic
5ab541440d
commit
47d3d53a18
|
@ -8,6 +8,8 @@
|
|||
|
||||
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.
|
||||
|
||||
* Add `process_text_links` text utility to linkify URL's in text.
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from federation.utils.text import decode_if_bytes, encode_if_text, validate_handle
|
||||
from federation.utils.text import decode_if_bytes, encode_if_text, validate_handle, process_text_links
|
||||
|
||||
|
||||
def test_decode_if_bytes():
|
||||
|
@ -11,6 +11,29 @@ def test_encode_if_text():
|
|||
assert encode_if_text("foobar") == b"foobar"
|
||||
|
||||
|
||||
class TestProcessTextLinks:
|
||||
def test_link_at_start_or_end(self):
|
||||
assert process_text_links('https://example.org example.org\nhttp://example.org') == \
|
||||
'<a href="https://example.org" rel="nofollow" target="_blank">https://example.org</a> ' \
|
||||
'<a href="http://example.org" rel="nofollow" target="_blank">example.org</a>\n' \
|
||||
'<a href="http://example.org" rel="nofollow" target="_blank">http://example.org</a>'
|
||||
|
||||
def test_existing_links_get_attrs_added(self):
|
||||
assert process_text_links('<a href="https://example.org">https://example.org</a>') == \
|
||||
'<a href="https://example.org" rel="nofollow" target="_blank">https://example.org</a>'
|
||||
|
||||
def test_code_sections_are_skipped(self):
|
||||
assert process_text_links('<code>https://example.org</code><code>\nhttps://example.org\n</code>') == \
|
||||
'<code>https://example.org</code><code>\nhttps://example.org\n</code>'
|
||||
|
||||
def test_emails_are_skipped(self):
|
||||
assert process_text_links('foo@example.org') == 'foo@example.org'
|
||||
|
||||
def test_does_not_add_target_blank_if_link_is_internal(self):
|
||||
assert process_text_links('<a href="/streams/tag/foobar">#foobar</a>') == \
|
||||
'<a href="/streams/tag/foobar">#foobar</a>'
|
||||
|
||||
|
||||
def test_validate_handle():
|
||||
assert validate_handle("foo@bar.com")
|
||||
assert validate_handle("Foo@baR.com")
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import re
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import bleach
|
||||
from bleach import callbacks
|
||||
|
||||
|
||||
def decode_if_bytes(text):
|
||||
try:
|
||||
|
@ -24,6 +27,29 @@ def get_path_from_url(url: str) -> str:
|
|||
return parsed.path
|
||||
|
||||
|
||||
def process_text_links(text):
|
||||
"""Process links in text, adding some attributes and linkifying textual links."""
|
||||
link_callbacks = [callbacks.nofollow, callbacks.target_blank]
|
||||
|
||||
def link_attributes(attrs, new=False):
|
||||
"""Run standard callbacks except for internal links."""
|
||||
href_key = (None, "href")
|
||||
if attrs.get(href_key).startswith("/"):
|
||||
return attrs
|
||||
|
||||
# Run the standard callbacks
|
||||
for callback in link_callbacks:
|
||||
attrs = callback(attrs, new)
|
||||
return attrs
|
||||
|
||||
return bleach.linkify(
|
||||
text,
|
||||
callbacks=[link_attributes],
|
||||
parse_email=False,
|
||||
skip_tags=["code"],
|
||||
)
|
||||
|
||||
|
||||
def validate_handle(handle):
|
||||
"""
|
||||
Very basic handle validation as per
|
||||
|
|
1
setup.py
1
setup.py
|
@ -28,6 +28,7 @@ setup(
|
|||
license="BSD 3-clause",
|
||||
install_requires=[
|
||||
"attrs",
|
||||
"bleach>3.0",
|
||||
"commonmark",
|
||||
"cryptography",
|
||||
"cssselect>=0.9.2",
|
||||
|
|
Ładowanie…
Reference in New Issue