-- The admin Overview's status sections (M504): who is listening, what is -- downloading, what the library holds. Each is one cheap read. -- name: ListListeningNow :many -- Plays in progress: open play events still inside their track's length, -- with a few minutes' grace for a pause. A client that never says a play -- ended would otherwise read as listening until the 24-hour sweep closes it. SELECT pe.started_at, pe.client_id, pe.device_class, u.username, t.id AS track_id, t.title AS track_title, t.duration_ms, ar.name AS artist_name, al.id AS album_id, al.title AS album_title FROM play_events pe JOIN users u ON u.id = pe.user_id JOIN tracks t ON t.id = pe.track_id JOIN albums al ON al.id = t.album_id JOIN artists ar ON ar.id = t.artist_id WHERE pe.ended_at IS NULL AND pe.started_at > now() - INTERVAL '24 hours' AND pe.started_at + make_interval(secs => t.duration_ms / 1000.0) + INTERVAL '5 minutes' > now() ORDER BY pe.started_at DESC LIMIT 20; -- name: PlaysLastDay :one -- The last day's listening, for the line under Listening now. SELECT COUNT(*)::bigint AS plays, COUNT(DISTINCT user_id)::bigint AS listeners, MAX(started_at)::timestamptz AS last_at FROM play_events WHERE started_at > now() - INTERVAL '24 hours'; -- name: DownloadsStatus :one -- Downloads at a glance: running, waiting on a person (and since when), and -- the last day's imports and give-ups. SELECT COUNT(*) FILTER (WHERE ended_at IS NULL AND import_state IN ('', 'downloading', 'waiting', 'importing'))::bigint AS running, COUNT(*) FILTER (WHERE ended_at IS NULL AND import_state IN ('review', 'failed'))::bigint AS needs_you, MIN(COALESCE(import_updated_at, grabbed_at)) FILTER (WHERE ended_at IS NULL AND import_state IN ('review', 'failed'))::timestamptz AS needs_you_since, COUNT(*) FILTER (WHERE imported_at > now() - INTERVAL '24 hours')::bigint AS imported_day, COUNT(*) FILTER (WHERE ended_at > now() - INTERVAL '24 hours' AND end_reason IN ('stalled', 'failed', 'gone', 'abandoned'))::bigint AS given_up_day FROM grabs WHERE ended_at IS NULL OR ended_at > now() - INTERVAL '24 hours' OR imported_at > now() - INTERVAL '24 hours'; -- name: LibraryStatus :one -- What the library holds on disk: tracks whose files are present, the -- albums and artists they make, and their size. SELECT COUNT(*)::bigint AS tracks, COUNT(DISTINCT album_id)::bigint AS albums, COUNT(DISTINCT artist_id)::bigint AS artists, COALESCE(SUM(file_size), 0)::bigint AS bytes FROM tracks WHERE missing_since IS NULL;