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
|
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.
|
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
|
### 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():
|
def test_decode_if_bytes():
|
||||||
|
@ -11,6 +11,29 @@ def test_encode_if_text():
|
||||||
assert encode_if_text("foobar") == b"foobar"
|
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():
|
def test_validate_handle():
|
||||||
assert validate_handle("foo@bar.com")
|
assert validate_handle("foo@bar.com")
|
||||||
assert validate_handle("Foo@baR.com")
|
assert validate_handle("Foo@baR.com")
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import re
|
import re
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
|
import bleach
|
||||||
|
from bleach import callbacks
|
||||||
|
|
||||||
|
|
||||||
def decode_if_bytes(text):
|
def decode_if_bytes(text):
|
||||||
try:
|
try:
|
||||||
|
@ -24,6 +27,29 @@ def get_path_from_url(url: str) -> str:
|
||||||
return parsed.path
|
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):
|
def validate_handle(handle):
|
||||||
"""
|
"""
|
||||||
Very basic handle validation as per
|
Very basic handle validation as per
|
||||||
|
|
1
setup.py
1
setup.py
|
@ -28,6 +28,7 @@ setup(
|
||||||
license="BSD 3-clause",
|
license="BSD 3-clause",
|
||||||
install_requires=[
|
install_requires=[
|
||||||
"attrs",
|
"attrs",
|
||||||
|
"bleach>3.0",
|
||||||
"commonmark",
|
"commonmark",
|
||||||
"cryptography",
|
"cryptography",
|
||||||
"cssselect>=0.9.2",
|
"cssselect>=0.9.2",
|
||||||
|
|
Ładowanie…
Reference in New Issue