Implement executing tasks
This commit is contained in:
147
core/views/availability.py
Normal file
147
core/views/availability.py
Normal file
@@ -0,0 +1,147 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.shortcuts import render
|
||||
from django.views import View
|
||||
|
||||
from core.models import (
|
||||
ContactAvailabilityEvent,
|
||||
ContactAvailabilitySettings,
|
||||
ContactAvailabilitySpan,
|
||||
Person,
|
||||
)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def _iso_to_ms(value: str) -> int:
|
||||
raw = str(value or "").strip()
|
||||
if not raw:
|
||||
return 0
|
||||
try:
|
||||
dt = datetime.fromisoformat(raw)
|
||||
if dt.tzinfo is None:
|
||||
dt = dt.replace(tzinfo=timezone.utc)
|
||||
return int(dt.timestamp() * 1000)
|
||||
except Exception:
|
||||
return 0
|
||||
|
||||
|
||||
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)
|
||||
person_id = str(request.GET.get("person") or "").strip()
|
||||
service = str(request.GET.get("service") or "").strip().lower()
|
||||
state = str(request.GET.get("state") or "").strip().lower()
|
||||
source_kind = str(request.GET.get("source_kind") or "").strip().lower()
|
||||
start_ts = _iso_to_ms(request.GET.get("start"))
|
||||
end_ts = _iso_to_ms(request.GET.get("end"))
|
||||
if end_ts <= 0:
|
||||
end_ts = int(datetime.now(tz=timezone.utc).timestamp() * 1000)
|
||||
if start_ts <= 0:
|
||||
start_ts = max(0, end_ts - (14 * 24 * 60 * 60 * 1000))
|
||||
|
||||
events_qs = ContactAvailabilityEvent.objects.filter(user=request.user)
|
||||
spans_qs = ContactAvailabilitySpan.objects.filter(user=request.user)
|
||||
|
||||
if person_id:
|
||||
events_qs = events_qs.filter(person_id=person_id)
|
||||
spans_qs = spans_qs.filter(person_id=person_id)
|
||||
if service:
|
||||
events_qs = events_qs.filter(service=service)
|
||||
spans_qs = spans_qs.filter(service=service)
|
||||
if state:
|
||||
events_qs = events_qs.filter(availability_state=state)
|
||||
spans_qs = spans_qs.filter(state=state)
|
||||
if source_kind:
|
||||
events_qs = events_qs.filter(source_kind=source_kind)
|
||||
|
||||
events_qs = events_qs.filter(ts__gte=start_ts, ts__lte=end_ts)
|
||||
spans_qs = spans_qs.filter(start_ts__lte=end_ts, end_ts__gte=start_ts)
|
||||
|
||||
events = list(
|
||||
events_qs.select_related("person", "person_identifier").order_by("-ts")[:500]
|
||||
)
|
||||
spans = list(
|
||||
spans_qs.select_related("person", "person_identifier").order_by("-end_ts")[:500]
|
||||
)
|
||||
|
||||
people = list(Person.objects.filter(user=request.user).order_by("name"))
|
||||
|
||||
context = {
|
||||
"settings_row": settings_row,
|
||||
"people": people,
|
||||
"events": events,
|
||||
"spans": spans,
|
||||
"filters": {
|
||||
"person": person_id,
|
||||
"service": service,
|
||||
"state": state,
|
||||
"source_kind": source_kind,
|
||||
"start": request.GET.get("start") or "",
|
||||
"end": request.GET.get("end") or "",
|
||||
},
|
||||
"service_choices": ["signal", "whatsapp", "xmpp", "instagram", "web"],
|
||||
"state_choices": ["available", "fading", "unavailable", "unknown"],
|
||||
"source_kind_choices": [
|
||||
"native_presence",
|
||||
"read_receipt",
|
||||
"typing_start",
|
||||
"typing_stop",
|
||||
"message_in",
|
||||
"message_out",
|
||||
"inferred_timeout",
|
||||
],
|
||||
}
|
||||
return render(request, self.template_name, context)
|
||||
Reference in New Issue
Block a user