mirror of
https://github.com/narrrl/holy-flavor-rater.git
synced 2026-11-04 17:07:01 +01:00
146 lines
5.8 KiB
Python
146 lines
5.8 KiB
Python
from django.conf import settings
|
|
from django.core.mail import send_mail
|
|
from rest_framework import permissions, status, viewsets
|
|
from rest_framework.decorators import action
|
|
from rest_framework.request import Request
|
|
from rest_framework.response import Response
|
|
|
|
from api.models import Job, Rating, Reply, SystemConfig, Ticket, User
|
|
from api.serializers import (
|
|
AdminUserDetailSerializer,
|
|
AdminUserListSerializer,
|
|
JobSerializer,
|
|
SystemConfigSerializer,
|
|
)
|
|
|
|
|
|
class AdminViewSet(viewsets.ViewSet):
|
|
permission_classes = [permissions.IsAdminUser]
|
|
|
|
@action(detail=False, methods=["get"])
|
|
def stats(self, request: Request) -> Response:
|
|
return Response(
|
|
{
|
|
"total_users": User.objects.count(),
|
|
"total_ratings": Rating.objects.count(),
|
|
"total_replies": Reply.objects.count(),
|
|
"open_tickets": Ticket.objects.filter(status="open").count(),
|
|
"email_config": {
|
|
"host": getattr(settings, "EMAIL_HOST", "None"),
|
|
"port": getattr(settings, "EMAIL_PORT", "None"),
|
|
"use_tls": getattr(settings, "EMAIL_USE_TLS", False),
|
|
"use_ssl": getattr(settings, "EMAIL_USE_SSL", False),
|
|
"skip_verify": getattr(settings, "EMAIL_SKIP_CERT_VERIFICATION", False),
|
|
},
|
|
"server_info": {
|
|
"debug": settings.DEBUG,
|
|
"allowed_hosts": settings.ALLOWED_HOSTS,
|
|
"frontend_url": getattr(settings, "FRONTEND_URL", "Not set"),
|
|
"media_root": str(settings.MEDIA_ROOT),
|
|
"static_root": str(settings.STATIC_ROOT),
|
|
},
|
|
}
|
|
)
|
|
|
|
@action(detail=False, methods=["get", "patch"])
|
|
def config(self, request: Request) -> Response:
|
|
config = SystemConfig.get_solo()
|
|
if request.method == "PATCH":
|
|
serializer = SystemConfigSerializer(config, data=request.data, partial=True)
|
|
serializer.is_valid(raise_exception=True)
|
|
serializer.save()
|
|
return Response(serializer.data)
|
|
|
|
return Response(SystemConfigSerializer(config).data)
|
|
|
|
@action(detail=False, methods=["get"])
|
|
def jobs(self, request: Request) -> Response:
|
|
for job_type, _ in Job.JOB_TYPES:
|
|
Job.objects.get_or_create(name=job_type)
|
|
|
|
jobs = Job.objects.all().order_by("name")
|
|
return Response(JobSerializer(jobs, many=True).data)
|
|
|
|
@action(detail=True, methods=["post"])
|
|
def trigger_job(self, request: Request, pk=None) -> Response:
|
|
try:
|
|
job = Job.objects.get(pk=pk)
|
|
job.status = "pending"
|
|
job.save()
|
|
return Response({"status": "Job queued"})
|
|
except Job.DoesNotExist:
|
|
return Response(status=status.HTTP_404_NOT_FOUND)
|
|
|
|
@action(detail=True, methods=["patch"])
|
|
def update_job_schedule(self, request: Request, pk=None) -> Response:
|
|
try:
|
|
job = Job.objects.get(pk=pk)
|
|
interval = request.data.get("interval_hours")
|
|
next_run = request.data.get("next_run")
|
|
|
|
if interval is not None:
|
|
job.interval_hours = int(interval)
|
|
|
|
if next_run is not None:
|
|
from django.utils import timezone
|
|
from django.utils.dateparse import parse_datetime
|
|
|
|
parsed_dt = parse_datetime(next_run)
|
|
if parsed_dt:
|
|
if timezone.is_naive(parsed_dt):
|
|
job.next_run = timezone.make_aware(
|
|
parsed_dt, timezone.get_current_timezone()
|
|
)
|
|
else:
|
|
job.next_run = parsed_dt
|
|
elif interval is not None and job.interval_hours > 0 and not job.next_run:
|
|
from django.utils import timezone
|
|
|
|
job.next_run = timezone.now()
|
|
|
|
job.save()
|
|
return Response(JobSerializer(job).data)
|
|
except Job.DoesNotExist:
|
|
return Response(status=status.HTTP_404_NOT_FOUND)
|
|
|
|
@action(detail=False, methods=["post"])
|
|
def send_test_email(self, request: Request) -> Response:
|
|
try:
|
|
send_mail(
|
|
"Holy Flavors Admin Test Email",
|
|
(
|
|
f"This is a test email sent to {request.user.email} from the "
|
|
f"Holy Flavors Admin Interface."
|
|
),
|
|
settings.DEFAULT_FROM_EMAIL,
|
|
[request.user.email],
|
|
fail_silently=False,
|
|
)
|
|
return Response({"status": "Test email sent!"})
|
|
except Exception as e:
|
|
return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
|
|
@action(detail=False, methods=["get"])
|
|
def users(self, request: Request) -> Response:
|
|
users = User.objects.all().prefetch_related("ips").order_by("-date_joined")
|
|
return Response(AdminUserListSerializer(users, many=True).data)
|
|
|
|
@action(detail=True, methods=["get", "patch", "delete"])
|
|
def user_detail(self, request: Request, pk=None) -> Response:
|
|
try:
|
|
user = User.objects.get(pk=pk)
|
|
except User.DoesNotExist:
|
|
return Response(status=status.HTTP_404_NOT_FOUND)
|
|
|
|
if request.method == "GET":
|
|
return Response(AdminUserDetailSerializer(user, context={"request": request}).data)
|
|
elif request.method == "PATCH":
|
|
is_active = request.data.get("is_active")
|
|
if is_active is not None:
|
|
user.is_active = is_active
|
|
user.save()
|
|
return Response(AdminUserDetailSerializer(user, context={"request": request}).data)
|
|
elif request.method == "DELETE":
|
|
user.delete()
|
|
return Response(status=status.HTTP_204_NO_CONTENT)
|