diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3d6238d..352f81b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,18 +25,24 @@ jobs: run: | python -m pip install --upgrade pip pip install -r requirements.txt - pip install pyinstaller + pip install pyinstaller pillow + + - name: Prepare release metadata + shell: pwsh + run: | + $version = "${{ github.ref_name }}".TrimStart('v') + python scripts/set_version.py $version + python scripts/prepare_icon.py - name: Build exe run: | - pyinstaller --noconfirm --onefile --windowed --name "Real-Debrid-Downloader" real_debrid_downloader_gui.py + pyinstaller --noconfirm --windowed --onedir --name "Real-Debrid-Downloader" --icon "assets/app_icon.ico" real_debrid_downloader_gui.py - name: Pack release zip shell: pwsh run: | New-Item -ItemType Directory -Path release -Force | Out-Null - Copy-Item "dist/Real-Debrid-Downloader.exe" "release/Real-Debrid-Downloader.exe" - Compress-Archive -Path "release/*" -DestinationPath "Real-Debrid-Downloader-win64.zip" -Force + Compress-Archive -Path "dist/Real-Debrid-Downloader/*" -DestinationPath "Real-Debrid-Downloader-win64.zip" -Force - name: Install Inno Setup shell: pwsh @@ -47,7 +53,7 @@ jobs: shell: pwsh run: | $version = "${{ github.ref_name }}".TrimStart('v') - & "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" "/DMyAppVersion=$version" "/DMySourceExe=..\\dist\\Real-Debrid-Downloader.exe" "/DMyOutputDir=..\\release" "installer\\RealDebridDownloader.iss" + & "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" "/DMyAppVersion=$version" "/DMySourceDir=..\\dist\\Real-Debrid-Downloader" "/DMyOutputDir=..\\release" "/DMyIconFile=..\\assets\\app_icon.ico" "installer\\RealDebridDownloader.iss" - name: Publish GitHub Release uses: softprops/action-gh-release@v2 diff --git a/.gitignore b/.gitignore index b4550de..fb539a4 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ venv/ build/ dist/ +release/ *.spec rd_downloader_config.json diff --git a/README.md b/README.md index e99f928..f756c75 100644 --- a/README.md +++ b/README.md @@ -76,12 +76,18 @@ Danach liegt die EXE in `dist/`. - Bei Tag-Push wie `v1.0.1` wird automatisch eine Windows-EXE gebaut - Release-Asset fuer Auto-Update: `Real-Debrid-Downloader-win64.zip` - Zusaetzlich wird ein Installer gebaut: `Real-Debrid-Downloader-Setup-.exe` +- Installer legt automatisch eine Desktop-Verknuepfung an ## Auto-Installer - Im GitHub Release findest du direkt die Setup-Datei (`...Setup-.exe`) - Setup installiert die App unter `Programme/Real-Debrid Downloader` -- Optional erstellt Setup eine Desktop-Verknuepfung +- Setup erstellt automatisch eine Desktop-Verknuepfung mit App-Icon + +## App-Icon + +- Das Projekt nutzt `assets/app_icon.png` (aus deinem `Downloads/abc.png`) +- Beim Build wird automatisch `assets/app_icon.ico` erzeugt Beispiel: diff --git a/assets/app_icon.ico b/assets/app_icon.ico new file mode 100644 index 0000000..1a222ce Binary files /dev/null and b/assets/app_icon.ico differ diff --git a/assets/app_icon.png b/assets/app_icon.png new file mode 100644 index 0000000..16bd10b Binary files /dev/null and b/assets/app_icon.png differ diff --git a/build_exe.ps1 b/build_exe.ps1 index 9d3c970..74426e3 100644 --- a/build_exe.ps1 +++ b/build_exe.ps1 @@ -1,6 +1,16 @@ +param( + [string]$Version = "" +) + python -m pip install --upgrade pip pip install -r requirements.txt -pip install pyinstaller -pyinstaller --noconfirm --onefile --windowed --name "Real-Debrid-Downloader" real_debrid_downloader_gui.py +pip install pyinstaller pillow -Write-Host "Build fertig: dist/Real-Debrid-Downloader.exe" +if ($Version -ne "") { + python scripts/set_version.py $Version +} + +python scripts/prepare_icon.py +pyinstaller --noconfirm --windowed --onedir --name "Real-Debrid-Downloader" --icon "assets/app_icon.ico" real_debrid_downloader_gui.py + +Write-Host "Build fertig: dist/Real-Debrid-Downloader/Real-Debrid-Downloader.exe" diff --git a/installer/RealDebridDownloader.iss b/installer/RealDebridDownloader.iss index 2b64e1d..b749627 100644 --- a/installer/RealDebridDownloader.iss +++ b/installer/RealDebridDownloader.iss @@ -5,14 +5,18 @@ #define MyAppVersion "1.0.0" #endif -#ifndef MySourceExe - #define MySourceExe "dist\\Real-Debrid-Downloader.exe" +#ifndef MySourceDir + #define MySourceDir "..\\dist\\Real-Debrid-Downloader" #endif #ifndef MyOutputDir #define MyOutputDir "release" #endif +#ifndef MyIconFile + #define MyIconFile "..\\assets\\app_icon.ico" +#endif + [Setup] AppId={{C0E95B39-389E-4D2C-8E1E-12A44E8AE8E0} AppName={#MyAppName} @@ -25,23 +29,22 @@ OutputBaseFilename=Real-Debrid-Downloader-Setup-{#MyAppVersion} Compression=lzma SolidCompression=yes WizardStyle=modern -PrivilegesRequired=lowest +PrivilegesRequired=admin ArchitecturesInstallIn64BitMode=x64compatible UninstallDisplayIcon={app}\{#MyAppExeName} +SetupIconFile={#MyIconFile} [Languages] Name: "german"; MessagesFile: "compiler:Languages\German.isl" Name: "english"; MessagesFile: "compiler:Default.isl" -[Tasks] -Name: "desktopicon"; Description: "Desktop-Verknuepfung erstellen"; GroupDescription: "Zusaetzliche Aufgaben:"; Flags: unchecked - [Files] -Source: "{#MySourceExe}"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MySourceDir}\\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyIconFile}"; DestDir: "{app}"; DestName: "app_icon.ico"; Flags: ignoreversion [Icons] -Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" -Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon +Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\app_icon.ico" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\app_icon.ico" [Run] Filename: "{app}\{#MyAppExeName}"; Description: "{#MyAppName} starten"; Flags: nowait postinstall skipifsilent diff --git a/real_debrid_downloader_gui.py b/real_debrid_downloader_gui.py index 1b9041b..9040d2b 100644 --- a/real_debrid_downloader_gui.py +++ b/real_debrid_downloader_gui.py @@ -29,7 +29,7 @@ API_BASE_URL = "https://api.real-debrid.com/rest/1.0" CONFIG_FILE = Path(__file__).with_name("rd_downloader_config.json") CHUNK_SIZE = 1024 * 512 APP_NAME = "Real-Debrid Downloader GUI" -APP_VERSION = "1.0.0" +APP_VERSION = "1.0.5" DEFAULT_UPDATE_REPO = "Sucukdeluxe/real-debrid-downloader" DEFAULT_RELEASE_ASSET = "Real-Debrid-Downloader-win64.zip" REQUEST_RETRIES = 3 @@ -223,19 +223,12 @@ def fetch_latest_release(session: requests.Session, repo: str, preferred_asset: chosen = None for asset in assets: - if asset.get("name") == preferred_asset: + if str(asset.get("name", "")).strip() == preferred_asset: chosen = asset break if chosen is None: - for asset in assets: - name = str(asset.get("name", "")).lower() - if name.endswith(".zip"): - chosen = asset - break - - if chosen is None: - chosen = assets[0] + raise RuntimeError(f"Release-Asset '{preferred_asset}' nicht gefunden") return ReleaseInfo( version=normalize_version(str(payload.get("tag_name", "0.0.0"))), diff --git a/scripts/prepare_icon.py b/scripts/prepare_icon.py new file mode 100644 index 0000000..4f8b205 --- /dev/null +++ b/scripts/prepare_icon.py @@ -0,0 +1,29 @@ +from pathlib import Path + + +def main() -> int: + project_root = Path(__file__).resolve().parents[1] + png_path = project_root / "assets" / "app_icon.png" + ico_path = project_root / "assets" / "app_icon.ico" + + if not png_path.exists(): + print(f"Icon PNG not found: {png_path}") + return 1 + + try: + from PIL import Image + except ImportError: + print("Pillow missing. Install with: pip install pillow") + return 1 + + with Image.open(png_path) as image: + image = image.convert("RGBA") + sizes = [(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)] + image.save(ico_path, format="ICO", sizes=sizes) + + print(f"Wrote icon: {ico_path}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/scripts/set_version.py b/scripts/set_version.py new file mode 100644 index 0000000..ae10e13 --- /dev/null +++ b/scripts/set_version.py @@ -0,0 +1,35 @@ +import re +import sys +from pathlib import Path + + +def main() -> int: + if len(sys.argv) < 2: + print("Usage: python scripts/set_version.py ") + return 1 + + version = sys.argv[1].strip().lstrip("v") + if not re.fullmatch(r"\d+(?:\.\d+){1,3}", version): + print(f"Invalid version: {version}") + return 1 + + target = Path(__file__).resolve().parents[1] / "real_debrid_downloader_gui.py" + content = target.read_text(encoding="utf-8") + updated, count = re.subn( + r'^APP_VERSION\s*=\s*"[^"]+"\s*$', + f'APP_VERSION = "{version}"', + content, + count=1, + flags=re.MULTILINE, + ) + if count != 1: + print("APP_VERSION marker not found") + return 1 + + target.write_text(updated, encoding="utf-8") + print(f"Set APP_VERSION to {version}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main())