From fc8a21fc5c6809ea115092eeec57e09e984cdd76 Mon Sep 17 00:00:00 2001 From: Andrew Godwin Date: Sun, 11 Dec 2022 11:22:06 -0700 Subject: More API read coverage --- api/views/timelines.py | 126 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 9 deletions(-) (limited to 'api/views/timelines.py') diff --git a/api/views/timelines.py b/api/views/timelines.py index 5de0e0f..d560596 100644 --- a/api/views/timelines.py +++ b/api/views/timelines.py @@ -1,16 +1,21 @@ -from activities.models import TimelineEvent +from activities.models import Post, TimelineEvent from .. import schemas from ..decorators import identity_required -from .base import api +from .base import api_router -@api.get("/v1/timelines/home", response=list[schemas.Status]) +@api_router.get("/v1/timelines/home", response=list[schemas.Status]) @identity_required -def home(request): - if request.GET.get("max_id"): - return [] - limit = int(request.GET.get("limit", "20")) +def home( + request, + max_id: str | None = None, + since_id: str | None = None, + min_id: str | None = None, + limit: int = 20, +): + if limit > 40: + limit = 40 events = ( TimelineEvent.objects.filter( identity=request.identity, @@ -18,6 +23,109 @@ def home(request): ) .select_related("subject_post", "subject_post__author") .prefetch_related("subject_post__attachments") - .order_by("-created")[:limit] + .order_by("-created") ) - return [event.subject_post.to_mastodon_json() for event in events] + if max_id: + anchor_post = Post.objects.get(pk=max_id) + events = events.filter(created__lt=anchor_post.created) + if since_id: + anchor_post = Post.objects.get(pk=since_id) + events = events.filter(created__gt=anchor_post.created) + if min_id: + # Min ID requires LIMIT events _immediately_ newer than specified, so we + # invert the ordering to accomodate + anchor_post = Post.objects.get(pk=min_id) + events = events.filter(created__gt=anchor_post.created).order_by("created") + return [event.subject_post.to_mastodon_json() for event in events[:limit]] + + +@api_router.get("/v1/timelines/public", response=list[schemas.Status]) +@identity_required +def public( + request, + 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 limit > 40: + limit = 40 + posts = ( + Post.objects.public() + .select_related("author") + .prefetch_related("attachments") + .order_by("-created") + ) + if local: + posts = posts.filter(local=True) + elif remote: + posts = posts.filter(local=False) + if only_media: + posts = posts.filter(attachments__id__isnull=True) + if max_id: + anchor_post = Post.objects.get(pk=max_id) + posts = posts.filter(created__lt=anchor_post.created) + if since_id: + anchor_post = Post.objects.get(pk=since_id) + posts = posts.filter(created__gt=anchor_post.created) + if min_id: + # Min ID requires LIMIT posts _immediately_ newer than specified, so we + # invert the ordering to accomodate + anchor_post = Post.objects.get(pk=min_id) + posts = posts.filter(created__gt=anchor_post.created).order_by("created") + return [post.to_mastodon_json() for post in posts[:limit]] + + +@api_router.get("/v1/timelines/tag/{hashtag}", response=list[schemas.Status]) +@identity_required +def hashtag( + request, + 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 + posts = ( + Post.objects.public() + .tagged_with(hashtag) + .select_related("author") + .prefetch_related("attachments") + .order_by("-created") + ) + if local: + posts = posts.filter(local=True) + if only_media: + posts = posts.filter(attachments__id__isnull=True) + if max_id: + anchor_post = Post.objects.get(pk=max_id) + posts = posts.filter(created__lt=anchor_post.created) + if since_id: + anchor_post = Post.objects.get(pk=since_id) + posts = posts.filter(created__gt=anchor_post.created) + if min_id: + # Min ID requires LIMIT posts _immediately_ newer than specified, so we + # invert the ordering to accomodate + anchor_post = Post.objects.get(pk=min_id) + posts = posts.filter(created__gt=anchor_post.created).order_by("created") + return [post.to_mastodon_json() for post in posts[:limit]] + + +@api_router.get("/v1/conversations", response=list[schemas.Status]) +@identity_required +def conversations( + request, + 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 [] -- cgit v1.2.3