takahe/api/views/accounts.py

174 lines
5.1 KiB
Python
Raw Normal View History

from django.http import HttpRequest, HttpResponse
2022-12-11 10:22:06 -08:00
from django.shortcuts import get_object_or_404
2022-12-21 13:54:49 -08:00
from ninja import Field
2022-12-11 10:22:06 -08:00
2022-12-11 11:37:28 -08:00
from activities.models import Post, PostInteraction
2022-12-21 13:54:49 -08:00
from activities.services import SearchService
2022-12-11 10:22:06 -08:00
from api import schemas
2022-12-11 11:37:28 -08:00
from api.decorators import identity_required
2022-12-11 23:38:02 -08:00
from api.pagination import MastodonPaginator
2022-12-11 10:22:06 -08:00
from api.views.base import api_router
from users.models import Identity
from users.services import IdentityService
2022-12-11 10:22:06 -08:00
2022-12-10 23:25:48 -08:00
2022-12-11 10:22:06 -08:00
@api_router.get("/v1/accounts/verify_credentials", response=schemas.Account)
2022-12-10 23:25:48 -08:00
@identity_required
def verify_credentials(request):
return request.identity.to_mastodon_json()
2022-12-11 10:22:06 -08:00
@api_router.get("/v1/accounts/relationships", response=list[schemas.Relationship])
@identity_required
def account_relationships(request):
ids = request.GET.getlist("id[]")
result = []
for id in ids:
identity = get_object_or_404(Identity, pk=id)
result.append(
IdentityService(identity).mastodon_json_relationship(request.identity)
2022-12-11 10:22:06 -08:00
)
return result
@api_router.get(
"/v1/accounts/familiar_followers", response=list[schemas.FamiliarFollowers]
)
@identity_required
def familiar_followers(request):
"""
Returns people you follow that also follow given account IDs
"""
ids = request.GET.getlist("id[]")
result = []
for id in ids:
target_identity = get_object_or_404(Identity, pk=id)
result.append(
{
"id": id,
"accounts": [
identity.to_mastodon_json()
for identity in Identity.objects.filter(
inbound_follows__source=request.identity,
outbound_follows__target=target_identity,
)[:20]
],
}
)
return result
2022-12-21 13:54:49 -08:00
@api_router.get("/v1/accounts/search", response=list[schemas.Account])
@identity_required
def search(
request,
q: str,
fetch_identities: bool = Field(False, alias="resolve"),
following: bool = False,
limit: int = 20,
offset: int = 0,
):
"""
Handles searching for accounts by username or handle
"""
if limit > 40:
limit = 40
if offset:
return []
searcher = SearchService(q, request.identity)
search_result = searcher.search_identities_handle()
return [i.to_mastodon_json() for i in search_result]
2022-12-11 10:22:06 -08:00
@api_router.get("/v1/accounts/{id}", response=schemas.Account)
@identity_required
def account(request, id: str):
2022-12-16 18:42:48 -08:00
identity = get_object_or_404(
Identity.objects.exclude(restriction=Identity.Restriction.blocked), pk=id
)
2022-12-11 10:22:06 -08:00
return identity.to_mastodon_json()
@api_router.get("/v1/accounts/{id}/statuses", response=list[schemas.Status])
@identity_required
def account_statuses(
request: HttpRequest,
response: HttpResponse,
2022-12-11 10:22:06 -08:00
id: str,
exclude_reblogs: bool = False,
exclude_replies: bool = False,
only_media: bool = False,
pinned: bool = False,
tagged: str | None = None,
max_id: str | None = None,
since_id: str | None = None,
min_id: str | None = None,
limit: int = 20,
):
2022-12-16 18:42:48 -08:00
identity = get_object_or_404(
Identity.objects.exclude(restriction=Identity.Restriction.blocked), pk=id
)
2022-12-11 23:38:02 -08:00
queryset = (
2022-12-11 11:37:28 -08:00
identity.posts.not_hidden()
.unlisted(include_replies=not exclude_replies)
2022-12-11 10:22:06 -08:00
.select_related("author")
.prefetch_related("attachments")
.order_by("-created")
)
if pinned:
return []
if only_media:
2022-12-11 23:38:02 -08:00
queryset = queryset.filter(attachments__pk__isnull=False)
2022-12-11 10:22:06 -08:00
if tagged:
2022-12-11 23:38:02 -08:00
queryset = queryset.tagged_with(tagged)
paginator = MastodonPaginator(Post, sort_attribute="published")
pager = paginator.paginate(
2022-12-11 23:38:02 -08:00
queryset,
min_id=min_id,
max_id=max_id,
since_id=since_id,
limit=limit,
)
if pager.results:
response.headers["Link"] = pager.link_header(
request,
[
"limit",
"id",
"exclude_reblogs",
"exclude_replies",
"only_media",
"pinned",
"tagged",
],
)
interactions = PostInteraction.get_post_interactions(
pager.results, request.identity
)
return [post.to_mastodon_json(interactions=interactions) for post in pager.results]
@api_router.post("/v1/accounts/{id}/follow", response=schemas.Relationship)
@identity_required
def account_follow(request, id: str):
identity = get_object_or_404(
Identity.objects.exclude(restriction=Identity.Restriction.blocked), pk=id
)
service = IdentityService(identity)
service.follow_from(request.identity)
return service.mastodon_json_relationship(request.identity)
@api_router.post("/v1/accounts/{id}/unfollow", response=schemas.Relationship)
@identity_required
def account_unfollow(request, id: str):
identity = get_object_or_404(
Identity.objects.exclude(restriction=Identity.Restriction.blocked), pk=id
)
service = IdentityService(identity)
service.unfollow_from(request.identity)
return service.mastodon_json_relationship(request.identity)