4.5 KiB
4.5 KiB
streamrip-ui — Projektwissen
Diese Datei hält jede neue Session auf Stand (Architektur, Entscheidungen, Umgebungs-Eigenheiten, offene Punkte). Bei größeren Schritten aktualisieren.
Was es ist
Webapp für das CLI-Tool streamrip (Musik-Downloader). Nur Deezer,
lokal Single-User ohne Login (bewusst, nur Heimnetz — nicht ins Internet stellen).
Architektur
backend/— FastAPI, importiertstreamripals Library (kein Subprocess). Endpoints: search (track/album/artist/playlist/podcast), artist/album/playlist/ podcast-Detail, discover (charts/genres/radios), downloads (Queue + SSE + Cancel- Batch + URL-Import), history, config (voll/maskiert/arl/ui), files (+download).
frontend/— Next.js 14 (App Router), dunkel/hell, Space Grotesk, Bernstein-Akzent. Seiten: Suche, Entdecken, Artist, Album, Playlist, Podcast, Korb, Queue, Verlauf, Dateien, Einstellungen.- Betrieb per
docker-compose.yml(2 Services). UI: Host-Port 3002, API: 8000.
Getroffene Entscheidungen (mit Begründung)
- Zwei Container statt einem (Diskussion Okt 2026): Python/Node brauchen je eigene Laufzeit; HTMX-Rewrite und Single-Stack verworfen (Rewrite-Aufwand, schlechtere UX). Bleibt so.
- streamrip exakt v2.2.0 vom Git-Tag (
git+https://...@v2.2.0): PyPI kennt nur bis 2.1.0; 2.1.0 vs. lokaleconfig.toml(2.2.0) wirft „Need to update config“. - Python 3.12-slim als Basis: Pillow 10.4 (streamrip-Pin) hat kein 3.14-Wheel.
- Non-Root: Backend
appuser(UID/GID per Build-Arg), Frontendnode-User. - Version: automatisch CalVer
DATUM.Commitanzahlviascripts/version.sh(APP_VERSION-Build-Arg →GET /api/version→ Header-Anzeige). - ARL wird in
GET /api/configmaskiert (__MASKED__, Roundtrip-sicher). - Kein echter %-Fortschritt: nur Job-Status + Logs (streamrip-Rich-Bars sind terminalgebunden).
- Podcasts: nur Suche + Episodenliste + Deezer-Link — streamrip kann keine Podcasts laden (technisch unmöglich ohne Fork).
- Deezer-Lücken mit Fallbacks: Chart-Tracks/Artists + Editorial-Selection sind
leer (
total: 0, auch eingeloggt) → Fallback Top-Playlist-Tracks bzw. Charts-Alben (neueste zuerst).get_editorial_releasesist tot, Ersatz istget_editorial_selection. Echte Sub-Genres gibt Deezer nicht (flache Genreliste) → Ersatz: Playlists-Tab + Genre-Sender mit aufklappbarer Trackliste. - Ports: UI Host 3002 (Host-3000 ist von einem
bun-Prozess belegt, nicht anfassen). Alle Ports per Env umstellbar (*_HOST_PORT,BACKEND_PORT,FRONTEND_PORT);BACKEND_URLwird daraus abgeleitet. - Volumes per
.env(.env.example):CONFIG_DIR,DOWNLOAD_DIR,UID/GID. - Git/Gitea: Repo
loki/streamrip-ui(privat),main, Commits pro Feature. CI (.gitea/workflows/ci.yml): Tests + Docker-Builds.docker.ymlbaut und pusht beide Images (:latest+:Version) angitea.lokcal.de. Registry-Login nutzt SecretACTION_BOT(von Lokman per Web gesetzt — nicht zurückändern). - Kein lokaler venv-Push:
.venv/,node_modules/,.next/sind ignoriert. Lokaler Backend-venv braucht--system-site-packages(streamrip 2.2.0 nur systemweit).
Bekannte Stolpersteine
~/.local/bin/rip(pipx-Shim) ist kaputt — irrelevant, Library-Import genutzt.- DB-Pfade aus gemounteter
config.tomlzeigen auf Host-Pfade → Service biegt sie auf das Config-Verzeichnis um (_load_config). - Fehlende
config.tomlwird automatisch aus streamrip-Defaults angelegt (_ensure_config_exists, Ordner =STREAMRIP_DOWNLOAD_DIR); ARL danach per UI. - Next-14-Fallen: keine
use(params)-Promise-Params; keine fremden Exporte auspage.tsx(z. B.sortByDate→app/lib/sort.ts);public/-Copy im Standalone-Dockerfile nötig; Healthcheck mit127.0.0.1stattlocalhost(BusyBox-wget/IPv6); Frontend brauchtHOSTNAME=0.0.0.0(sonst DNS-Crash). - TestClient erzeugt pro Request einen Loop → Background-Tasks darin sofort
gecancelt; Cancel-Tests laufen deshalb auf einem Loop (
asyncio.run). - Radio-ID 1 liefert leere Tracks (Deezer-seitig); Upload-Album
3451971451ist tot (no data) — beides kein App-Fehler.
Offen / Später
- Auth + HTTPS (Caddy) nur falls je über Heimnetz hinaus gehostet wird.
- Echte %-Fortschritte (Downloadable-Hooks in streamrip).
- Personalisierte Vorschläge aus
downloads.db-Verlauf (Discover ist nur Genre/Charts). - Ordner als ZIP laden; Download-Links mit Ablauf.
- Queue nutzt Polling (SSE-Endpoint existiert, wird nicht verwendet).