Move timelines to a service class

pull/226/head
Andrew Godwin 2022-12-21 19:47:48 +00:00
rodzic bf5a46df38
commit e2371a3cd7
5 zmienionych plików z 108 dodań i 109 usunięć

Wyświetl plik

@ -1,2 +1,3 @@
from .post import PostService # noqa from .post import PostService # noqa
from .search import SearchService # noqa from .search import SearchService # noqa
from .timeline import TimelineService # noqa

Wyświetl plik

@ -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",
)
)

Wyświetl plik

@ -3,10 +3,10 @@ from django.shortcuts import get_object_or_404, redirect
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.generic import ListView, TemplateView 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 core.decorators import cache_page
from users.decorators import identity_required from users.decorators import identity_required
from users.models import Identity
from .compose import Compose from .compose import Compose
@ -22,28 +22,7 @@ class Home(TemplateView):
return self.form_class(request=self.request, **self.get_form_kwargs()) return self.form_class(request=self.request, **self.get_form_kwargs())
def get_context_data(self): def get_context_data(self):
events = ( events = TimelineService(self.request.identity).home()
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")
)
paginator = Paginator(events, 50) paginator = Paginator(events, 50)
page_number = self.request.GET.get("page") page_number = self.request.GET.get("page")
context = { context = {
@ -80,14 +59,7 @@ class Tag(ListView):
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
return ( return TimelineService(self.request.identity).hashtag(self.hashtag)
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")
)
def get_context_data(self): def get_context_data(self):
context = super().get_context_data() context = super().get_context_data()
@ -111,13 +83,7 @@ class Local(ListView):
paginate_by = 50 paginate_by = 50
def get_queryset(self): def get_queryset(self):
return ( return TimelineService(self.request.identity).local()
Post.objects.local_public()
.filter(author__restriction=Identity.Restriction.none)
.select_related("author", "author__domain")
.prefetch_related("attachments", "mentions", "emojis")
.order_by("-published")
)
def get_context_data(self): def get_context_data(self):
context = super().get_context_data() context = super().get_context_data()
@ -138,15 +104,7 @@ class Federated(ListView):
paginate_by = 50 paginate_by = 50
def get_queryset(self): def get_queryset(self):
return ( return TimelineService(self.request.identity).federated()
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")
)
def get_context_data(self): def get_context_data(self):
context = super().get_context_data() context = super().get_context_data()
@ -187,25 +145,7 @@ class Notifications(ListView):
for type_name, type in self.notification_types.items(): for type_name, type in self.notification_types.items():
if notification_options.get(type_name, True): if notification_options.get(type_name, True):
types.append(type) types.append(type)
return ( return TimelineService(self.request.identity).notifications(types)
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",
)
)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)

Wyświetl plik

@ -1,4 +1,5 @@
from activities.models import PostInteraction, TimelineEvent from activities.models import PostInteraction, TimelineEvent
from activities.services import TimelineService
from api import schemas from api import schemas
from api.decorators import identity_required from api.decorators import identity_required
from api.pagination import MastodonPaginator from api.pagination import MastodonPaginator
@ -28,13 +29,8 @@ def notifications(
requested_types = set(base_types.keys()) requested_types = set(base_types.keys())
requested_types.difference_update(excluded_types) requested_types.difference_update(excluded_types)
# Use that to pull relevant events # Use that to pull relevant events
queryset = ( queryset = TimelineService(request.identity).notifications(
TimelineEvent.objects.filter( [base_types[r] for r in requested_types]
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")
) )
paginator = MastodonPaginator(TimelineEvent) paginator = MastodonPaginator(TimelineEvent)
events = paginator.paginate( events = paginator.paginate(

Wyświetl plik

@ -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 import schemas
from api.decorators import identity_required from api.decorators import identity_required
from api.pagination import MastodonPaginator from api.pagination import MastodonPaginator
from api.views.base import api_router from api.views.base import api_router
from users.models import Identity
@api_router.get("/v1/timelines/home", response=list[schemas.Status]) @api_router.get("/v1/timelines/home", response=list[schemas.Status])
@ -16,22 +16,7 @@ def home(
limit: int = 20, limit: int = 20,
): ):
paginator = MastodonPaginator(Post) paginator = MastodonPaginator(Post)
queryset = ( queryset = TimelineService(request.identity).home()
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")
)
events = paginator.paginate( events = paginator.paginate(
queryset, queryset,
min_id=min_id, min_id=min_id,
@ -58,16 +43,11 @@ def public(
min_id: str | None = None, min_id: str | None = None,
limit: int = 20, limit: int = 20,
): ):
queryset = (
Post.objects.public()
.filter(author__restriction=Identity.Restriction.none)
.select_related("author")
.prefetch_related("attachments")
.order_by("-published")
)
if local: if local:
queryset = queryset.filter(local=True) queryset = TimelineService(request.identity).local()
elif remote: else:
queryset = TimelineService(request.identity).federated()
if remote:
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)
@ -97,14 +77,7 @@ def hashtag(
): ):
if limit > 40: if limit > 40:
limit = 40 limit = 40
queryset = ( queryset = TimelineService(request.identity).hashtag(hashtag)
Post.objects.public()
.filter(author__restriction=Identity.Restriction.none)
.tagged_with(hashtag)
.select_related("author")
.prefetch_related("attachments")
.order_by("-published")
)
if local: if local:
queryset = queryset.filter(local=True) queryset = queryset.filter(local=True)
if only_media: if only_media: