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:
parent
216915ddb8
commit
b31c5156ff
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue