summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activities/views/follows.py4
-rw-r--r--activities/views/posts.py6
-rw-r--r--activities/views/timelines.py10
-rw-r--r--core/decorators.py50
-rw-r--r--core/views.py2
-rw-r--r--users/views/identity.py6
6 files changed, 55 insertions, 23 deletions
diff --git a/activities/views/follows.py b/activities/views/follows.py
index 841c8cc..44d8adc 100644
--- a/activities/views/follows.py
+++ b/activities/views/follows.py
@@ -1,15 +1,11 @@
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView
-from core.decorators import per_identity_cache_page
from users.decorators import identity_required
from users.models import FollowStates
@method_decorator(identity_required, name="dispatch")
-@method_decorator(
- per_identity_cache_page("cache_timeout_page_timeline"), name="dispatch"
-)
class FollowsPage(TemplateView):
"""
Shows followers/follows.
diff --git a/activities/views/posts.py b/activities/views/posts.py
index adc732c..d343567 100644
--- a/activities/views/posts.py
+++ b/activities/views/posts.py
@@ -6,13 +6,15 @@ from django.utils.decorators import method_decorator
from django.views.generic import TemplateView, View
from activities.models import Post, PostInteraction, PostInteractionStates, PostStates
-from core.decorators import per_identity_cache_page
+from core.decorators import cache_page_by_ap_json
from core.ld import canonicalise
from users.decorators import identity_required
from users.shortcuts import by_handle_or_404
-@method_decorator(per_identity_cache_page("cache_timeout_page_post"), name="dispatch")
+@method_decorator(
+ cache_page_by_ap_json("cache_timeout_page_post", public_only=True), name="dispatch"
+)
class Individual(TemplateView):
template_name = "activities/post.html"
diff --git a/activities/views/timelines.py b/activities/views/timelines.py
index 2b456ad..711c357 100644
--- a/activities/views/timelines.py
+++ b/activities/views/timelines.py
@@ -5,13 +5,12 @@ from django.utils.decorators import method_decorator
from django.views.generic import FormView, ListView
from activities.models import Hashtag, Post, PostInteraction, TimelineEvent
-from core.decorators import per_identity_cache_page
+from core.decorators import cache_page
from core.models import Config
from users.decorators import identity_required
@method_decorator(identity_required, name="dispatch")
-@method_decorator(per_identity_cache_page(), name="dispatch")
class Home(FormView):
template_name = "activities/home.html"
@@ -64,7 +63,7 @@ class Home(FormView):
@method_decorator(
- per_identity_cache_page("cache_timeout_page_timeline"), name="dispatch"
+ cache_page("cache_timeout_page_timeline", public_only=True), name="dispatch"
)
class Tag(ListView):
@@ -102,7 +101,7 @@ class Tag(ListView):
@method_decorator(
- per_identity_cache_page("cache_timeout_page_timeline"), name="dispatch"
+ cache_page("cache_timeout_page_timeline", public_only=True), name="dispatch"
)
class Local(ListView):
@@ -130,9 +129,6 @@ class Local(ListView):
@method_decorator(identity_required, name="dispatch")
-@method_decorator(
- per_identity_cache_page("cache_timeout_page_timeline"), name="dispatch"
-)
class Federated(ListView):
template_name = "activities/federated.html"
diff --git a/core/decorators.py b/core/decorators.py
index fece564..dc8d4d2 100644
--- a/core/decorators.py
+++ b/core/decorators.py
@@ -1,34 +1,72 @@
+from collections.abc import Callable
from functools import partial, wraps
+from typing import ParamSpecArgs, ParamSpecKwargs
+from django.http import HttpRequest
from django.views.decorators.cache import cache_page as dj_cache_page
from core.models import Config
+VaryByFunc = Callable[[HttpRequest, ParamSpecArgs, ParamSpecKwargs], str]
+
+
+def vary_by_ap_json(request, *args, **kwargs) -> str:
+ """
+ Return a cache usable string token that is different based upon Accept
+ header.
+ """
+ if request.ap_json:
+ return "ap_json"
+ return "not_ap"
+
+
+def vary_by_identity(request, *args, **kwargs) -> str:
+ """
+ Return a cache usable string token that is different based upon the
+ request.identity
+ """
+ if request.identity:
+ return f"ident{request.identity.pk}"
+ return "identNone"
+
def cache_page(
timeout: int | str = "cache_timeout_page_default",
*,
- per_identity: bool = False,
key_prefix: str = "",
+ public_only: bool = False,
+ vary_by: VaryByFunc | list[VaryByFunc] | None = None,
):
"""
Decorator for views that caches the page result.
timeout can either be the number of seconds or the name of a SystemOptions
value.
+ If public_only is True, requests with an identity are not cached.
"""
_timeout = timeout
+ _prefix = key_prefix
+ if callable(vary_by):
+ vary_by = [vary_by]
def decorator(function):
@wraps(function)
def inner(request, *args, **kwargs):
- prefix = key_prefix
- if per_identity:
- identity_id = request.identity.pk if request.identity else "0"
- prefix = f"{key_prefix or ''}:ident{identity_id}"
+ if public_only:
+ if request.user.is_authenticated:
+ return function(request, *args, **kwargs)
+
+ prefix = [_prefix]
+
+ if isinstance(vary_by, list):
+ prefix.extend([vfunc(request, *args, **kwargs) for vfunc in vary_by])
+
+ prefix = "".join(prefix)
+
if isinstance(_timeout, str):
timeout = getattr(Config.system, _timeout)
else:
timeout = _timeout
+
return dj_cache_page(timeout=timeout, key_prefix=prefix)(function)(
request, *args, **kwargs
)
@@ -38,4 +76,4 @@ def cache_page(
return decorator
-per_identity_cache_page = partial(cache_page, per_identity=True)
+cache_page_by_ap_json = partial(cache_page, vary_by=[vary_by_ap_json])
diff --git a/core/views.py b/core/views.py
index a09d925..2772eb8 100644
--- a/core/views.py
+++ b/core/views.py
@@ -18,7 +18,7 @@ def homepage(request):
return LoggedOutHomepage.as_view()(request)
-@method_decorator(cache_page(), name="dispatch")
+@method_decorator(cache_page(public_only=True), name="dispatch")
class LoggedOutHomepage(TemplateView):
template_name = "index.html"
diff --git a/users/views/identity.py b/users/views/identity.py
index 4996ad7..4ca230a 100644
--- a/users/views/identity.py
+++ b/users/views/identity.py
@@ -10,7 +10,7 @@ from django.utils.decorators import method_decorator
from django.views.generic import FormView, ListView, TemplateView, View
from activities.models import Post, PostInteraction
-from core.decorators import per_identity_cache_page
+from core.decorators import cache_page, cache_page_by_ap_json
from core.ld import canonicalise
from core.models import Config
from users.decorators import identity_required
@@ -18,7 +18,7 @@ from users.models import Domain, Follow, FollowStates, Identity, IdentityStates
from users.shortcuts import by_handle_or_404
-@method_decorator(per_identity_cache_page(), name="dispatch")
+@method_decorator(cache_page_by_ap_json(public_only=True), name="dispatch")
class ViewIdentity(ListView):
"""
Shows identity profile pages, and also acts as the Actor endpoint when
@@ -88,7 +88,7 @@ class ViewIdentity(ListView):
@method_decorator(
- per_identity_cache_page("cache_timeout_identity_feed"), name="__call__"
+ cache_page("cache_timeout_identity_feed", public_only=True), name="__call__"
)
class IdentityFeed(Feed):
"""