Files
ad/molodetz/utils/presence.py
T

54 lines
1.5 KiB
Python
Raw Normal View History

2026-10-05 09:36:20 +02:00
# retoor <retoor@molodetz.nl>
import json
import threading
import time
from datetime import datetime, timedelta, timezone
from molodetz import config
from molodetz.database import db, get_service_state, now_iso, update_user
_lock = threading.Lock()
_last_write = {}
def touch(uid):
if not uid:
return
now = time.monotonic()
throttle = max(1, config.PRESENCE_TIMEOUT_SECONDS // 2)
with _lock:
if now - _last_write.get(uid, 0) < throttle:
return
_last_write[uid] = now
update_user(uid, last_seen_at=now_iso())
def compute_roster():
if "users" not in db.tables:
return []
window = config.PRESENCE_TIMEOUT_SECONDS + config.PRESENCE_ONLINE_MARGIN_SECONDS
cutoff = (datetime.now(timezone.utc) - timedelta(seconds=window)).isoformat()
rows = db.query(
"SELECT uid FROM users WHERE last_seen_at >= :cutoff AND deleted_at IS NULL "
"ORDER BY last_seen_at DESC LIMIT :limit",
cutoff=cutoff,
limit=config.PRESENCE_TRACK_LIMIT,
)
return [row["uid"] for row in rows]
def published_roster():
row = get_service_state("presence")
if row and row.get("metrics"):
try:
metrics = json.loads(row["metrics"])
except ValueError:
metrics = {}
if "roster" in metrics:
return metrics["roster"]
return compute_roster()
def online_uids(limit=None):
return published_roster()[: limit or config.PRESENCE_ONLINE_LIMIT]