61 lines
1.7 KiB
Python
61 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from django.db.models import Q
|
|
|
|
from core.models import ContactAvailabilityEvent, ContactAvailabilitySpan, Person, User
|
|
from .engine import ensure_fading_state
|
|
from .inference import now_ms
|
|
|
|
|
|
def spans_for_range(
|
|
*,
|
|
user: User,
|
|
person: Person,
|
|
start_ts: int,
|
|
end_ts: int,
|
|
service: str = "",
|
|
limit: int = 200,
|
|
):
|
|
qs = ContactAvailabilitySpan.objects.filter(
|
|
user=user,
|
|
person=person,
|
|
).filter(
|
|
Q(start_ts__lte=end_ts) & Q(end_ts__gte=start_ts)
|
|
)
|
|
if service:
|
|
qs = qs.filter(service=str(service).strip().lower())
|
|
|
|
ensure_fading_state(
|
|
user=user,
|
|
person=person,
|
|
person_identifier=None,
|
|
service=(str(service or "").strip().lower() or "signal"),
|
|
at_ts=now_ms(),
|
|
)
|
|
|
|
return list(qs.order_by("-end_ts")[: max(1, min(int(limit or 200), 500))])
|
|
|
|
|
|
def latest_state_for_people(*, user: User, person_ids: list, service: str = "") -> dict:
|
|
out = {}
|
|
if not person_ids:
|
|
return out
|
|
qs = ContactAvailabilityEvent.objects.filter(user=user, person_id__in=person_ids)
|
|
if service:
|
|
qs = qs.filter(service=str(service).strip().lower())
|
|
rows = list(qs.order_by("person_id", "-ts", "-id"))
|
|
seen = set()
|
|
for row in rows:
|
|
person_key = str(row.person_id)
|
|
if person_key in seen:
|
|
continue
|
|
seen.add(person_key)
|
|
out[person_key] = {
|
|
"state": str(row.availability_state or "unknown"),
|
|
"confidence": float(row.confidence or 0.0),
|
|
"service": str(row.service or ""),
|
|
"ts": int(row.ts or 0),
|
|
"source_kind": str(row.source_kind or ""),
|
|
}
|
|
return out
|