65 lines
2.3 KiB
Python
65 lines
2.3 KiB
Python
# list_streams.py — FastAPI route to list all public streams (users with stream.opus)
|
|
|
|
from fastapi import APIRouter
|
|
from pathlib import Path
|
|
from fastapi.responses import StreamingResponse
|
|
import asyncio
|
|
|
|
router = APIRouter()
|
|
DATA_ROOT = Path("./data")
|
|
|
|
@router.get("/streams-sse")
|
|
def streams_sse():
|
|
return list_streams_sse()
|
|
|
|
import json
|
|
|
|
import datetime
|
|
|
|
def list_streams_sse():
|
|
async def event_generator():
|
|
txt_path = Path("./public_streams.txt")
|
|
if not txt_path.exists():
|
|
print(f"[{datetime.datetime.now()}] [SSE] No public_streams.txt found")
|
|
yield f"data: {json.dumps({'end': True})}\n\n"
|
|
return
|
|
try:
|
|
with txt_path.open("r") as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line:
|
|
continue
|
|
try:
|
|
stream = json.loads(line)
|
|
print(f"[{datetime.datetime.now()}] [SSE] Yielding stream: {stream}")
|
|
yield f"data: {json.dumps(stream)}\n\n"
|
|
await asyncio.sleep(0) # Yield control to event loop
|
|
except Exception as e:
|
|
print(f"[{datetime.datetime.now()}] [SSE] JSON decode error: {e}")
|
|
continue # skip malformed lines
|
|
print(f"[{datetime.datetime.now()}] [SSE] Yielding end event")
|
|
yield f"data: {json.dumps({'end': True})}\n\n"
|
|
except Exception as e:
|
|
print(f"[{datetime.datetime.now()}] [SSE] Exception: {e}")
|
|
yield f"data: {json.dumps({'end': True, 'error': True})}\n\n"
|
|
return StreamingResponse(event_generator(), media_type="text/event-stream")
|
|
|
|
def list_streams():
|
|
txt_path = Path("./public_streams.txt")
|
|
if not txt_path.exists():
|
|
return {"streams": []}
|
|
try:
|
|
streams = []
|
|
with txt_path.open("r") as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line:
|
|
continue
|
|
try:
|
|
streams.append(json.loads(line))
|
|
except Exception:
|
|
continue # skip malformed lines
|
|
return {"streams": streams}
|
|
except Exception:
|
|
return {"streams": []}
|