mirror of
https://github.com/jointakahe/takahe.git
synced 2024-12-27 15:40:29 +00:00
28cfbf2ef5
Prefetch/select required fields for API version of home. Requires considerably more data than HTML version of home.
146 lines
4.4 KiB
Python
146 lines
4.4 KiB
Python
from django.http import HttpRequest, HttpResponse, JsonResponse
|
|
|
|
from activities.services import TimelineService
|
|
from api import schemas
|
|
from api.decorators import identity_required
|
|
from api.pagination import MastodonPaginator
|
|
from api.views.base import api_router
|
|
from core.models import Config
|
|
|
|
|
|
@api_router.get("/v1/timelines/home", response=list[schemas.Status])
|
|
@identity_required
|
|
def home(
|
|
request: HttpRequest,
|
|
response: HttpResponse,
|
|
max_id: str | None = None,
|
|
since_id: str | None = None,
|
|
min_id: str | None = None,
|
|
limit: int = 20,
|
|
):
|
|
# Grab a paginated result set of instances
|
|
paginator = MastodonPaginator()
|
|
queryset = TimelineService(request.identity).home()
|
|
queryset = queryset.select_related(
|
|
"subject_post_interaction__post",
|
|
"subject_post_interaction__post__author",
|
|
"subject_post_interaction__post__author__domain",
|
|
)
|
|
queryset = queryset.prefetch_related(
|
|
"subject_post__mentions__domain",
|
|
"subject_post_interaction__post__attachments",
|
|
"subject_post_interaction__post__mentions",
|
|
"subject_post_interaction__post__emojis",
|
|
"subject_post_interaction__post__mentions__domain",
|
|
"subject_post_interaction__post__author__posts",
|
|
)
|
|
pager = paginator.paginate_home(
|
|
queryset,
|
|
min_id=min_id,
|
|
max_id=max_id,
|
|
since_id=since_id,
|
|
limit=limit,
|
|
)
|
|
# Convert those to the JSON form
|
|
pager.jsonify_status_events(identity=request.identity)
|
|
# Add the link header if needed
|
|
if pager.results:
|
|
response.headers["Link"] = pager.link_header(request, ["limit"])
|
|
return pager.json_results
|
|
|
|
|
|
@api_router.get("/v1/timelines/public", response=list[schemas.Status])
|
|
def public(
|
|
request: HttpRequest,
|
|
response: HttpResponse,
|
|
local: bool = False,
|
|
remote: bool = False,
|
|
only_media: bool = False,
|
|
max_id: str | None = None,
|
|
since_id: str | None = None,
|
|
min_id: str | None = None,
|
|
limit: int = 20,
|
|
):
|
|
if not request.identity and not Config.system.public_timeline:
|
|
return JsonResponse({"error": "public timeline is disabled"}, status=422)
|
|
|
|
if local:
|
|
queryset = TimelineService(request.identity).local()
|
|
else:
|
|
queryset = TimelineService(request.identity).federated()
|
|
if remote:
|
|
queryset = queryset.filter(local=False)
|
|
if only_media:
|
|
queryset = queryset.filter(attachments__id__isnull=True)
|
|
# Grab a paginated result set of instances
|
|
paginator = MastodonPaginator()
|
|
pager = paginator.paginate(
|
|
queryset,
|
|
min_id=min_id,
|
|
max_id=max_id,
|
|
since_id=since_id,
|
|
limit=limit,
|
|
)
|
|
# Convert those to the JSON form
|
|
pager.jsonify_posts(identity=request.identity)
|
|
# Add the link header if needed
|
|
if pager.results:
|
|
response.headers["Link"] = pager.link_header(
|
|
request,
|
|
["limit", "local", "remote", "only_media"],
|
|
)
|
|
return pager.json_results
|
|
|
|
|
|
@api_router.get("/v1/timelines/tag/{hashtag}", response=list[schemas.Status])
|
|
@identity_required
|
|
def hashtag(
|
|
request: HttpRequest,
|
|
response: HttpResponse,
|
|
hashtag: str,
|
|
local: bool = False,
|
|
only_media: bool = False,
|
|
max_id: str | None = None,
|
|
since_id: str | None = None,
|
|
min_id: str | None = None,
|
|
limit: int = 20,
|
|
):
|
|
if limit > 40:
|
|
limit = 40
|
|
queryset = TimelineService(request.identity).hashtag(hashtag)
|
|
if local:
|
|
queryset = queryset.filter(local=True)
|
|
if only_media:
|
|
queryset = queryset.filter(attachments__id__isnull=True)
|
|
# Grab a paginated result set of instances
|
|
paginator = MastodonPaginator()
|
|
pager = paginator.paginate(
|
|
queryset,
|
|
min_id=min_id,
|
|
max_id=max_id,
|
|
since_id=since_id,
|
|
limit=limit,
|
|
)
|
|
# Convert those to the JSON form
|
|
pager.jsonify_posts(identity=request.identity)
|
|
# Add a link header if we need to
|
|
if pager.results:
|
|
response.headers["Link"] = pager.link_header(
|
|
request,
|
|
["limit", "local", "remote", "only_media"],
|
|
)
|
|
return pager.json_results
|
|
|
|
|
|
@api_router.get("/v1/conversations", response=list[schemas.Status])
|
|
@identity_required
|
|
def conversations(
|
|
request: HttpRequest,
|
|
response: HttpResponse,
|
|
max_id: str | None = None,
|
|
since_id: str | None = None,
|
|
min_id: str | None = None,
|
|
limit: int = 20,
|
|
):
|
|
# We don't implement this yet
|
|
return []
|