From f146f33f5d7617ceac27fb92086612fdde61e3ad Mon Sep 17 00:00:00 2001 From: Hitonabi Date: Sun, 26 Jul 2026 15:46:15 +0200 Subject: [PATCH] feat(installer): Verknuepfung auf dem Desktop - mit Rippy-Icon Commander: "Und wenn man den worker installiert braucht man auch eine exe auf dem Desktop abgelegt wird zum starten you know?" Berechtigt: Die Startdateien lagen nur im Programmordner. Wer den Worker von Hand starten wollte, musste erst "C:\Program Files\Rippy Worker" suchen - und genau das war heute noetig, als der Worker stand. Jetzt legen beide Installer eine Verknuepfung "Rippy Worker" auf den Desktop (GUI mit Haekchen, Kommandozeile per -KeineDesktopVerknuepfung abschaltbar). Drei Details, die den Unterschied machen: * Das ICON wird mit ausgeliefert. rippy.ico lag im Repo, ging aber nie an die Zielmaschine - die Verknuepfung haette das Batch-Standardsymbol getragen und waere zwischen den anderen Icons unfindbar gewesen. Jetzt im Worker-Paket. * WindowStyle 7 (minimiert): start-tray.bat startet pythonw, also ohne Konsolenfenster - aber die .bat selbst blitzt sonst kurz auf. Gilt jetzt auch fuer die Autostart-Verknuepfung, wo derselbe Blitz war. * Der DEINSTALLER nimmt sie mit, an beiden moeglichen Orten (eigener Desktop und Desktop aller Benutzer). "Rueckstandsfrei entfernbar" ist ein MUSS-Kriterium; ein totes Symbol auf dem Desktop waere genau so ein Rueckstand. Dieselbe Rechte-Ueberlegung wie beim Autostart: bei einer Installation unter "Programme" auf den Desktop ALLER Benutzer, sonst auf den eigenen - bei einer UAC-Erhoehung ueber ein fremdes Admin-Konto waere der eigene der falsche. Layout headless gerendert und angesehen (Fenster 648 -> 672 px, nichts ueberlappt), beide .ps1 mit echtem PowerShell 5.1 geprueft, .exe neu gebaut. Und die CRLF-Falle aus dem Savepoint hat prompt wieder zugeschlagen: Mein Python-Rewrite machte aus install-gui.ps1 LF - zurueckgedreht, `file` bestaetigt BOM und CRLF fuer beide. Co-Authored-By: Claude Opus 5 --- deploy/worker-windows/RippyWorkerSetup.exe | Bin 68096 -> 73728 bytes deploy/worker-windows/install-gui.ps1 | 72 +++++++++++++++++++-- deploy/worker-windows/install.ps1 | 42 ++++++++++++ docker/api/Dockerfile | 5 ++ docker/api/main.py | 4 +- 5 files changed, 116 insertions(+), 7 deletions(-) diff --git a/deploy/worker-windows/RippyWorkerSetup.exe b/deploy/worker-windows/RippyWorkerSetup.exe index 8b986be13e4dab8065525af2273c795d8458f686..8014d3a002d3994be676432c2318d81185471537 100644 GIT binary patch delta 4973 zcmb_gYiu0V72Y*@fWhGrnt)QAll2m>!|vK~QsSDXV8YMU^U5st}?-N>LHe{%EC2ZNGD8 z)?OQ^s;Vp78sC{Y_uO;7?>p!0*-LBAzOm-1bFn9Ho;ei>Kkr0ZqBllw#DCF9q&-;t z(blJbaCpN*TceRIFHkh{-j=7gZS=QAbFKg41zwH%7os~_TB81I(e2T8|LthU-FSgN z2k_exSsQuaH<8F4Bie98MI!5ZaNYK}|K|HU7AIQXxu@lZ#}|9k_12a>y^DYAJ9ziP zVWBG06SFg(ERo^OP*GHANH`VOo~6V-yIM75QK-}rPdbG%_1>HA*^}<=>AklrO^0n& z7K$vRBqSA0(bn2QS=Uf*(Qt){HR&lbt2CkPk}|4QTNNdqPf-nji@1NpPOA#8=WIy_ zun#%>Hg42x%W_4M4OTtJaRmwGxD@k$S-ophj2y2}7Bbz|8ZVS9p|gJU#Lj{6Iz1&$ zyR?^L`gHYcpME++S^}QOn$7qhJ=A-1UtiaXwO5WN{I^eRSl`&`qZ6Cf1=s$zW1D?C zxoPQE|H;#>yL)^1eakNSj~q`e{^{g*qu1Tr)3}>acH_^6` zV;BGonc=Yv9nB1nWSZ?Bou=$W{hL!b-X#VdjS9yB0tfBW;U-06&Q_Ec(sR$aL3EnK z%oxj)VL5iQSyPgOT)^dah8i$9pz^|WoioC;M3PR4qHt)`u>7|!-m!4BCQP8%bcKQg z^{cWZEGk(7p$np;Wan#k*`n#HWq3e(QL!(s z0KzG8$ne0vny^5=E&x8j#sX0Xo6Aj#sy!!C!<>@Tq$qgG5tQ0*tAe2TL^fMc=Bztu z+is4m`m3#_#mMKac(FHtGv5Z;V zVaYgR%A#F!g6yuccE+0%%Bo*=9J53T&exofbE%<`5r-VSN76>j5IzHf08Ke4kTg>D zt6mjgGvz9CmhIr#FXAjN(ov`uo6bW!_1eJCV7D5T+GD`iMNKcc1D2nG$vD+s!* z3?%_{Xh0)KKi)~q!~}0{&QKyHZI>Dz(W605a&betH58pq0#pF4K*fe9UjDsR1i?}`Q%Nyqzx*gBD&K4 zAI|lJr_aS7PG?SotFDo^#Dw9NDP@@zL9vE6J5ZAR`=2N;>f+6k1%!f{hNw^6TS3;l0wNJRQ0{>~;Mb0@R|AUuN^8a%FVwN+tD^0_Q5UU&1PB;LX3TOVOW6a45A*Wf0OtFh^}yx zlsBCw#SiV(M2S%tY!gUOC65sGy#5gV7C zlnTma)}6Nm9WaYfai;k(|CIxu^N*jqEo=b;fHZ1U$gHrP2?LMH3Rc!oMY+16YZlVv zRy->z++WFbLvUAsE!IU}rE$+qjd_;U)*5?YS(H0ydTRezs*gs8r)Y3|6y;PGE#0W- zOwtgy_N+hU`c(^p6ErPBjF)R}lS#kQz3mt(zg^M6(~Tr%f z^QiCD^ze9kKe{j0doI1uVs7kFmY6Bw$3OnUork?fkDH!#cE-Ar6kl3tsyX~dVocOh zkb@WI<_Swx-6Vj!DAzjNFX2-7z!G$yk*|T{g8vl zL0(UtVetB2e`cfKb7kEI-FF2*+Dm)Jkn165pf8*wo_7S8luxr|(-?eLkVliKWrwlS85&LI6ui7$cYCpi2q> z+9>~F8=|q1R|cj#3>zq0hPMF8(UQds#L>B5ZB)2b_Re_KVERM@@hQXUe>0h4q*!Hi z-}0#XA1Br3F?E#*J+!V5hgP0>z61`<%b8VRQ)?hKgLl#8UO?sJ*sFh!@Azj z|LZs?|AVJCBPsZJlH1K#W4IQvFg~&oA3{r;nWRBI2nm%8Q4~aRbv6Vm2TS-gG#L@6 z{i4i62ZnpnTF#=!^E~c7gbITGi+$BY7~BZ@xK$?)+ajLFB;3Ub>(|O)&GKVh?V4x! z^H23G{_&Z7^d<~j{0#(ZDZ0zouO$6Fgr$W3_SC-=X0>-EtOqfhs&|2KxbXJG&U delta 878 zcmZ8fVMtR^6n=NpoU>_Ws9>(^bLw1sL(OCnlBR~5q->xB2Agkp?&aHi&%3)!WFXWJ zNl>5HlKN3lffbR)qlEH@Aq4&IM+6b}Pedq)D8e7zr^BoR7Y^S!=R4=z?~JczjL&7v zOz@9?qsv^{);SBv0XZDE$pGgr_{^q1>CFw<0C(O5AmBDi^s)k42151?6JT$Xqm#g6 z+2ZIjs023p8I)JB0@K>rvv8SQ`wGVucX6DFVvajd!~7y`{tW;gqsOv-+)|(!b-p#b zrQUD+^mkU!SZLUK;#7n2DfAxXpY+#PJM69jqI4(;5|(8;++RiSMRJWF0|Z!E*pMTu z74-B}KK(LPTr5SQTToO2L#}fw7Ev`EgC<5-r`_#*K+?2Pp-;s_2*WDZ$c1nmRlx|7 zcDW^lk#dIj?&k5{`f4aB2=W(Ef;WlKRf)h9Owq+!NN-H%(Uk6^OL}QuPcSHANh1MO zB_1Bq4|=S#&S5Wy%}JuNu`v;P5gt<3Ru7C*@wJzOvLwbB z)Qt)9!Vx6NFd`wwLKkNnDq%dF5MvUnVG#mH!r14qM^%i%Vhp-NE)_=B5{hV+a05kCd`y+Avmevq&UWfkC2bY#A|37{M5Ayg8l83YmB8)}^7pft14@ zL`3LPS)y6y4r;PQgq|>ou|M9wIAkFEKf?41ptyPk2^|E*p%6e~5+@K8b_Dsa$YD2? z8T?n7{elqRo*s;tZ*tgS+RU+9RE4mXW@|PNpH$LH`m{tX4~5>aoJ7#I2h-+>qsF`2 zkFsYUWEv|Ev#j*(^CIKb()A3Z>BZBQLtFRzx*A_^ci$l&TjfB^ZEXMQw;i5HU$lAE rcTFGaWrfxm8`$null | Out-Null @@ -588,6 +605,11 @@ Start-Process cmd.exe -ArgumentList '/c timeout /t 4 /nobreak >nul & rd /s /q "' $lnk.TargetPath = (Join-Path $InstallDir "start-tray.bat") $lnk.WorkingDirectory = $InstallDir $lnk.Description = "Rippy Encoding-Worker" + # WindowStyle 7 = minimiert. start-tray.bat startet pythonw (kein + # Konsolenfenster), aber die .bat selbst blitzt sonst kurz auf. + $lnk.WindowStyle = 7 + $ico = Join-Path $InstallDir "rippy.ico" + if (Test-Path $ico) { $lnk.IconLocation = $ico } $lnk.Save() if ($maschinenweit) { Log "Autostart eingerichtet (für alle Benutzer dieser Maschine)." @@ -603,6 +625,44 @@ Start-Process cmd.exe -ArgumentList '/c timeout /t 4 /nobreak >nul & rd /s /q "' } } + # 8. Verknüpfung auf dem Desktop (Commander-Wunsch 26.07.2026: „wenn man + # den Worker installiert braucht man auch eine exe auf dem Desktop + # zum Starten"). Vorher lagen die Startdateien nur im Programmordner — + # wer den Worker von Hand starten wollte, musste erst + # "C:\Program Files\Rippy Worker" suchen. + # + # Dieselbe Rechte-Überlegung wie beim Autostart: bei einer Installation + # unter "Programme" auf den Desktop ALLER Benutzer, sonst auf den + # eigenen. Und ein Fehlschlag hier ist nur eine Warnung — der Worker + # läuft davon unberührt. + if ($chkDesktop.Checked) { + try { + $programme = [Environment]::GetFolderPath("ProgramFiles") + $programmeX86 = [Environment]::GetFolderPath("ProgramFilesX86") + $maschinenweit = $InstallDir.StartsWith($programme, "OrdinalIgnoreCase") ` + -or ($programmeX86 -and $InstallDir.StartsWith($programmeX86, "OrdinalIgnoreCase")) + $desktopDir = if ($maschinenweit) { + [Environment]::GetFolderPath("CommonDesktopDirectory") + } else { + [Environment]::GetFolderPath("Desktop") + } + $wsh = New-Object -ComObject WScript.Shell + $lnk = $wsh.CreateShortcut((Join-Path $desktopDir "Rippy Worker.lnk")) + $lnk.TargetPath = (Join-Path $InstallDir "start-tray.bat") + $lnk.WorkingDirectory = $InstallDir + $lnk.Description = "Rippy Encoding-Worker starten (Symbol neben der Uhr)" + $lnk.WindowStyle = 7 # minimiert, damit die .bat nicht aufblitzt + $ico = Join-Path $InstallDir "rippy.ico" + if (Test-Path $ico) { $lnk.IconLocation = $ico } + $lnk.Save() + Log "Verknüpfung 'Rippy Worker' auf dem Desktop angelegt." + } catch { + Log "HINWEIS: Desktop-Verknüpfung ging nicht ($($_.Exception.Message))." + Log " Der Worker ist trotzdem fertig — starten über" + Log " $InstallDir\start-tray.bat" + } + } + Log "" Log "FERTIG! Ordner: $InstallDir" Log "Klick 'Worker starten' - er erscheint dann in Rippy unter Einstellungen -> Worker." diff --git a/deploy/worker-windows/install.ps1 b/deploy/worker-windows/install.ps1 index 431fa11..570ebf9 100644 --- a/deploy/worker-windows/install.ps1 +++ b/deploy/worker-windows/install.ps1 @@ -22,6 +22,9 @@ param( [Parameter(Mandatory = $true)] [string]$RippyHost, [string]$WorkerName = $env:COMPUTERNAME.ToLower(), [switch]$Autostart, + # Verknüpfung auf dem Desktop. Standard AN (Commander-Wunsch 26.07.2026) — + # mit -KeineDesktopVerknuepfung abschaltbar. + [switch]$KeineDesktopVerknuepfung, # Übersetzung der Rippy-Container-Pfade auf Freigaben, die DIESER PC sieht. # Leer lassen: dann holt der Installer den Wert von Rippy selbst # (GET /worker-setup/pfad-map, abgeleitet aus dessen eigenen Mounts). @@ -221,6 +224,11 @@ Start-Sleep 2 foreach (`$ordner in @("Startup", "CommonStartup")) { try { Remove-Item -Force (Join-Path ([Environment]::GetFolderPath(`$ordner)) "RippyWorker.lnk") -ErrorAction Stop } catch {} } +# ... und die Desktop-Verknüpfung. „Rückstandsfrei entfernbar" ist ein +# MUSS-Kriterium; ein totes Symbol auf dem Desktop wäre genau so ein Rückstand. +foreach (`$ordner in @("Desktop", "CommonDesktopDirectory")) { + try { Remove-Item -Force (Join-Path ([Environment]::GetFolderPath(`$ordner)) "Rippy Worker.lnk") -ErrorAction Stop } catch {} +} # ... und die geplante Aufgabe aus älteren Installationen, falls vorhanden. schtasks /delete /tn "RippyWorker" /f 2>`$null | Out-Null try { @@ -267,6 +275,11 @@ if ($Autostart) { $lnk.TargetPath = (Join-Path $ziel "start-tray.bat") $lnk.WorkingDirectory = $ziel $lnk.Description = "Rippy Encoding-Worker" + # WindowStyle 7 = minimiert: start-tray.bat startet pythonw (kein + # Konsolenfenster), aber die .bat selbst blitzt sonst kurz auf. + $lnk.WindowStyle = 7 + $ico = Join-Path $ziel "rippy.ico" + if (Test-Path $ico) { $lnk.IconLocation = $ico } $lnk.Save() Write-Host "Autostart eingerichtet (Verknüpfung im Autostart-Ordner)." } catch { @@ -276,8 +289,37 @@ if ($Autostart) { } } +# 10. Verknüpfung auf dem Desktop (Commander-Wunsch 26.07.2026). Vorher lagen die +# Startdateien nur im Programmordner — wer den Worker von Hand starten wollte, +# musste erst "C:\Program Files\Rippy Worker" suchen. Ein Fehlschlag hier ist nur +# eine Warnung; der Worker läuft davon unberührt. +if (-not $KeineDesktopVerknuepfung) { + try { + $programme = [Environment]::GetFolderPath("ProgramFiles") + $maschinenweit = $ziel.StartsWith($programme, "OrdinalIgnoreCase") + $desktopDir = if ($maschinenweit) { + [Environment]::GetFolderPath("CommonDesktopDirectory") + } else { + [Environment]::GetFolderPath("Desktop") + } + $wsh = New-Object -ComObject WScript.Shell + $lnk = $wsh.CreateShortcut((Join-Path $desktopDir "Rippy Worker.lnk")) + $lnk.TargetPath = (Join-Path $ziel "start-tray.bat") + $lnk.WorkingDirectory = $ziel + $lnk.Description = "Rippy Encoding-Worker starten (Symbol neben der Uhr)" + $lnk.WindowStyle = 7 + $ico = Join-Path $ziel "rippy.ico" + if (Test-Path $ico) { $lnk.IconLocation = $ico } + $lnk.Save() + Write-Host "Verknüpfung 'Rippy Worker' auf dem Desktop angelegt." + } catch { + Write-Host "HINWEIS: Desktop-Verknüpfung ging nicht ($($_.Exception.Message))." -ForegroundColor Yellow + } +} + Write-Host "" Write-Host "FERTIG." -ForegroundColor Green +Write-Host " Auf dem Desktop: Rippy Worker" Write-Host " Starten (mit Tray-Symbol): $ziel\start-tray.bat" Write-Host " Starten (Konsole/Debug): $ziel\start-worker.bat" Write-Host " Deinstallieren: $ziel\uninstall.ps1" diff --git a/docker/api/Dockerfile b/docker/api/Dockerfile index 5f7155f..609b9c4 100644 --- a/docker/api/Dockerfile +++ b/docker/api/Dockerfile @@ -22,6 +22,11 @@ COPY docker/api/ . # die Zielmaschine braucht weder git noch Docker. COPY docker/worker/*.py docker/worker/requirements.txt worker_dist/ COPY deploy/worker-windows/install.ps1 deploy/worker-windows/install-gui.ps1 worker_dist/ +# Rippy-Icon: Der Installer legt damit eine Verknüpfung auf den Desktop +# (Commander-Wunsch 26.07.2026). Ohne die Datei auf der Zielmaschine trüge die +# Verknüpfung das Standard-Batch-Symbol — und niemand fände sie zwischen den +# anderen Icons wieder. +COPY deploy/worker-windows/rippy.ico worker_dist/ # Vorgebaute .exe (Rippy-Icon, kein Konsolenfenster) — auf Windows via # deploy/worker-windows/build-exe.ps1 erzeugt (Windows-.exe geht nicht von # Linux). Nur bei GUI-Aenderungen neu bauen, nicht bei Tool-Updates. diff --git a/docker/api/main.py b/docker/api/main.py index 21e3bce..c03a762 100644 --- a/docker/api/main.py +++ b/docker/api/main.py @@ -1608,7 +1608,9 @@ async def worker_setup_paket(): for name in sorted(os.listdir("worker_dist")): if name.endswith(".py") and not name.startswith(("test_", "conftest")): z.write(os.path.join("worker_dist", name), name) - elif name == "requirements.txt": + # requirements.txt für die venv, rippy.ico für die Verknüpfung + # auf dem Desktop (sonst trägt sie das Batch-Standardsymbol). + elif name in ("requirements.txt", "rippy.ico"): z.write(os.path.join("worker_dist", name), name) return puffer.getvalue()