parent
eb7297d743
commit
4d3b76612b
|
@ -4,6 +4,8 @@ import urllib.parse
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
|
|
||||||
|
from activities.models import PostInteraction
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass
|
@dataclasses.dataclass
|
||||||
class PaginationResult:
|
class PaginationResult:
|
||||||
|
@ -68,7 +70,7 @@ class PaginationResult:
|
||||||
|
|
||||||
class MastodonPaginator:
|
class MastodonPaginator:
|
||||||
"""
|
"""
|
||||||
Paginates in the Mastodon style (max_id, min_id, etc)
|
Paginates in the Mastodon style (max_id, min_id, etc).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -83,6 +85,22 @@ class MastodonPaginator:
|
||||||
self.default_limit = default_limit
|
self.default_limit = default_limit
|
||||||
self.max_limit = max_limit
|
self.max_limit = max_limit
|
||||||
|
|
||||||
|
def get_anchor(self, anchor_id: str):
|
||||||
|
"""
|
||||||
|
Gets an anchor object by ID.
|
||||||
|
It's possible that the anchor object might be an interaction, in which
|
||||||
|
case we recurse down to its post.
|
||||||
|
"""
|
||||||
|
if anchor_id.startswith("interaction-"):
|
||||||
|
try:
|
||||||
|
return PostInteraction.objects.get(pk=anchor_id[12:])
|
||||||
|
except PostInteraction.DoesNotExist:
|
||||||
|
return PaginationResult.empty()
|
||||||
|
try:
|
||||||
|
return self.anchor_model.objects.get(pk=anchor_id)
|
||||||
|
except self.anchor_model.DoesNotExist:
|
||||||
|
return PaginationResult.empty()
|
||||||
|
|
||||||
def paginate(
|
def paginate(
|
||||||
self,
|
self,
|
||||||
queryset,
|
queryset,
|
||||||
|
@ -92,19 +110,13 @@ class MastodonPaginator:
|
||||||
limit: int | None,
|
limit: int | None,
|
||||||
) -> PaginationResult:
|
) -> PaginationResult:
|
||||||
if max_id:
|
if max_id:
|
||||||
try:
|
anchor = self.get_anchor(max_id)
|
||||||
anchor = self.anchor_model.objects.get(pk=max_id)
|
|
||||||
except self.anchor_model.DoesNotExist:
|
|
||||||
return PaginationResult.empty()
|
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(
|
||||||
**{self.sort_attribute + "__lt": getattr(anchor, self.sort_attribute)}
|
**{self.sort_attribute + "__lt": getattr(anchor, self.sort_attribute)}
|
||||||
)
|
)
|
||||||
|
|
||||||
if since_id:
|
if since_id:
|
||||||
try:
|
anchor = self.get_anchor(since_id)
|
||||||
anchor = self.anchor_model.objects.get(pk=since_id)
|
|
||||||
except self.anchor_model.DoesNotExist:
|
|
||||||
return PaginationResult.empty()
|
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(
|
||||||
**{self.sort_attribute + "__gt": getattr(anchor, self.sort_attribute)}
|
**{self.sort_attribute + "__gt": getattr(anchor, self.sort_attribute)}
|
||||||
)
|
)
|
||||||
|
@ -112,10 +124,7 @@ class MastodonPaginator:
|
||||||
if min_id:
|
if min_id:
|
||||||
# Min ID requires items _immediately_ newer than specified, so we
|
# Min ID requires items _immediately_ newer than specified, so we
|
||||||
# invert the ordering to accommodate
|
# invert the ordering to accommodate
|
||||||
try:
|
anchor = self.get_anchor(min_id)
|
||||||
anchor = self.anchor_model.objects.get(pk=min_id)
|
|
||||||
except self.anchor_model.DoesNotExist:
|
|
||||||
return PaginationResult.empty()
|
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(
|
||||||
**{self.sort_attribute + "__gt": getattr(anchor, self.sort_attribute)}
|
**{self.sort_attribute + "__gt": getattr(anchor, self.sort_attribute)}
|
||||||
).order_by(self.sort_attribute)
|
).order_by(self.sort_attribute)
|
||||||
|
|
|
@ -122,7 +122,7 @@ def account_statuses(
|
||||||
if tagged:
|
if tagged:
|
||||||
queryset = queryset.tagged_with(tagged)
|
queryset = queryset.tagged_with(tagged)
|
||||||
|
|
||||||
paginator = MastodonPaginator(Post)
|
paginator = MastodonPaginator(Post, sort_attribute="published")
|
||||||
pager = paginator.paginate(
|
pager = paginator.paginate(
|
||||||
queryset,
|
queryset,
|
||||||
min_id=min_id,
|
min_id=min_id,
|
||||||
|
|
|
@ -19,7 +19,7 @@ def home(
|
||||||
min_id: str | None = None,
|
min_id: str | None = None,
|
||||||
limit: int = 20,
|
limit: int = 20,
|
||||||
):
|
):
|
||||||
paginator = MastodonPaginator(Post)
|
paginator = MastodonPaginator(Post, sort_attribute="published")
|
||||||
queryset = TimelineService(request.identity).home()
|
queryset = TimelineService(request.identity).home()
|
||||||
pager = paginator.paginate(
|
pager = paginator.paginate(
|
||||||
queryset,
|
queryset,
|
||||||
|
@ -64,7 +64,7 @@ def public(
|
||||||
queryset = queryset.filter(local=False)
|
queryset = queryset.filter(local=False)
|
||||||
if only_media:
|
if only_media:
|
||||||
queryset = queryset.filter(attachments__id__isnull=True)
|
queryset = queryset.filter(attachments__id__isnull=True)
|
||||||
paginator = MastodonPaginator(Post)
|
paginator = MastodonPaginator(Post, sort_attribute="published")
|
||||||
pager = paginator.paginate(
|
pager = paginator.paginate(
|
||||||
queryset,
|
queryset,
|
||||||
min_id=min_id,
|
min_id=min_id,
|
||||||
|
@ -105,7 +105,7 @@ def hashtag(
|
||||||
queryset = queryset.filter(local=True)
|
queryset = queryset.filter(local=True)
|
||||||
if only_media:
|
if only_media:
|
||||||
queryset = queryset.filter(attachments__id__isnull=True)
|
queryset = queryset.filter(attachments__id__isnull=True)
|
||||||
paginator = MastodonPaginator(Post)
|
paginator = MastodonPaginator(Post, sort_attribute="published")
|
||||||
pager = paginator.paginate(
|
pager = paginator.paginate(
|
||||||
queryset,
|
queryset,
|
||||||
min_id=min_id,
|
min_id=min_id,
|
||||||
|
|
Loading…
Reference in New Issue