Only cache unauthenticated page views (#117)
This commit is contained in:
parent
b0929214d5
commit
b8460b0acd
@ -1,15 +1,11 @@
|
|||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
|
|
||||||
from core.decorators import per_identity_cache_page
|
|
||||||
from users.decorators import identity_required
|
from users.decorators import identity_required
|
||||||
from users.models import FollowStates
|
from users.models import FollowStates
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(identity_required, name="dispatch")
|
@method_decorator(identity_required, name="dispatch")
|
||||||
@method_decorator(
|
|
||||||
per_identity_cache_page("cache_timeout_page_timeline"), name="dispatch"
|
|
||||||
)
|
|
||||||
class FollowsPage(TemplateView):
|
class FollowsPage(TemplateView):
|
||||||
"""
|
"""
|
||||||
Shows followers/follows.
|
Shows followers/follows.
|
||||||
|
@ -6,13 +6,15 @@ from django.utils.decorators import method_decorator
|
|||||||
from django.views.generic import TemplateView, View
|
from django.views.generic import TemplateView, View
|
||||||
|
|
||||||
from activities.models import Post, PostInteraction, PostInteractionStates, PostStates
|
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 core.ld import canonicalise
|
||||||
from users.decorators import identity_required
|
from users.decorators import identity_required
|
||||||
from users.shortcuts import by_handle_or_404
|
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):
|
class Individual(TemplateView):
|
||||||
|
|
||||||
template_name = "activities/post.html"
|
template_name = "activities/post.html"
|
||||||
|
@ -5,13 +5,12 @@ from django.utils.decorators import method_decorator
|
|||||||
from django.views.generic import FormView, ListView
|
from django.views.generic import FormView, ListView
|
||||||
|
|
||||||
from activities.models import Hashtag, Post, PostInteraction, TimelineEvent
|
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 core.models import Config
|
||||||
from users.decorators import identity_required
|
from users.decorators import identity_required
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(identity_required, name="dispatch")
|
@method_decorator(identity_required, name="dispatch")
|
||||||
@method_decorator(per_identity_cache_page(), name="dispatch")
|
|
||||||
class Home(FormView):
|
class Home(FormView):
|
||||||
|
|
||||||
template_name = "activities/home.html"
|
template_name = "activities/home.html"
|
||||||
@ -64,7 +63,7 @@ class Home(FormView):
|
|||||||
|
|
||||||
|
|
||||||
@method_decorator(
|
@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):
|
class Tag(ListView):
|
||||||
|
|
||||||
@ -102,7 +101,7 @@ class Tag(ListView):
|
|||||||
|
|
||||||
|
|
||||||
@method_decorator(
|
@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):
|
class Local(ListView):
|
||||||
|
|
||||||
@ -130,9 +129,6 @@ class Local(ListView):
|
|||||||
|
|
||||||
|
|
||||||
@method_decorator(identity_required, name="dispatch")
|
@method_decorator(identity_required, name="dispatch")
|
||||||
@method_decorator(
|
|
||||||
per_identity_cache_page("cache_timeout_page_timeline"), name="dispatch"
|
|
||||||
)
|
|
||||||
class Federated(ListView):
|
class Federated(ListView):
|
||||||
|
|
||||||
template_name = "activities/federated.html"
|
template_name = "activities/federated.html"
|
||||||
|
@ -1,34 +1,72 @@
|
|||||||
|
from collections.abc import Callable
|
||||||
from functools import partial, wraps
|
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 django.views.decorators.cache import cache_page as dj_cache_page
|
||||||
|
|
||||||
from core.models import Config
|
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(
|
def cache_page(
|
||||||
timeout: int | str = "cache_timeout_page_default",
|
timeout: int | str = "cache_timeout_page_default",
|
||||||
*,
|
*,
|
||||||
per_identity: bool = False,
|
|
||||||
key_prefix: str = "",
|
key_prefix: str = "",
|
||||||
|
public_only: bool = False,
|
||||||
|
vary_by: VaryByFunc | list[VaryByFunc] | None = None,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Decorator for views that caches the page result.
|
Decorator for views that caches the page result.
|
||||||
timeout can either be the number of seconds or the name of a SystemOptions
|
timeout can either be the number of seconds or the name of a SystemOptions
|
||||||
value.
|
value.
|
||||||
|
If public_only is True, requests with an identity are not cached.
|
||||||
"""
|
"""
|
||||||
_timeout = timeout
|
_timeout = timeout
|
||||||
|
_prefix = key_prefix
|
||||||
|
if callable(vary_by):
|
||||||
|
vary_by = [vary_by]
|
||||||
|
|
||||||
def decorator(function):
|
def decorator(function):
|
||||||
@wraps(function)
|
@wraps(function)
|
||||||
def inner(request, *args, **kwargs):
|
def inner(request, *args, **kwargs):
|
||||||
prefix = key_prefix
|
if public_only:
|
||||||
if per_identity:
|
if request.user.is_authenticated:
|
||||||
identity_id = request.identity.pk if request.identity else "0"
|
return function(request, *args, **kwargs)
|
||||||
prefix = f"{key_prefix or ''}:ident{identity_id}"
|
|
||||||
|
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):
|
if isinstance(_timeout, str):
|
||||||
timeout = getattr(Config.system, _timeout)
|
timeout = getattr(Config.system, _timeout)
|
||||||
else:
|
else:
|
||||||
timeout = _timeout
|
timeout = _timeout
|
||||||
|
|
||||||
return dj_cache_page(timeout=timeout, key_prefix=prefix)(function)(
|
return dj_cache_page(timeout=timeout, key_prefix=prefix)(function)(
|
||||||
request, *args, **kwargs
|
request, *args, **kwargs
|
||||||
)
|
)
|
||||||
@ -38,4 +76,4 @@ def cache_page(
|
|||||||
return decorator
|
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])
|
||||||
|
@ -18,7 +18,7 @@ def homepage(request):
|
|||||||
return LoggedOutHomepage.as_view()(request)
|
return LoggedOutHomepage.as_view()(request)
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(cache_page(), name="dispatch")
|
@method_decorator(cache_page(public_only=True), name="dispatch")
|
||||||
class LoggedOutHomepage(TemplateView):
|
class LoggedOutHomepage(TemplateView):
|
||||||
|
|
||||||
template_name = "index.html"
|
template_name = "index.html"
|
||||||
|
@ -10,7 +10,7 @@ from django.utils.decorators import method_decorator
|
|||||||
from django.views.generic import FormView, ListView, TemplateView, View
|
from django.views.generic import FormView, ListView, TemplateView, View
|
||||||
|
|
||||||
from activities.models import Post, PostInteraction
|
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.ld import canonicalise
|
||||||
from core.models import Config
|
from core.models import Config
|
||||||
from users.decorators import identity_required
|
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
|
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):
|
class ViewIdentity(ListView):
|
||||||
"""
|
"""
|
||||||
Shows identity profile pages, and also acts as the Actor endpoint when
|
Shows identity profile pages, and also acts as the Actor endpoint when
|
||||||
@ -88,7 +88,7 @@ class ViewIdentity(ListView):
|
|||||||
|
|
||||||
|
|
||||||
@method_decorator(
|
@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):
|
class IdentityFeed(Feed):
|
||||||
"""
|
"""
|
||||||
|
Reference in New Issue
Block a user