UX-Runde: echte Disc-Titel via BD-Metadaten, Preview-Crash, Dashboard, Ziele
Ampel / ampel (push) Failing after 38s
Ampel / ampel (push) Failing after 38s
Commander-Befunde 23.07. abends:
1. Metadaten "klappen nicht": Wurzel = kryptisches Volume-Label + kein
TMDB-Key. Jetzt: API mountet die Disc read-only (CAP_SYS_ADMIN ist da)
und liest den KLARTEXT-Titel aus BDMV/META/DL/bdmt_*.xml; dazu
progressive Suchdegradation (Titel-Varianten) und OMDb-Unscharf-Suche
(s= + imdbID-Nachladen) — mit dem vorhandenen OMDb-Key gibt es damit
Titel/Jahr/Poster auch ohne TMDB
2. Weisses Fenster beim Pre-Scan: Lucide-Icons sind forwardRef —
Direktaufruf getIcon(...)({size}) crashte die Seite; als JSX gerendert
3. Dashboard sortiert: System-Leiste (Encoder + aktiver Job) oben,
Disc/Geraete -> Stats -> Jobs, Live-Log ans Ende
4. Ziel-Dialog mit ORDNER-BROWSER (GET /browse, nur unter /app/media);
Schnellwahl nutzt die Settings-Unterordner statt Hartkodierung;
Tab "Verzeichnisse" in "Speicherziele" aufgegangen (redundant)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -428,6 +428,31 @@ async def delete_storage_mount(name: str):
|
||||
return {"status": "removed"}
|
||||
|
||||
|
||||
@app.get("/browse")
|
||||
async def browse(path: str = MEDIA_ROOT):
|
||||
"""Server-seitiger Ordner-Browser für die Ziel-Auswahl (nur unter /app/media)."""
|
||||
normalisiert = os.path.normpath(path)
|
||||
if not normalisiert.startswith(MEDIA_ROOT):
|
||||
raise HTTPException(status_code=422, detail=f"Nur Pfade unter {MEDIA_ROOT}")
|
||||
|
||||
def liste():
|
||||
try:
|
||||
eintraege = sorted(os.listdir(normalisiert))
|
||||
except OSError:
|
||||
return None
|
||||
return [
|
||||
{"name": name, "path": os.path.join(normalisiert, name)}
|
||||
for name in eintraege
|
||||
if os.path.isdir(os.path.join(normalisiert, name))
|
||||
]
|
||||
|
||||
ordner = await asyncio.to_thread(liste)
|
||||
if ordner is None:
|
||||
raise HTTPException(status_code=404, detail="Ordner nicht lesbar")
|
||||
eltern = os.path.dirname(normalisiert) if normalisiert != MEDIA_ROOT else None
|
||||
return {"path": normalisiert, "parent": eltern, "dirs": ordner}
|
||||
|
||||
|
||||
@app.get("/setup")
|
||||
async def setup_status():
|
||||
"""First-Run-Erkennung: wurde der Einrichtungs-Assistent abgeschlossen?"""
|
||||
|
||||
Reference in New Issue
Block a user