fix(windows): Cover, Arbeitsverzeichnis und die zurueckgelassenen _MEI-Ordner
Drei Befunde des Commanders vom 28.08.2026, alle drei gemessen.
## 1. „Was ist mit dem Cover auf Windows Rippy?"
Es gab keins, weil es keinen Treffer gab. `_scan_video` verlangte woertliche
Gleichheit:
if movie.get("title", "").lower() == kandidat.lower():
An seiner Disc gemessen:
'Evangelion 2.22' 1 Treffer Evangelion: 2.0 You Can (Not) Advance
'Evangelion' 20 Treffer irgendein Evangelion
Der EINZIGE Treffer auf den vollen Disc-Titel war der richtige Film, mit
Poster — und wurde verworfen. Jetzt zaehlt die SPEZIFITAET der Anfrage: Wer
auf den vollen Disc-Titel hoechstens drei Treffer bekommt, hat gefragt wie
jemand, der weiss was er sucht. Ergebnis an derselben Disc:
Evangelion: 2.0 You Can (Not) Advance / 2009 / 80 % / Poster + dt. Text
## 2. „Warum heisst das hier noch container platte? … Waere es moeglich das
## Arbeitsverzeichnis zu aendern? momentan geht das nicht."
Beide Haelften gehen auf EINE Zeile zurueck: `MEDIA_ROOT = "/app/media"` war
zugleich Vorgabe UND Pfadgrenze. Auf Windows gibt es den Ordner nicht:
* `/storage-targets` fing den OSError und gab still [] zurueck — die Auswahl
hatte genau einen Eintrag. Das ist „momentan geht das nicht".
* Dessen Text war fest verdrahtet „(Container-Platte)".
* `/browse` antwortete auf jeden Pfad mit 422.
Die Grenze faellt nicht weg, sie wird betriebsabhaengig: Container und
Kopflos-Betrieb bedienen ein Netz, die native App den Menschen davor.
Gemessen auf seinem PC: 7 Laufwerke zur Auswahl, X/Y/Z mit je 2,2 TB frei.
## 3. „Failed to remove temporary directory: …_MEI0000b0882"
GEMESSEN: 20 zurueckgelassene _MEI-Ordner mit 1,1 GB. Ursache: `Popen` ohne
`env=` reicht PyInstallers Auspack-Zeiger an die Kinder weiter (--dienst und
--oeffnen). Beide laufen dann im Ordner des Elternprozesses, der sich zuerst
beendet und ihn loeschen will. Waere das TEILWEISE geglueckt, haetten Dienst
und Fenster mitten im Betrieb ihre Dateien verloren.
Nebenbefund: test_setup_fenster scheiterte in jeder Umgebung ohne pywebview.
794 Tests gruen, ruff sauber.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
11001a443e
commit
35370fd552
@@ -940,15 +940,40 @@ export default function SettingsPage() {
|
||||
/storage-targets — dieselbe Liste wie bei den Speicherzielen,
|
||||
inklusive freiem Platz.
|
||||
*/}
|
||||
{!betrieb.kann.container_pfade ? (
|
||||
/*
|
||||
* Ein echtes Pfadfeld statt einer Auswahl — dieselbe
|
||||
* Entscheidung wie bei der Ablage darüber, und aus demselben
|
||||
* Grund.
|
||||
*
|
||||
* Commander am 28.08.2026: „Wäre es möglich das
|
||||
* Arbeitsverzeichnis zu ändern? momentan geht das nicht."
|
||||
*
|
||||
* Es ging nicht, weil `ziele` auf Windows LEER war: Die Liste
|
||||
* kommt aus /storage-targets, und das las `/app/media` — ein
|
||||
* Ordner, den es dort nicht gibt. Übrig blieb eine Auswahl mit
|
||||
* genau einem Eintrag, und der hieß „Container-Platte".
|
||||
*
|
||||
* Die Liste ist inzwischen repariert (sie bringt jetzt die
|
||||
* Laufwerke mit freiem Platz). Aber die richtige Antwort auf
|
||||
* „wohin mit 100 GB" ist auf Windows oft ein Ort, den keine
|
||||
* Liste kennt — D:\Rippy-Arbeit oder eine UNC-Freigabe.
|
||||
* Deshalb hier ein Feld, in das man ihn schreiben kann.
|
||||
*/
|
||||
<Input
|
||||
label="Arbeitsverzeichnis für Roh-Rips (Standard)"
|
||||
value={settings.workDir}
|
||||
placeholder={betrieb.arbeits_vorgabe}
|
||||
onChange={(e) => handleChange('workDir', e.target.value)}
|
||||
/>
|
||||
) : (
|
||||
<Select
|
||||
label="Arbeitsverzeichnis für Roh-Rips (Standard)"
|
||||
value={settings.workDir}
|
||||
onChange={(e) => handleChange('workDir', e.target.value)}
|
||||
>
|
||||
<option value="">
|
||||
{betrieb.kann.container_pfade
|
||||
? 'Container-Platte (Standard) — klein, nur für DVD/Blu-ray'
|
||||
: `Standard (${betrieb.ablage_vorgabe || 'neben der Ablage'})`}
|
||||
Container-Platte (Standard) — klein, nur für DVD/Blu-ray
|
||||
</option>
|
||||
{ziele.map(z => (
|
||||
<option key={z.path} value={z.path}>
|
||||
@@ -957,6 +982,27 @@ export default function SettingsPage() {
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
)}
|
||||
{!betrieb.kann.container_pfade && !!ziele.length && (
|
||||
/* Die Laufwerke als Ein-Klick-Wahl. Wer den Platz sieht,
|
||||
wählt anders — genau daran ist am 25.07. eine Platte
|
||||
vollgelaufen. */
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{ziele.map(z => (
|
||||
<button
|
||||
key={z.path}
|
||||
onClick={() => handleChange('workDir', z.path)}
|
||||
className={`px-2.5 py-1 text-xs rounded-lg border transition-colors ${
|
||||
settings.workDir === z.path
|
||||
? 'border-amber-500 bg-amber-500/10 text-amber-700 dark:text-amber-300'
|
||||
: 'border-slate-200 dark:border-slate-700 text-slate-500 dark:text-slate-400 hover:border-slate-400'
|
||||
}`}
|
||||
>
|
||||
{z.name}{z.free_gb != null ? ` — ${z.free_gb} GB frei` : ''}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<p className="text-xs text-slate-500 dark:text-slate-400">
|
||||
<strong className="text-slate-700 dark:text-slate-300">Der Standard</strong> — beim
|
||||
„Rippen starten" kannst du für jede Disc etwas anderes wählen. <strong className="text-slate-700 dark:text-slate-300">
|
||||
|
||||
Reference in New Issue
Block a user