110 lines
3.7 KiB
Python
110 lines
3.7 KiB
Python
from __future__ import annotations
|
|
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
from django.db.models import Count, Max, Q
|
|
from django.shortcuts import render
|
|
from django.views import View
|
|
|
|
from core.models import (
|
|
ContactAvailabilityEvent,
|
|
ContactAvailabilitySettings,
|
|
)
|
|
|
|
|
|
def _to_int(value, default=0):
|
|
try:
|
|
return int(value)
|
|
except Exception:
|
|
return int(default)
|
|
|
|
|
|
def _to_bool(value, default=False):
|
|
if value is None:
|
|
return bool(default)
|
|
text = str(value).strip().lower()
|
|
if text in {"1", "true", "yes", "on", "y"}:
|
|
return True
|
|
if text in {"0", "false", "no", "off", "n"}:
|
|
return False
|
|
return bool(default)
|
|
|
|
|
|
class AvailabilitySettingsPage(LoginRequiredMixin, View):
|
|
template_name = "pages/availability-settings.html"
|
|
|
|
def _settings(self, request):
|
|
row, _ = ContactAvailabilitySettings.objects.get_or_create(user=request.user)
|
|
return row
|
|
|
|
def post(self, request):
|
|
row = self._settings(request)
|
|
row.enabled = _to_bool(request.POST.get("enabled"), row.enabled)
|
|
row.show_in_chat = _to_bool(request.POST.get("show_in_chat"), row.show_in_chat)
|
|
row.show_in_groups = _to_bool(
|
|
request.POST.get("show_in_groups"), row.show_in_groups
|
|
)
|
|
row.inference_enabled = _to_bool(
|
|
request.POST.get("inference_enabled"), row.inference_enabled
|
|
)
|
|
row.retention_days = max(1, _to_int(request.POST.get("retention_days"), 90))
|
|
row.fade_threshold_seconds = max(
|
|
30, _to_int(request.POST.get("fade_threshold_seconds"), 900)
|
|
)
|
|
row.save(
|
|
update_fields=[
|
|
"enabled",
|
|
"show_in_chat",
|
|
"show_in_groups",
|
|
"inference_enabled",
|
|
"retention_days",
|
|
"fade_threshold_seconds",
|
|
"updated_at",
|
|
]
|
|
)
|
|
return self.get(request)
|
|
|
|
def get(self, request):
|
|
settings_row = self._settings(request)
|
|
contact_stats = list(
|
|
ContactAvailabilityEvent.objects.filter(
|
|
user=request.user, person__isnull=False
|
|
)
|
|
.values("person_id", "person__name", "service")
|
|
.annotate(
|
|
total_events=Count("id"),
|
|
available_events=Count(
|
|
"id", filter=Q(availability_state="available")
|
|
),
|
|
fading_events=Count("id", filter=Q(availability_state="fading")),
|
|
unavailable_events=Count(
|
|
"id", filter=Q(availability_state="unavailable")
|
|
),
|
|
unknown_events=Count("id", filter=Q(availability_state="unknown")),
|
|
native_presence_events=Count(
|
|
"id", filter=Q(source_kind="native_presence")
|
|
),
|
|
read_receipt_events=Count("id", filter=Q(source_kind="read_receipt")),
|
|
typing_events=Count(
|
|
"id",
|
|
filter=Q(source_kind="typing_start")
|
|
| Q(source_kind="typing_stop"),
|
|
),
|
|
message_activity_events=Count(
|
|
"id",
|
|
filter=Q(source_kind="message_in")
|
|
| Q(source_kind="message_out"),
|
|
),
|
|
inferred_timeout_events=Count(
|
|
"id", filter=Q(source_kind="inferred_timeout")
|
|
),
|
|
last_event_ts=Max("ts"),
|
|
)
|
|
.order_by("-total_events", "person__name", "service")
|
|
)
|
|
|
|
context = {
|
|
"settings_row": settings_row,
|
|
"contact_stats": contact_stats,
|
|
}
|
|
return render(request, self.template_name, context)
|