Improve hashtag case handling and implement /api/v1/tags/<hashtag> endpoint (#554)

* Lowercase hashtag before loading its timeline

* Implement /api/v1/tags/<hashtag> endpoint

* Lower hashtag before un-/following

* Fix field name for hashtag following/followed boolean
This commit is contained in:
Christof Dorner 2023-04-06 21:14:21 +00:00 committed by GitHub
parent 216915ddb8
commit b31c5156ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 12 deletions

View file

@ -168,14 +168,14 @@ class Hashtag(StatorModel):
results[date(year, month, day)] = val
return dict(sorted(results.items(), reverse=True)[:num])
def to_mastodon_json(self, followed: bool | None = None):
def to_mastodon_json(self, following: bool | None = None):
value = {
"name": self.hashtag,
"url": self.urls.view.full(), # type: ignore
"history": [],
}
if followed is not None:
value["followed"] = followed
if following is not None:
value["following"] = following
return value

View file

@ -276,15 +276,15 @@ class Tag(Schema):
name: str
url: str
history: dict
followed: bool | None
following: bool | None
@classmethod
def from_hashtag(
cls,
hashtag: activities_models.Hashtag,
followed: bool | None = None,
following: bool | None = None,
) -> "Tag":
return cls(**hashtag.to_mastodon_json(followed=followed))
return cls(**hashtag.to_mastodon_json(following=following))
class FollowedTag(Tag):
@ -295,7 +295,7 @@ class FollowedTag(Tag):
cls,
follow: users_models.HashtagFollow,
) -> "FollowedTag":
return cls(id=follow.id, **follow.hashtag.to_mastodon_json(followed=True))
return cls(id=follow.id, **follow.hashtag.to_mastodon_json(following=True))
@classmethod
def map_from_follows(

View file

@ -96,6 +96,7 @@ urlpatterns = [
path("v1/statuses/<id>/unbookmark", statuses.unbookmark_status),
# Tags
path("v1/followed_tags", tags.followed_tags),
path("v1/tags/<hashtag>", tags.hashtag),
path("v1/tags/<id>/follow", tags.follow),
path("v1/tags/<id>/unfollow", tags.unfollow),
# Timelines

View file

@ -9,6 +9,22 @@ from api.pagination import MastodonPaginator, PaginatingApiResponse, PaginationR
from users.models import HashtagFollow
@api_view.get
def hashtag(request: HttpRequest, hashtag: str) -> schemas.Tag:
tag = get_object_or_404(
Hashtag,
pk=hashtag.lower(),
)
following = None
if request.identity:
following = tag.followers.filter(identity=request.identity).exists()
return schemas.Tag.from_hashtag(
tag,
following=following,
)
@scope_required("read:follows")
@api_view.get
def followed_tags(
@ -42,12 +58,12 @@ def follow(
) -> schemas.Tag:
hashtag = get_object_or_404(
Hashtag,
pk=id,
pk=id.lower(),
)
request.identity.hashtag_follows.get_or_create(hashtag=hashtag)
return schemas.Tag.from_hashtag(
hashtag,
followed=True,
following=True,
)
@ -59,10 +75,10 @@ def unfollow(
) -> schemas.Tag:
hashtag = get_object_or_404(
Hashtag,
pk=id,
pk=id.lower(),
)
request.identity.hashtag_follows.filter(hashtag=hashtag).delete()
return schemas.Tag.from_hashtag(
hashtag,
followed=False,
following=False,
)

View file

@ -101,7 +101,7 @@ def hashtag(
) -> ApiResponse[list[schemas.Status]]:
if limit > 40:
limit = 40
queryset = TimelineService(request.identity).hashtag(hashtag)
queryset = TimelineService(request.identity).hashtag(hashtag.lower())
if local:
queryset = queryset.filter(local=True)
if only_media: