Dateigröße pro Aufnahme entkoppelt - feste Größe nach Abschluss
Build Dev Docker Image / build-amd64 (push) Successful in 10s
Build Dev Docker Image / build-arm64 (push) Successful in 16s
Build Dev Docker Image / publish-dev-manifest (push) Successful in 9s

Die Dateigröße wird jetzt pro Aufnahme korrekt berechnet statt das
gesamte Verzeichnis zu summieren. Bei abgeschlossenen Aufnahmen wird
die Größe einmalig gespeichert und nicht mehr durch laufende Aufnahmen
verändert.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Patrick Asmus
2026-09-16 11:46:18 +02:00
co-authored by Claude Opus 4.6
parent 1ad87c7186
commit 851ff086ac
6 changed files with 600 additions and 124 deletions
+104 -1
View File
@@ -13,7 +13,7 @@ from pydantic import BaseModel
from typing import Optional
from config import Config
from models import init_db, get_session, Job, Recording as RecordingModel, LogEntry
from models import init_db, get_session, Job, Station, Recording as RecordingModel, LogEntry
from recorder import RecordingManager, format_elapsed
from scheduler import StreamScheduler
@@ -83,6 +83,106 @@ async def health():
# --- Jobs CRUD ---
class StationCreate(BaseModel):
name: str
stream_url: str
stream_type: str = "auto"
description: str = ""
class StationUpdate(StationCreate):
pass
def _station_to_dict(station: Station) -> dict:
return {
"id": station.id,
"name": station.name,
"stream_url": station.stream_url,
"stream_type": station.stream_type,
"description": station.description,
"created_at": station.created_at.isoformat() if station.created_at else None,
"updated_at": station.updated_at.isoformat() if station.updated_at else None,
}
def _clean_station_data(data: StationCreate | StationUpdate) -> dict:
values = data.model_dump()
values["name"] = values["name"].strip()
values["stream_url"] = values["stream_url"].strip()
values["stream_type"] = (values.get("stream_type") or "auto").strip() or "auto"
values["description"] = (values.get("description") or "").strip()
if not values["name"] or not values["stream_url"]:
raise HTTPException(400, "Name und URL sind Pflichtfelder")
return values
@app.get("/api/stations")
async def list_stations():
session = get_session()
try:
stations = session.query(Station).order_by(Station.name.collate("NOCASE"), Station.id).all()
return [_station_to_dict(s) for s in stations]
finally:
session.close()
@app.post("/api/stations")
async def create_station(data: StationCreate):
values = _clean_station_data(data)
session = get_session()
try:
station = Station(**values)
session.add(station)
session.commit()
return {"id": station.id, "message": "Sender gespeichert"}
finally:
session.close()
@app.get("/api/stations/{station_id}")
async def get_station(station_id: int):
session = get_session()
try:
station = session.query(Station).filter_by(id=station_id).first()
if not station:
raise HTTPException(404, "Sender nicht gefunden")
return _station_to_dict(station)
finally:
session.close()
@app.put("/api/stations/{station_id}")
async def update_station(station_id: int, data: StationUpdate):
values = _clean_station_data(data)
session = get_session()
try:
station = session.query(Station).filter_by(id=station_id).first()
if not station:
raise HTTPException(404, "Sender nicht gefunden")
for k, v in values.items():
setattr(station, k, v)
station.updated_at = datetime.datetime.utcnow()
session.commit()
return {"message": "Sender aktualisiert"}
finally:
session.close()
@app.delete("/api/stations/{station_id}")
async def delete_station(station_id: int):
session = get_session()
try:
station = session.query(Station).filter_by(id=station_id).first()
if not station:
raise HTTPException(404, "Sender nicht gefunden")
session.delete(station)
session.commit()
return {"message": "Sender gelöscht"}
finally:
session.close()
class JobCreate(BaseModel):
name: str
stream_url: str
@@ -310,6 +410,9 @@ async def get_recording(rec_id: int):
@app.post("/api/recordings/{rec_id}/stop")
async def stop_recording(rec_id: int):
status = recorder.get_status(rec_id)
if status and status.get("job_id"):
scheduler.suppress_current_occurrence(status["job_id"])
recorder.stop_recording(rec_id)
return {"message": "Aufnahme gestoppt"}