Implement Manticore fully and re-theme
This commit is contained in:
@@ -4,13 +4,16 @@ from typing import Iterable
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from core.events.ledger import append_event_sync
|
||||
from core.models import Message
|
||||
from core.presence import AvailabilitySignal, record_inferred_signal
|
||||
from core.presence.inference import now_ms
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Backfill inferred contact availability events from historical message/read-receipt activity."
|
||||
help = (
|
||||
"Backfill behavioral event ledger rows from historical message and "
|
||||
"read-receipt activity."
|
||||
)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("--days", type=int, default=30)
|
||||
@@ -39,17 +42,18 @@ class Command(BaseCommand):
|
||||
user_filter = str(options.get("user_id") or "").strip()
|
||||
dry_run = bool(options.get("dry_run"))
|
||||
|
||||
created = 0
|
||||
indexed = 0
|
||||
scanned = 0
|
||||
|
||||
for msg in self._iter_messages(
|
||||
days=days, limit=limit, service=service_filter, user_id=user_filter
|
||||
):
|
||||
scanned += 1
|
||||
identifier = getattr(getattr(msg, "session", None), "identifier", None)
|
||||
session = getattr(msg, "session", None)
|
||||
identifier = getattr(session, "identifier", None)
|
||||
person = getattr(identifier, "person", None)
|
||||
user = getattr(msg, "user", None)
|
||||
if not identifier or not person or not user:
|
||||
if not session or not identifier or not person or not user:
|
||||
continue
|
||||
|
||||
service = (
|
||||
@@ -60,76 +64,65 @@ class Command(BaseCommand):
|
||||
if not service:
|
||||
continue
|
||||
|
||||
base_ts = int(getattr(msg, "ts", 0) or 0)
|
||||
message_author = (
|
||||
str(getattr(msg, "custom_author", "") or "").strip().upper()
|
||||
)
|
||||
outgoing = message_author in {"USER", "BOT"}
|
||||
author = str(getattr(msg, "custom_author", "") or "").strip().upper()
|
||||
outgoing = author in {"USER", "BOT"}
|
||||
message_id = str(
|
||||
getattr(msg, "source_message_id", "") or f"django-message-{msg.id}"
|
||||
).strip()
|
||||
|
||||
candidates = []
|
||||
if base_ts > 0:
|
||||
candidates.append(
|
||||
{
|
||||
"source_kind": "message_out" if outgoing else "message_in",
|
||||
"availability_state": "available",
|
||||
"confidence": 0.65 if outgoing else 0.75,
|
||||
"ts": base_ts,
|
||||
"payload": {
|
||||
"origin": "backfill_contact_availability",
|
||||
"message_id": str(msg.id),
|
||||
"inferred_from": "message_activity",
|
||||
},
|
||||
}
|
||||
if not dry_run:
|
||||
append_event_sync(
|
||||
user=user,
|
||||
session=session,
|
||||
ts=int(getattr(msg, "ts", 0) or 0),
|
||||
event_type="message_created",
|
||||
direction="out" if outgoing else "in",
|
||||
actor_identifier=str(
|
||||
getattr(msg, "sender_uuid", "") or identifier.identifier or ""
|
||||
),
|
||||
origin_transport=service,
|
||||
origin_message_id=message_id,
|
||||
origin_chat_id=str(getattr(msg, "source_chat_id", "") or ""),
|
||||
payload={
|
||||
"origin": "backfill_contact_availability",
|
||||
"message_id": str(msg.id),
|
||||
"text": str(getattr(msg, "text", "") or ""),
|
||||
"outgoing": outgoing,
|
||||
},
|
||||
)
|
||||
indexed += 1
|
||||
|
||||
read_ts = int(getattr(msg, "read_ts", 0) or 0)
|
||||
if read_ts > 0:
|
||||
candidates.append(
|
||||
{
|
||||
"source_kind": "read_receipt",
|
||||
"availability_state": "available",
|
||||
"confidence": 0.95,
|
||||
"ts": read_ts,
|
||||
"payload": {
|
||||
"origin": "backfill_contact_availability",
|
||||
"message_id": str(msg.id),
|
||||
"inferred_from": "read_receipt",
|
||||
"read_by": str(
|
||||
getattr(msg, "read_by_identifier", "") or ""
|
||||
),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
for row in candidates:
|
||||
exists = user.contact_availability_events.filter(
|
||||
person=person,
|
||||
person_identifier=identifier,
|
||||
service=service,
|
||||
source_kind=row["source_kind"],
|
||||
ts=int(row["ts"]),
|
||||
).exists()
|
||||
if exists:
|
||||
continue
|
||||
created += 1
|
||||
if dry_run:
|
||||
continue
|
||||
record_inferred_signal(
|
||||
AvailabilitySignal(
|
||||
user=user,
|
||||
person=person,
|
||||
person_identifier=identifier,
|
||||
service=service,
|
||||
source_kind=row["source_kind"],
|
||||
availability_state=row["availability_state"],
|
||||
confidence=float(row["confidence"]),
|
||||
ts=int(row["ts"]),
|
||||
payload=dict(row["payload"]),
|
||||
)
|
||||
if read_ts <= 0:
|
||||
continue
|
||||
if not dry_run:
|
||||
append_event_sync(
|
||||
user=user,
|
||||
session=session,
|
||||
ts=read_ts,
|
||||
event_type="read_receipt",
|
||||
direction="system",
|
||||
actor_identifier=str(
|
||||
getattr(msg, "read_by_identifier", "") or identifier.identifier
|
||||
),
|
||||
origin_transport=service,
|
||||
origin_message_id=message_id,
|
||||
origin_chat_id=str(getattr(msg, "source_chat_id", "") or ""),
|
||||
payload={
|
||||
"origin": "backfill_contact_availability",
|
||||
"message_id": str(msg.id),
|
||||
"message_ts": int(getattr(msg, "ts", 0) or 0),
|
||||
"read_by": str(
|
||||
getattr(msg, "read_by_identifier", "") or ""
|
||||
).strip(),
|
||||
},
|
||||
)
|
||||
indexed += 1
|
||||
|
||||
self.stdout.write(
|
||||
self.style.SUCCESS(
|
||||
f"backfill_contact_availability complete scanned={scanned} created={created} dry_run={dry_run} days={days} limit={limit}"
|
||||
"backfill_contact_availability complete "
|
||||
f"scanned={scanned} indexed={indexed} dry_run={dry_run} "
|
||||
f"days={days} limit={limit}"
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user