"""Project-level views every service exposes: health, timezone, legal pages.""" from __future__ import annotations from functools import lru_cache from zoneinfo import available_timezones from django.contrib import messages from django.db import connection from django.http import JsonResponse from django.shortcuts import redirect, render from django.urls import reverse from django.utils import timezone from django.utils.http import url_has_allowed_host_and_scheme from django.utils.translation import gettext as _ from .context_processors import DEFAULT_COMMON_TIMEZONES @lru_cache(maxsize=1) def _timezone_name_options(): try: names = sorted(available_timezones()) except Exception: names = list(DEFAULT_COMMON_TIMEZONES) preferred = ["UTC", "Europe/Moscow", "Asia/Yakutsk"] ordered = [n for n in preferred if n in names] ordered += [n for n in names if n not in ordered] return ordered def _safe_next_url(request, candidate): if candidate and url_has_allowed_host_and_scheme( candidate, allowed_hosts={request.get_host()}, require_https=request.is_secure(), ): return candidate return reverse("timezone-preferences") def privacy_policy(request): return render(request, "privacy_policy.html") def cookie_policy(request): return render(request, "cookie_policy.html") def timezone_preferences(request): timezone_names = _timezone_name_options() timezone_set = set(timezone_names) selected_timezone = request.session.get("user_timezone", "UTC") if selected_timezone not in timezone_set: selected_timezone = "UTC" if request.method == "POST": selected_timezone = (request.POST.get("timezone") or "UTC").strip() if selected_timezone not in timezone_set: messages.error(request, _("Selected time zone is not supported.")) else: request.session["user_timezone"] = selected_timezone request.session.modified = True messages.success(request, _("Time zone preference saved.")) return redirect(_safe_next_url(request, request.POST.get("next"))) return render(request, "timezone_preferences.html", { "timezone_names": timezone_names, "selected_timezone": selected_timezone, "next_url": _safe_next_url( request, request.GET.get("next") or request.META.get("HTTP_REFERER"), ), }) def health_check(request): """Swarm healthcheck target: it must answer without a database, not raise.""" try: with connection.cursor() as cursor: cursor.execute("SELECT 1") return JsonResponse({ "status": "healthy", "timestamp": timezone.now().isoformat(), "database": "connected", }) except Exception as exc: return JsonResponse( { "status": "unhealthy", "timestamp": timezone.now().isoformat(), "database": "disconnected", "error": str(exc), }, status=503, )