summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/decorators.py41
-rw-r--r--core/middleware.py12
-rw-r--r--core/models/config.py5
-rw-r--r--core/views.py3
4 files changed, 60 insertions, 1 deletions
diff --git a/core/decorators.py b/core/decorators.py
new file mode 100644
index 0000000..4934b60
--- /dev/null
+++ b/core/decorators.py
@@ -0,0 +1,41 @@
+from functools import partial, wraps
+
+from django.views.decorators.cache import cache_page as dj_cache_page
+
+from core.models import Config
+
+
+def cache_page(
+ timeout: int | str = "cache_timeout_page_default",
+ *,
+ per_identity: bool = False,
+ key_prefix: str = "",
+):
+ """
+ Decorator for views that caches the page result.
+ timeout can either be the number of seconds or the name of a SystemOptions
+ value.
+ """
+ if isinstance(timeout, str):
+ timeout = Config.lazy_system_value(timeout)
+
+ 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}"
+ _timeout = timeout
+ if callable(_timeout):
+ _timeout = _timeout()
+ return dj_cache_page(timeout=_timeout, key_prefix=prefix)(function)(
+ request, *args, **kwargs
+ )
+
+ return inner
+
+ return decorator
+
+
+per_identity_cache_page = partial(cache_page, per_identity=True)
diff --git a/core/middleware.py b/core/middleware.py
index 08c28fa..bd89d1c 100644
--- a/core/middleware.py
+++ b/core/middleware.py
@@ -1,3 +1,5 @@
+from time import time
+
from django.core.exceptions import MiddlewareNotUsed
from core import sentry
@@ -9,11 +11,19 @@ class ConfigLoadingMiddleware:
Caches the system config every request
"""
+ refresh_interval: float = 30.0
+
def __init__(self, get_response):
self.get_response = get_response
+ self.config_ts: float = 0.0
def __call__(self, request):
- Config.system = Config.load_system()
+ if (
+ not getattr(Config, "system", None)
+ or (time() - self.config_ts) >= self.refresh_interval
+ ):
+ Config.system = Config.load_system()
+ self.config_ts = time()
response = self.get_response(request)
return response
diff --git a/core/models/config.py b/core/models/config.py
index dd7da9f..b18471e 100644
--- a/core/models/config.py
+++ b/core/models/config.py
@@ -218,6 +218,11 @@ class Config(models.Model):
hashtag_unreviewed_are_public: bool = True
hashtag_stats_max_age: int = 60 * 60
+ cache_timeout_page_default: int = 60
+ cache_timeout_page_timeline: int = 60 * 3
+ cache_timeout_page_post: int = 60 * 2
+ cache_timeout_identity_feed: int = 60 * 5
+
restricted_usernames: str = "admin\nadmins\nadministrator\nadministrators\nsystem\nroot\nannounce\nannouncement\nannouncements"
class UserOptions(pydantic.BaseModel):
diff --git a/core/views.py b/core/views.py
index 889fa27..ea8a1ca 100644
--- a/core/views.py
+++ b/core/views.py
@@ -1,8 +1,10 @@
from django.http import JsonResponse
from django.templatetags.static import static
+from django.utils.decorators import method_decorator
from django.views.generic import TemplateView, View
from activities.views.timelines import Home
+from core.decorators import cache_page
from users.models import Identity
@@ -13,6 +15,7 @@ def homepage(request):
return LoggedOutHomepage.as_view()(request)
+@method_decorator(cache_page(), name="dispatch")
class LoggedOutHomepage(TemplateView):
template_name = "index.html"