56 lines
1.9 KiB
Python
56 lines
1.9 KiB
Python
import json
|
|
import logging
|
|
from pathlib import Path
|
|
from typing import Any, Type
|
|
|
|
from django.core.cache import cache
|
|
from django.core.exceptions import BadRequest
|
|
from django.utils.translation import gettext_lazy as _
|
|
from graphene import Context
|
|
from rest_framework.request import Request
|
|
|
|
from evibes.settings import UNSAFE_CACHE_KEYS
|
|
from vibes_auth.models import User
|
|
|
|
logger = logging.getLogger("django")
|
|
|
|
|
|
def is_safe_cache_key(key: str) -> bool:
|
|
return key not in UNSAFE_CACHE_KEYS
|
|
|
|
|
|
def get_cached_value(user: Type[User], key: str, default: Any = None) -> Any:
|
|
if user.is_staff or user.is_superuser:
|
|
return cache.get(key, default)
|
|
|
|
if is_safe_cache_key(key):
|
|
return cache.get(key, default)
|
|
|
|
return None
|
|
|
|
|
|
def set_cached_value(user: Type[User], key: str, value: object, timeout: int = 3600) -> None | object:
|
|
if user.is_staff or user.is_superuser:
|
|
cache.set(key, value, timeout)
|
|
return value
|
|
|
|
return None
|
|
|
|
|
|
def web_cache(request: Request | Context, key: str, data: dict[str, Any], timeout: int) -> dict[str, Any]:
|
|
if not data and not timeout:
|
|
return {"data": get_cached_value(request.user, key)} # type: ignore [assignment, arg-type]
|
|
if (data and not timeout) or (timeout and not data):
|
|
raise BadRequest(_("both data and timeout are required"))
|
|
if not 0 < int(timeout) < 216000:
|
|
raise BadRequest(_("invalid timeout value, it must be between 0 and 216000 seconds"))
|
|
return {"data": set_cached_value(request.user, key, data, timeout)} # type: ignore [assignment, arg-type]
|
|
|
|
|
|
def set_default_cache() -> None:
|
|
data_dir = Path(__file__).resolve().parent.parent / "data"
|
|
for json_file in data_dir.glob("*.json"):
|
|
with json_file.open("r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
logger.info(f"Setting cache for {json_file.stem}")
|
|
cache.set(json_file.stem, data, timeout=28800)
|