28a12b2e06
Vorher gab es KEINEN Code-Pfad, der je einen Rip ausgelöst hat: kein POST /jobs, kein udev-Daemon (udev_daemon.py existierte nirgends), GET /jobs gab hart [] zurück, Postgres lag komplett brach, der SSE-Stream konnte strukturell nie senden (sse_connections wurde nie befüllt), udevadm lieferte ohne udevd nichts. - POST /jobs: legt Job-Zeile an, schickt worker.tasks.rip_disc via Celery - GET /jobs aus Postgres (running→processing fürs UI) - Disc-Watcher: 3s-ioctl-Poll statt udev, protokolliert Einwurf/Auswurf - /devices über /sys (vendor/model) + ioctl-Status — ehrlich statt leer - /logs + /settings (Settings-Seite sprach vorher gegen 404) - SSE-Fix, udev aus dem API-Image entfernt, Import-Smoke-Test Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
64 lines
1.8 KiB
Python
64 lines
1.8 KiB
Python
"""Laufwerks-Discovery über /sys und ioctls — ehrlich, ohne udev.
|
|
|
|
Warum kein udevadm mehr: Im Container läuft kein udevd, die udev-Datenbank ist
|
|
leer — `udevadm info` lieferte schlicht nichts (der alte Weg zeigte deshalb nie
|
|
ein Laufwerk an). /sys/class/block/<name>/device/{vendor,model} kommt dagegen
|
|
direkt vom Kernel und funktioniert überall.
|
|
"""
|
|
|
|
import glob
|
|
import os
|
|
|
|
from detection import (
|
|
CDS_DISC_OK,
|
|
classify,
|
|
disc_size_bytes,
|
|
disc_status,
|
|
drive_status,
|
|
)
|
|
|
|
|
|
def list_optical_devices() -> list:
|
|
"""Alle optischen Laufwerke, die der Container sieht (devices: in compose)."""
|
|
return sorted(glob.glob("/dev/sr[0-9]*"))
|
|
|
|
|
|
def read_sys_attr(device_name: str, attr: str) -> str:
|
|
pfad = f"/sys/class/block/{device_name}/device/{attr}"
|
|
try:
|
|
with open(pfad, encoding="ascii", errors="replace") as f:
|
|
return f.read().strip()
|
|
except OSError:
|
|
return ""
|
|
|
|
|
|
def device_info(device_path: str) -> dict:
|
|
"""Baut den Geräte-Eintrag fürs UI: Name aus /sys, Disc-Status per ioctl."""
|
|
name = os.path.basename(device_path)
|
|
vendor = read_sys_attr(name, "vendor")
|
|
model = read_sys_attr(name, "model")
|
|
|
|
try:
|
|
status_code = drive_status(device_path)
|
|
except OSError:
|
|
status_code = -1
|
|
|
|
disc_type = "unknown"
|
|
status = "empty"
|
|
if status_code == CDS_DISC_OK:
|
|
status = "ready"
|
|
try:
|
|
disc_type = classify(disc_status(device_path), disc_size_bytes(device_path))
|
|
except OSError:
|
|
disc_type = "unknown"
|
|
|
|
return {
|
|
"id": name,
|
|
"name": " ".join(teil for teil in (vendor, model) if teil) or f"Laufwerk {name}",
|
|
"type": disc_type,
|
|
"path": device_path,
|
|
"status": status,
|
|
"model": model,
|
|
"serial": read_sys_attr(name, "wwid"),
|
|
}
|