Scaffold containerized Django/Wagtail app with core features

This commit is contained in:
Codex_B
2026-02-28 11:52:59 +00:00
parent 62323abd62
commit b5f0f40c4c
84 changed files with 1647 additions and 0 deletions

59
apps/core/consent.py Normal file
View File

@@ -0,0 +1,59 @@
from __future__ import annotations
import time
from dataclasses import dataclass
from urllib.parse import parse_qs, urlencode
from django.conf import settings
CONSENT_COOKIE_NAME = "nhAiConsent"
@dataclass
class ConsentState:
analytics: bool = False
advertising: bool = False
policy_version: int = 0
timestamp: int = 0
@property
def requires_prompt(self) -> bool:
return self.policy_version != settings.CONSENT_POLICY_VERSION
class ConsentService:
@staticmethod
def get_consent(request) -> ConsentState:
raw = request.COOKIES.get(CONSENT_COOKIE_NAME, "")
if not raw:
return ConsentState()
try:
data = {k: v[0] for k, v in parse_qs(raw).items()}
return ConsentState(
analytics=data.get("a", "0") == "1",
advertising=data.get("d", "0") == "1",
policy_version=int(data.get("v", "0")),
timestamp=int(data.get("ts", "0")),
)
except (ValueError, AttributeError):
return ConsentState()
@staticmethod
def set_consent(response, *, analytics: bool, advertising: bool) -> None:
payload = urlencode(
{
"a": int(analytics),
"d": int(advertising),
"v": settings.CONSENT_POLICY_VERSION,
"ts": int(time.time()),
}
)
response.set_cookie(
CONSENT_COOKIE_NAME,
payload,
max_age=60 * 60 * 24 * 365,
httponly=False,
samesite="Lax",
secure=not settings.DEBUG,
)