from datetime import datetime, timedelta, timezone from app.db.database import get_connection from app.db.migrations import run_migrations def parse_timestamp(value: str | None) -> datetime | None: if not value: return None normalized = value.strip().replace("Z", "+00:00") formats = [ "%Y-%m-%d %H:%M:%S", "%Y-%m-%d %H:%M:%S.%f", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%dT%H:%M:%S.%f", ] try: parsed = datetime.fromisoformat(normalized) return parsed.astimezone(timezone.utc).replace(tzinfo=None) if parsed.tzinfo else parsed except ValueError: pass for fmt in formats: try: return datetime.strptime(normalized, fmt) except ValueError: continue return None def is_worker_online(last_seen_at: str | None) -> bool: last_seen = parse_timestamp(last_seen_at) if not last_seen: return False return last_seen >= datetime.utcnow() - timedelta(seconds=30) def with_online_status(worker: dict): worker["online"] = is_worker_online(worker.get("last_seen_at")) return worker def get_workers(): run_migrations() con = get_connection() rows = con.execute( """ SELECT id, status, started_at, last_seen_at, current_job_id, metadata_json FROM workers ORDER BY id """ ).fetchall() con.close() return [with_online_status(dict(row)) for row in rows] def get_worker(worker_id: str): run_migrations() con = get_connection() row = con.execute( """ SELECT id, status, started_at, last_seen_at, current_job_id, metadata_json FROM workers WHERE id = ? """, (worker_id,), ).fetchone() con.close() return with_online_status(dict(row)) if row else None