Files
Audiolib/backend/app/main.py
Audiolib afba751c21 Add first-run setup wizard and file browser for library creation
- On first start (no users in DB), show a setup page in the web UI
  to create the admin account instead of reading credentials from .env
- New public endpoints: GET /api/setup/status, POST /api/setup
- New admin endpoint: GET /api/filebrowser?path=... for directory listing
- FileBrowser modal component with navigation, used in Admin > Libraries
- Remove _seed_admin / _seed_default_library from server startup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 13:30:42 +02:00

71 lines
2.0 KiB
Python

import logging
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from .database import init_db
from .config import get_settings
from .services.file_watcher import start_file_watcher, stop_file_watcher
from .services.podcast_feed import update_all_feeds
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s")
logger = logging.getLogger(__name__)
_scheduler = AsyncIOScheduler()
@asynccontextmanager
async def lifespan(app: FastAPI):
settings = get_settings()
for d in [settings.hls_cache_dir, settings.covers_dir, settings.log_dir]:
os.makedirs(d, exist_ok=True)
await init_db()
await start_file_watcher()
# Podcast-Feed-Scheduler
_scheduler.add_job(update_all_feeds, "interval", hours=settings.podcast_update_interval_hours, id="feed_update")
_scheduler.start()
logger.info("Audiolib gestartet.")
yield
stop_file_watcher()
_scheduler.shutdown(wait=False)
logger.info("Audiolib gestoppt.")
app = FastAPI(title="Audiolib", version="2.4.0", lifespan=lifespan)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
settings = get_settings()
if os.path.exists(settings.covers_dir):
app.mount("/covers", StaticFiles(directory=settings.covers_dir), name="covers")
from .routers import auth, libraries, items, stream, me, users, settings as settings_router
from .routers import matching, podcasts, setup, filebrowser
app.include_router(setup.router)
app.include_router(auth.router)
app.include_router(libraries.router)
app.include_router(items.router)
app.include_router(stream.router)
app.include_router(me.router)
app.include_router(users.router)
app.include_router(settings_router.router)
app.include_router(matching.router)
app.include_router(podcasts.router)
app.include_router(filebrowser.router)