Track-Auswahl-Tabelle, nativer Windows-Worker (via UI angeboten), Anleitungs-Tab
Ampel / ampel (push) Successful in 29s
Ampel / ampel (push) Successful in 29s
Volle Titel-Auswahl vor dem Rip (Etappe-12-Rest):
- worker.tasks.scan_tracks: makemkvcon info -> Titel-Liste (Dauer/Groesse/
Kapitel, apdefs-Attr 8/9/11) in die settings-Tabelle 'tracks:<device>';
API: POST /devices/{n}/scan-tracks + GET /devices/{n}/tracks (Polling).
- Rip-Dialog: 'Disc scannen' -> Tabelle mit Checkboxen, Vorauswahl ab
5 min, Groessen-Summe; gewaehlte Titel als meta.titles in den Job.
- rip_titel_auswahl: ein makemkvcon-Aufruf je Titel (mkv kann nur einen
Titel oder all), Fortschritt anteilig. Parser-Tests dabei.
Nativer Windows-Worker OHNE Docker (Commander-Wunsch):
- Die Rippy-Instanz versorgt sich selbst: GET /worker-setup/windows
liefert install.ps1, /worker-setup/paket den Worker-Code als Zip
(api-Dockerfile kopiert docker/worker/*.py als worker_dist/ ins Image).
- install.ps1: Python-Check, venv + requirements, HandBrakeCLI 1.9.2 vom
offiziellen GitHub-Release (URL per HEAD verifiziert), start-worker.bat
mit celery -Q transcode --pool=solo (Celery-Doku: Windows nur solo),
optional -Autostart via schtasks onlogon.
- tasks.py laedt jetzt auch ohne fcntl (Import-Guard) — rip_disc ist auf
solchen Workern hart verriegelt (Klartext-Fehler statt Crash).
- Einstellungen -> Worker: Varianten-Umschalter Linux(Docker)/Windows(nativ)
mit passenden Copy-Paste-Befehlen.
Anleitungs-Tab: Rippy erklaert sich selbst (Disc-Weg, Serien, NAS,
Media-Server, Benachrichtigungen, Key, Worker, Downloads, FAQ).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -148,6 +148,28 @@ def get_job(job_id: str) -> dict:
|
||||
return dict(zeile) if zeile else None
|
||||
|
||||
|
||||
def save_settings(werte: dict, key: str = "ui") -> None:
|
||||
"""Upsert in die settings-Tabelle — der Worker legt hier z. B. die
|
||||
Track-Scan-Ergebnisse ab (key 'tracks:<device>'), die API liest sie."""
|
||||
import json
|
||||
|
||||
from sqlalchemy import select
|
||||
|
||||
payload = json.dumps(werte)
|
||||
with engine.begin() as conn:
|
||||
vorhanden = conn.execute(
|
||||
select(settings_table.c.key).where(settings_table.c.key == key)
|
||||
).first()
|
||||
if vorhanden:
|
||||
conn.execute(
|
||||
settings_table.update()
|
||||
.where(settings_table.c.key == key)
|
||||
.values(value=payload)
|
||||
)
|
||||
else:
|
||||
conn.execute(settings_table.insert().values(key=key, value=payload))
|
||||
|
||||
|
||||
def get_job_status(job_id: str) -> str:
|
||||
"""Nur der Status — der Worker prüft damit kooperative Abbruch-Anfragen."""
|
||||
from sqlalchemy import select
|
||||
|
||||
Reference in New Issue
Block a user