import json from django.contrib.admin.views.decorators import staff_member_required from django.db.models import Count from django.http import JsonResponse from django.shortcuts import render, HttpResponse, redirect from django.utils import timezone from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST from datetime import timedelta from .models import UsageEvent from .utils import parse_user_agent # Create your views here. def index(request): return render(request, "app/base.html") def install(request): return render(request, "app/install.html") def home(request): return redirect("/app/v262") def login(request): return render(request, "app/login.html") def v1321(request): return redirect("/app/v262") def v1322(request): return redirect("/app/v262") def v133(request): return redirect("/app/v262") def v1332(request): return redirect("/app/v262") def v1333(request): return redirect("/app/v262") def v1334(request): return redirect("/app/v262") def v1335(request): return redirect("/app/v262") def v1340(request): return redirect("/app/v262") def v260(request): return redirect("/app/v262") def v261(request): return redirect("/app/v262") def v262(request): return render(request, "app/home.html") # --------------------------------------------------------------------------- # Anonyme Nutzungsstatistik fürs Admin-Dashboard # --------------------------------------------------------------------------- @csrf_exempt @require_POST def track_usage(request): """Nimmt ein anonymes Nutzungssignal entgegen (ein Aufruf pro Gerät und Tag, siehe home01.js: pingUsageIfNeeded()). Kein CSRF-Schutz nötig, da rein additiv und ohne jeden Personenbezug - device_id kommt aus dem localStorage des Geräts.""" try: data = json.loads(request.body or "{}") except json.JSONDecodeError: data = {} device_id = str(data.get("device_id", "")).strip()[:64] if not device_id: return JsonResponse({"ok": False, "error": "device_id fehlt"}, status=400) user_agent = request.META.get("HTTP_USER_AGENT", "") platform, browser = parse_user_agent(user_agent) UsageEvent.objects.create( device_id=device_id, app_version=str(data.get("app_version", ""))[:20], user_agent=user_agent[:1000], platform=platform, browser=browser, is_standalone=bool(data.get("standalone", False)), ) return JsonResponse({"ok": True}) @staff_member_required def usage_dashboard(request): """Nutzungs-Dashboard für Admins - nur für angemeldete Staff-Nutzer (Django-Admin-Login).""" now = timezone.now() today_start = now.replace(hour=0, minute=0, second=0, microsecond=0) events = UsageEvent.objects.all() context = { "unique_devices_total": events.values("device_id").distinct().count(), "devices_today": events.filter(created_at__gte=today_start).values("device_id").distinct().count(), "devices_7d": events.filter(created_at__gte=now - timedelta(days=7)).values("device_id").distinct().count(), "devices_30d": events.filter(created_at__gte=now - timedelta(days=30)).values("device_id").distinct().count(), "standalone_count": events.filter(is_standalone=True).values("device_id").distinct().count(), "by_platform": events.values("platform").annotate(count=Count("device_id", distinct=True)).order_by("-count"), "by_browser": events.values("browser").annotate(count=Count("device_id", distinct=True)).order_by("-count"), "recent_events": events[:30], } return render(request, "app/dashboard.html", context)