Skip to content

Commit

Permalink
Fixed jointakahe#559: Trim hashtags to 100 chars or less
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewgodwin committed May 4, 2023
1 parent 8f57aa5 commit 709dc86
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 5 deletions.
2 changes: 2 additions & 0 deletions activities/models/hashtag.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ def hashtag_or_alias(self, hashtag: str):

class Hashtag(StatorModel):

MAXIMUM_LENGTH = 100

# Normalized hashtag without the '#'
hashtag = models.SlugField(primary_key=True, max_length=100)

Expand Down
16 changes: 12 additions & 4 deletions activities/models/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,10 @@ def create_local(
# Strip all unwanted HTML and apply linebreaks filter, grabbing hashtags on the way
parser = FediverseHtmlParser(linebreaks_filter(content), find_hashtags=True)
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
post = cls.objects.create(
author=author,
Expand Down Expand Up @@ -529,7 +532,10 @@ def edit_local(
# Strip all HTML and apply linebreaks filter
parser = FediverseHtmlParser(linebreaks_filter(content), find_hashtags=True)
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.sensitive = bool(summary) if sensitive is None else sensitive
self.visibility = visibility
Expand Down Expand Up @@ -577,7 +583,7 @@ async def ensure_hashtags(self) -> None:
if self.hashtags:
for hashtag in self.hashtags:
tag, _ = await Hashtag.objects.aget_or_create(
hashtag=hashtag,
hashtag=hashtag[: Hashtag.MAXIMUM_LENGTH],
)
await tag.atransition_perform(HashtagStates.outdated)

Expand Down Expand Up @@ -876,7 +882,9 @@ def by_ap(cls, data, create=False, update=False, fetch_author=False) -> "Post":
post.mentions.add(mention_identity)
elif tag_type in ["_:hashtag", "hashtag"]:
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"]:
emoji = Emoji.by_ap_tag(post.author.domain, tag, create=True)
Expand Down
30 changes: 29 additions & 1 deletion tests/activities/models/test_post.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
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 users.models import Identity, InboxMessage

Expand Down Expand Up @@ -57,6 +57,34 @@ def test_post_create_edit(identity: Identity, config_system):
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
def test_linkify_mentions_remote(
identity, identity2, remote_identity, remote_identity2
Expand Down

0 comments on commit 709dc86

Please sign in to comment.