From 3a6bbb874e54ee3ecd6894ed00594fac1afde18e Mon Sep 17 00:00:00 2001 From: magicfelix <felix@felix-zauberer.de> Date: Mon, 3 Feb 2025 08:19:39 +0100 Subject: [PATCH] [DAV] Replace get_dav_objects with get_objects --- aleksis/core/mixins.py | 59 ++++++++++++------------ aleksis/core/models.py | 40 +--------------- aleksis/core/util/dav_handler/base.py | 2 +- aleksis/core/util/dav_handler/generic.py | 9 ++-- aleksis/core/views.py | 16 +++---- 5 files changed, 44 insertions(+), 82 deletions(-) diff --git a/aleksis/core/mixins.py b/aleksis/core/mixins.py index b37e8e40e..437b962f9 100644 --- a/aleksis/core/mixins.py +++ b/aleksis/core/mixins.py @@ -2,7 +2,7 @@ import os import warnings -from collections.abc import Iterable +from collections.abc import Iterable, Sequence from datetime import datetime from hashlib import sha256 from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, Union @@ -12,7 +12,7 @@ from django.conf import settings from django.contrib import messages from django.contrib.auth.views import LoginView, RedirectURLMixin from django.db import models -from django.db.models import JSONField, QuerySet +from django.db.models import JSONField, Q, QuerySet from django.db.models.fields import CharField, TextField from django.forms.forms import BaseForm from django.forms.models import ModelForm, ModelFormMetaclass, fields_for_model @@ -607,21 +607,6 @@ class DAVResource(RegistryObject): for ns, propname in cls.dav_live_props: ElementTree.SubElement(prop, f"{{{ns}}}{propname}") - @classmethod - def get_dav_objects( - cls, request: HttpRequest, objects: Optional[Iterable | QuerySet] = None - ) -> Iterable | QuerySet: - if objects is None: - return [] - return objects - - @classmethod - def get_dav_objects_by_id(cls, id, request: HttpRequest): # noqa: A002 - objects = cls.get_dav_objects(request) - if isinstance(objects, QuerySet): - return objects.filter(id=id) - return list(filter(lambda x: x.id == id, objects)) - @classmethod def get_dav_absolute_url(cls, reference_object, request: HttpRequest) -> str: raise NotImplementedError @@ -816,13 +801,35 @@ class CalendarEventMixin(DAVResource, RegistryObject, is_registry=True): @classmethod def get_objects( cls, - request: Optional[HttpRequest] = None, - params: Optional[dict[str, any]] = None, + request: HttpRequest | None = None, + params: dict[str, any] | None = None, start: Optional[datetime] = None, end: Optional[datetime] = None, - ) -> Iterable: - """Return the objects to create the calendar feed for.""" - raise NotImplementedError + start_qs: QuerySet | None = None, + additional_filter: Q | None = None, + select_related: Sequence | None = None, + prefetch_related: Sequence | None = None, + ) -> QuerySet: + """Return all objects that should be included in the calendar.""" + start_qs = cls.objects if start_qs is None else start_qs + start_qs = start_qs.instance_of(cls) + if not start or not end: + if additional_filter is not None: + qs = start_qs.filter(additional_filter) + if select_related is not None: + qs = start_qs.select_related(*select_related) + if prefetch_related is not None: + qs = start_qs.prefetch_related(*prefetch_related) + else: + qs = cls.objects.with_occurrences( + start, + end, + start_qs=start_qs, + additional_filter=additional_filter, + select_related=select_related, + prefetch_related=prefetch_related, + ) + return qs @classmethod def create_feed( @@ -955,14 +962,6 @@ class CalendarEventMixin(DAVResource, RegistryObject, is_registry=True): def get_dav_verbose_name(cls, request: Optional[HttpRequest] = None) -> str: return str(cls.get_verbose_name()) - @classmethod - def get_dav_objects( - cls, request: HttpRequest, objects: Optional[Iterable | QuerySet] = None - ) -> Iterable | QuerySet: - if objects is None: - objects = cls.get_objects(request) - return super().get_dav_objects(request, objects) - @classmethod def get_dav_file_content( cls, diff --git a/aleksis/core/models.py b/aleksis/core/models.py index d6d1b1041..b05625a83 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -483,12 +483,6 @@ class Person(ContactMixin, ExtensibleModel): ) return qs.filter(additional_filter) if additional_filter else qs - @classmethod - def get_dav_objects( - cls, request: HttpRequest, objects: Optional[QuerySet] = None - ) -> Iterable | QuerySet: - return [person for person in cls.get_objects(request=request, start_qs=objects)] - @classmethod def get_dav_file_content( cls, @@ -497,7 +491,7 @@ class Person(ContactMixin, ExtensibleModel): params: Optional[dict[str, any]] = None, ) -> str: if objects is None: - objects = cls.get_dav_objects(request) + objects = cls.get_objects(request) content = "" for person in objects: content += person.as_vcard(request, params) @@ -1766,38 +1760,6 @@ class CalendarEvent( calendar_alarm.get_alarm(request) for calendar_alarm in reference_object.alarms.all() ] - @classmethod - def get_objects( - cls, - request: HttpRequest | None = None, - params: dict[str, any] | None = None, - start: Optional[datetime] = None, - end: Optional[datetime] = None, - start_qs: QuerySet | None = None, - additional_filter: Q | None = None, - select_related: Sequence | None = None, - prefetch_related: Sequence | None = None, - ) -> QuerySet: - """Return all objects that should be included in the calendar.""" - start_qs = cls.objects if start_qs is None else start_qs - start_qs = start_qs.instance_of(cls) - if not start or not end: - start = timezone.now() - timedelta(days=50) - end = timezone.now() + timedelta(days=50) - qs = cls.objects.with_occurrences( - start, - end, - start_qs=start_qs, - additional_filter=additional_filter, - select_related=select_related, - prefetch_related=prefetch_related, - ) - return qs - - @classmethod - def get_dav_objects_by_id(cls, id, request): # noqa: A002 - return cls.get_objects(request).filter(Q(id=id) | Q(amends__pk=id)) - def save(self, *args, **kwargs): if ( self.datetime_start diff --git a/aleksis/core/util/dav_handler/base.py b/aleksis/core/util/dav_handler/base.py index 87d8ee491..5d97e4c05 100644 --- a/aleksis/core/util/dav_handler/base.py +++ b/aleksis/core/util/dav_handler/base.py @@ -150,7 +150,7 @@ class DAVRequest(ElementHandler, ContentHandler): lambda r: not getattr(r, "_is_registry", False), self.resources ): try: - objs = resource.get_dav_objects(self._request) + objs = resource.get_objects(self._request) except NotImplementedError: objs = [] diff --git a/aleksis/core/util/dav_handler/generic.py b/aleksis/core/util/dav_handler/generic.py index d47ddbf0c..1f57d0b67 100644 --- a/aleksis/core/util/dav_handler/generic.py +++ b/aleksis/core/util/dav_handler/generic.py @@ -120,10 +120,11 @@ class DAVHref(ElementHandler): pk = res.kwargs.get("id") resource = DAVResource.registered_objects_dict[name] - objs = resource.get_dav_objects_by_id(pk, self.request._request) - if len(objs) == 0: - objs = [NotFoundObject(self.content)] - self.request.objects += objs + try: + obj = resource.get_objects(self.request._request).get(pk=pk) + except resource.DoesNotExist: + obj = NotFoundObject(self.content) + self.request.objects = list(self.request.objects).append(obj) class DAVProp(ElementHandler): diff --git a/aleksis/core/views.py b/aleksis/core/views.py index 9cd1719d0..908c12a51 100644 --- a/aleksis/core/views.py +++ b/aleksis/core/views.py @@ -1485,10 +1485,10 @@ class DAVSingleResourceView(DAVResourceView): def propfind(self, request, id, *args, **kwargs): # noqa: A002 resource = self.get_object() - objects = resource.get_dav_objects_by_id(id, request) - - if len(objects) == 0: - raise Http404 + try: + objects = resource.get_objects(request).get(pk=id) + except resource.DoesNotExist as exc: + raise Http404 from exc self._dav_request = DAVRequest(request, resource, objects[0]) @@ -1507,10 +1507,10 @@ class DAVSingleResourceView(DAVResourceView): def get(self, request, name, id, *args, **kwargs): # noqa: A002 resource: DAVResource = self.get_object() - objects = resource.get_dav_objects_by_id(id, request) - - if len(objects) == 0: - raise Http404 + try: + objects = resource.get_objects(request).get(pk=id) + except resource.DoesNotExist as exc: + raise Http404 from exc response = HttpResponse(content_type=resource.get_dav_content_type()) response.write(resource.get_dav_file_content(request, objects=objects)) -- GitLab