Fixed #559: Trim hashtags to 100 chars or less
This commit is contained in:
parent
8f57aa5f37
commit
709dc86162
|
@ -87,6 +87,8 @@ class HashtagManager(models.Manager):
|
||||||
|
|
||||||
class Hashtag(StatorModel):
|
class Hashtag(StatorModel):
|
||||||
|
|
||||||
|
MAXIMUM_LENGTH = 100
|
||||||
|
|
||||||
# Normalized hashtag without the '#'
|
# Normalized hashtag without the '#'
|
||||||
hashtag = models.SlugField(primary_key=True, max_length=100)
|
hashtag = models.SlugField(primary_key=True, max_length=100)
|
||||||
|
|
||||||
|
|
|
@ -489,7 +489,10 @@ class Post(StatorModel):
|
||||||
# Strip all unwanted HTML and apply linebreaks filter, grabbing hashtags on the way
|
# Strip all unwanted HTML and apply linebreaks filter, grabbing hashtags on the way
|
||||||
parser = FediverseHtmlParser(linebreaks_filter(content), find_hashtags=True)
|
parser = FediverseHtmlParser(linebreaks_filter(content), find_hashtags=True)
|
||||||
content = parser.html
|
content = parser.html
|
||||||
hashtags = sorted(parser.hashtags) or None
|
hashtags = (
|
||||||
|
sorted([tag[: Hashtag.MAXIMUM_LENGTH] for tag in parser.hashtags])
|
||||||
|
or None
|
||||||
|
)
|
||||||
# Make the Post object
|
# Make the Post object
|
||||||
post = cls.objects.create(
|
post = cls.objects.create(
|
||||||
author=author,
|
author=author,
|
||||||
|
@ -529,7 +532,10 @@ class Post(StatorModel):
|
||||||
# Strip all HTML and apply linebreaks filter
|
# Strip all HTML and apply linebreaks filter
|
||||||
parser = FediverseHtmlParser(linebreaks_filter(content), find_hashtags=True)
|
parser = FediverseHtmlParser(linebreaks_filter(content), find_hashtags=True)
|
||||||
self.content = parser.html
|
self.content = parser.html
|
||||||
self.hashtags = sorted(parser.hashtags) or None
|
self.hashtags = (
|
||||||
|
sorted([tag[: Hashtag.MAXIMUM_LENGTH] for tag in parser.hashtags])
|
||||||
|
or None
|
||||||
|
)
|
||||||
self.summary = summary or None
|
self.summary = summary or None
|
||||||
self.sensitive = bool(summary) if sensitive is None else sensitive
|
self.sensitive = bool(summary) if sensitive is None else sensitive
|
||||||
self.visibility = visibility
|
self.visibility = visibility
|
||||||
|
@ -577,7 +583,7 @@ class Post(StatorModel):
|
||||||
if self.hashtags:
|
if self.hashtags:
|
||||||
for hashtag in self.hashtags:
|
for hashtag in self.hashtags:
|
||||||
tag, _ = await Hashtag.objects.aget_or_create(
|
tag, _ = await Hashtag.objects.aget_or_create(
|
||||||
hashtag=hashtag,
|
hashtag=hashtag[: Hashtag.MAXIMUM_LENGTH],
|
||||||
)
|
)
|
||||||
await tag.atransition_perform(HashtagStates.outdated)
|
await tag.atransition_perform(HashtagStates.outdated)
|
||||||
|
|
||||||
|
@ -876,7 +882,9 @@ class Post(StatorModel):
|
||||||
post.mentions.add(mention_identity)
|
post.mentions.add(mention_identity)
|
||||||
elif tag_type in ["_:hashtag", "hashtag"]:
|
elif tag_type in ["_:hashtag", "hashtag"]:
|
||||||
post.hashtags.append(
|
post.hashtags.append(
|
||||||
get_value_or_map(tag, "name", "nameMap").lower().lstrip("#")
|
get_value_or_map(tag, "name", "nameMap")
|
||||||
|
.lower()
|
||||||
|
.lstrip("#")[: Hashtag.MAXIMUM_LENGTH]
|
||||||
)
|
)
|
||||||
elif tag_type in ["toot:emoji", "emoji"]:
|
elif tag_type in ["toot:emoji", "emoji"]:
|
||||||
emoji = Emoji.by_ap_tag(post.author.domain, tag, create=True)
|
emoji = Emoji.by_ap_tag(post.author.domain, tag, create=True)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import pytest
|
import pytest
|
||||||
from pytest_httpx import HTTPXMock
|
from pytest_httpx import HTTPXMock
|
||||||
|
|
||||||
from activities.models import Post, PostStates
|
from activities.models import Hashtag, Post, PostStates
|
||||||
from activities.models.post_types import QuestionData
|
from activities.models.post_types import QuestionData
|
||||||
from users.models import Identity, InboxMessage
|
from users.models import Identity, InboxMessage
|
||||||
|
|
||||||
|
@ -57,6 +57,34 @@ def test_post_create_edit(identity: Identity, config_system):
|
||||||
assert list(post.mentions.all()) == []
|
assert list(post.mentions.all()) == []
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_ensure_hashtag(identity: Identity, config_system, stator):
|
||||||
|
"""
|
||||||
|
Tests that normal hashtags get a Hashtag object created, and a hashtag
|
||||||
|
over our limit of 100 characters is truncated.
|
||||||
|
"""
|
||||||
|
# Normal length hashtag
|
||||||
|
post = Post.create_local(
|
||||||
|
author=identity,
|
||||||
|
content="Hello, #testtag",
|
||||||
|
)
|
||||||
|
stator.run_single_cycle_sync()
|
||||||
|
assert post.hashtags == ["testtag"]
|
||||||
|
assert Hashtag.objects.filter(hashtag="testtag").exists()
|
||||||
|
# Excessively long hashtag
|
||||||
|
post = Post.create_local(
|
||||||
|
author=identity,
|
||||||
|
content="Hello, #thisisahashtagthatiswaytoolongandissignificantlyaboveourmaximumlimitofonehundredcharacterswhytheywouldbethislongidontknow",
|
||||||
|
)
|
||||||
|
stator.run_single_cycle_sync()
|
||||||
|
assert post.hashtags == [
|
||||||
|
"thisisahashtagthatiswaytoolongandissignificantlyaboveourmaximumlimitofonehundredcharacterswhytheywou"
|
||||||
|
]
|
||||||
|
assert Hashtag.objects.filter(
|
||||||
|
hashtag="thisisahashtagthatiswaytoolongandissignificantlyaboveourmaximumlimitofonehundredcharacterswhytheywou"
|
||||||
|
).exists()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
def test_linkify_mentions_remote(
|
def test_linkify_mentions_remote(
|
||||||
identity, identity2, remote_identity, remote_identity2
|
identity, identity2, remote_identity, remote_identity2
|
||||||
|
|
Loading…
Reference in New Issue