Move timelines to a service class
This commit is contained in:
parent
bf5a46df38
commit
e2371a3cd7
|
@ -1,2 +1,3 @@
|
|||
from .post import PostService # noqa
|
||||
from .search import SearchService # noqa
|
||||
from .timeline import TimelineService # noqa
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
from django.db import models
|
||||
|
||||
from activities.models import Hashtag, Post, TimelineEvent
|
||||
from users.models import Identity
|
||||
|
||||
|
||||
class TimelineService:
|
||||
"""
|
||||
Timelines and stuff!
|
||||
"""
|
||||
|
||||
def __init__(self, identity: Identity):
|
||||
self.identity = identity
|
||||
|
||||
def home(self) -> models.QuerySet[TimelineEvent]:
|
||||
return (
|
||||
TimelineEvent.objects.filter(
|
||||
identity=self.identity,
|
||||
type__in=[TimelineEvent.Types.post, TimelineEvent.Types.boost],
|
||||
)
|
||||
.select_related(
|
||||
"subject_post",
|
||||
"subject_post__author",
|
||||
"subject_post__author__domain",
|
||||
"subject_identity",
|
||||
"subject_identity__domain",
|
||||
"subject_post_interaction",
|
||||
"subject_post_interaction__identity",
|
||||
"subject_post_interaction__identity__domain",
|
||||
)
|
||||
.prefetch_related(
|
||||
"subject_post__attachments",
|
||||
"subject_post__mentions",
|
||||
"subject_post__emojis",
|
||||
)
|
||||
.order_by("-published")
|
||||
)
|
||||
|
||||
def local(self) -> models.QuerySet[Post]:
|
||||
return (
|
||||
Post.objects.local_public()
|
||||
.not_hidden()
|
||||
.filter(author__restriction=Identity.Restriction.none)
|
||||
.select_related("author", "author__domain")
|
||||
.prefetch_related("attachments", "mentions", "emojis")
|
||||
.order_by("-published")
|
||||
)
|
||||
|
||||
def federated(self) -> models.QuerySet[Post]:
|
||||
return (
|
||||
Post.objects.public()
|
||||
.not_hidden()
|
||||
.filter(author__restriction=Identity.Restriction.none)
|
||||
.select_related("author", "author__domain")
|
||||
.prefetch_related("attachments", "mentions", "emojis")
|
||||
.order_by("-published")
|
||||
)
|
||||
|
||||
def hashtag(self, hashtag: str | Hashtag) -> models.QuerySet[Post]:
|
||||
return (
|
||||
Post.objects.public()
|
||||
.not_hidden()
|
||||
.filter(author__restriction=Identity.Restriction.none)
|
||||
.tagged_with(hashtag)
|
||||
.select_related("author", "author__domain")
|
||||
.prefetch_related("attachments", "mentions")
|
||||
.order_by("-published")
|
||||
)
|
||||
|
||||
def notifications(self, types: list[str]) -> models.QuerySet[TimelineEvent]:
|
||||
return (
|
||||
TimelineEvent.objects.filter(identity=self.identity, type__in=types)
|
||||
.order_by("-published")
|
||||
.select_related(
|
||||
"subject_post",
|
||||
"subject_post__author",
|
||||
"subject_post__author__domain",
|
||||
"subject_identity",
|
||||
"subject_identity__domain",
|
||||
"subject_post_interaction",
|
||||
"subject_post_interaction__identity",
|
||||
"subject_post_interaction__identity__domain",
|
||||
)
|
||||
.prefetch_related(
|
||||
"subject_post__emojis",
|
||||
"subject_post__mentions",
|
||||
"subject_post__attachments",
|
||||
)
|
||||
)
|
|
@ -3,10 +3,10 @@ from django.shortcuts import get_object_or_404, redirect
|
|||
from django.utils.decorators import method_decorator
|
||||
from django.views.generic import ListView, TemplateView
|
||||
|
||||
from activities.models import Hashtag, Post, PostInteraction, TimelineEvent
|
||||
from activities.models import Hashtag, PostInteraction, TimelineEvent
|
||||
from activities.services import TimelineService
|
||||
from core.decorators import cache_page
|
||||
from users.decorators import identity_required
|
||||
from users.models import Identity
|
||||
|
||||
from .compose import Compose
|
||||
|
||||
|
@ -22,28 +22,7 @@ class Home(TemplateView):
|
|||
return self.form_class(request=self.request, **self.get_form_kwargs())
|
||||
|
||||
def get_context_data(self):
|
||||
events = (
|
||||
TimelineEvent.objects.filter(
|
||||
identity=self.request.identity,
|
||||
type__in=[TimelineEvent.Types.post, TimelineEvent.Types.boost],
|
||||
)
|
||||
.select_related(
|
||||
"subject_post",
|
||||
"subject_post__author",
|
||||
"subject_post__author__domain",
|
||||
"subject_identity",
|
||||
"subject_identity__domain",
|
||||
"subject_post_interaction",
|
||||
"subject_post_interaction__identity",
|
||||
"subject_post_interaction__identity__domain",
|
||||
)
|
||||
.prefetch_related(
|
||||
"subject_post__attachments",
|
||||
"subject_post__mentions",
|
||||
"subject_post__emojis",
|
||||
)
|
||||
.order_by("-published")
|
||||
)
|
||||
events = TimelineService(self.request.identity).home()
|
||||
paginator = Paginator(events, 50)
|
||||
page_number = self.request.GET.get("page")
|
||||
context = {
|
||||
|
@ -80,14 +59,7 @@ class Tag(ListView):
|
|||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_queryset(self):
|
||||
return (
|
||||
Post.objects.public()
|
||||
.filter(author__restriction=Identity.Restriction.none)
|
||||
.tagged_with(self.hashtag)
|
||||
.select_related("author", "author__domain")
|
||||
.prefetch_related("attachments", "mentions")
|
||||
.order_by("-published")
|
||||
)
|
||||
return TimelineService(self.request.identity).hashtag(self.hashtag)
|
||||
|
||||
def get_context_data(self):
|
||||
context = super().get_context_data()
|
||||
|
@ -111,13 +83,7 @@ class Local(ListView):
|
|||
paginate_by = 50
|
||||
|
||||
def get_queryset(self):
|
||||
return (
|
||||
Post.objects.local_public()
|
||||
.filter(author__restriction=Identity.Restriction.none)
|
||||
.select_related("author", "author__domain")
|
||||
.prefetch_related("attachments", "mentions", "emojis")
|
||||
.order_by("-published")
|
||||
)
|
||||
return TimelineService(self.request.identity).local()
|
||||
|
||||
def get_context_data(self):
|
||||
context = super().get_context_data()
|
||||
|
@ -138,15 +104,7 @@ class Federated(ListView):
|
|||
paginate_by = 50
|
||||
|
||||
def get_queryset(self):
|
||||
return (
|
||||
Post.objects.filter(
|
||||
visibility=Post.Visibilities.public, in_reply_to__isnull=True
|
||||
)
|
||||
.filter(author__restriction=Identity.Restriction.none)
|
||||
.select_related("author", "author__domain")
|
||||
.prefetch_related("attachments", "mentions", "emojis")
|
||||
.order_by("-published")
|
||||
)
|
||||
return TimelineService(self.request.identity).federated()
|
||||
|
||||
def get_context_data(self):
|
||||
context = super().get_context_data()
|
||||
|
@ -187,25 +145,7 @@ class Notifications(ListView):
|
|||
for type_name, type in self.notification_types.items():
|
||||
if notification_options.get(type_name, True):
|
||||
types.append(type)
|
||||
return (
|
||||
TimelineEvent.objects.filter(identity=self.request.identity, type__in=types)
|
||||
.order_by("-published")
|
||||
.select_related(
|
||||
"subject_post",
|
||||
"subject_post__author",
|
||||
"subject_post__author__domain",
|
||||
"subject_identity",
|
||||
"subject_identity__domain",
|
||||
"subject_post_interaction",
|
||||
"subject_post_interaction__identity",
|
||||
"subject_post_interaction__identity__domain",
|
||||
)
|
||||
.prefetch_related(
|
||||
"subject_post__emojis",
|
||||
"subject_post__mentions",
|
||||
"subject_post__attachments",
|
||||
)
|
||||
)
|
||||
return TimelineService(self.request.identity).notifications(types)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from activities.models import PostInteraction, TimelineEvent
|
||||
from activities.services import TimelineService
|
||||
from api import schemas
|
||||
from api.decorators import identity_required
|
||||
from api.pagination import MastodonPaginator
|
||||
|
@ -28,13 +29,8 @@ def notifications(
|
|||
requested_types = set(base_types.keys())
|
||||
requested_types.difference_update(excluded_types)
|
||||
# Use that to pull relevant events
|
||||
queryset = (
|
||||
TimelineEvent.objects.filter(
|
||||
identity=request.identity,
|
||||
type__in=[base_types[r] for r in requested_types],
|
||||
)
|
||||
.order_by("-published")
|
||||
.select_related("subject_post", "subject_post__author", "subject_identity")
|
||||
queryset = TimelineService(request.identity).notifications(
|
||||
[base_types[r] for r in requested_types]
|
||||
)
|
||||
paginator = MastodonPaginator(TimelineEvent)
|
||||
events = paginator.paginate(
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from activities.models import Post, PostInteraction, TimelineEvent
|
||||
from activities.models import Post, PostInteraction
|
||||
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 users.models import Identity
|
||||
|
||||
|
||||
@api_router.get("/v1/timelines/home", response=list[schemas.Status])
|
||||
|
@ -16,22 +16,7 @@ def home(
|
|||
limit: int = 20,
|
||||
):
|
||||
paginator = MastodonPaginator(Post)
|
||||
queryset = (
|
||||
TimelineEvent.objects.filter(
|
||||
identity=request.identity,
|
||||
type__in=[TimelineEvent.Types.post],
|
||||
)
|
||||
.select_related(
|
||||
"subject_post",
|
||||
"subject_post__author",
|
||||
"subject_post__author__domain",
|
||||
)
|
||||
.prefetch_related(
|
||||
"subject_post__attachments",
|
||||
"subject_post__mentions",
|
||||
)
|
||||
.order_by("-published")
|
||||
)
|
||||
queryset = TimelineService(request.identity).home()
|
||||
events = paginator.paginate(
|
||||
queryset,
|
||||
min_id=min_id,
|
||||
|
@ -58,16 +43,11 @@ def public(
|
|||
min_id: str | None = None,
|
||||
limit: int = 20,
|
||||
):
|
||||
queryset = (
|
||||
Post.objects.public()
|
||||
.filter(author__restriction=Identity.Restriction.none)
|
||||
.select_related("author")
|
||||
.prefetch_related("attachments")
|
||||
.order_by("-published")
|
||||
)
|
||||
if local:
|
||||
queryset = queryset.filter(local=True)
|
||||
elif remote:
|
||||
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)
|
||||
|
@ -97,14 +77,7 @@ def hashtag(
|
|||
):
|
||||
if limit > 40:
|
||||
limit = 40
|
||||
queryset = (
|
||||
Post.objects.public()
|
||||
.filter(author__restriction=Identity.Restriction.none)
|
||||
.tagged_with(hashtag)
|
||||
.select_related("author")
|
||||
.prefetch_related("attachments")
|
||||
.order_by("-published")
|
||||
)
|
||||
queryset = TimelineService(request.identity).hashtag(hashtag)
|
||||
if local:
|
||||
queryset = queryset.filter(local=True)
|
||||
if only_media:
|
||||
|
|
Loading…
Reference in New Issue