From f702b50b6ac6cb2e1e0e848a629a623f323c9de2 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 24 Jun 2023 19:38:33 +0200 Subject: Merging upstream version 2.1.2~dev0+20230529. Signed-off-by: Daniel Baumann --- packaging/win/README.md | 34 +++++ packaging/win/deluge-win-installer.nsi | 234 +++++++++++++++++++++++++++++++++ packaging/win/delugewin.spec | 183 ++++++++++++++++++++++++++ packaging/win/installer-side.bmp | Bin 0 -> 206038 bytes packaging/win/installer-top.bmp | Bin 0 -> 34254 bytes packaging/win/pyi_rth_gtk_csd.py | 3 + packaging/win/setup_nsis.py | 49 +++++++ 7 files changed, 503 insertions(+) create mode 100644 packaging/win/README.md create mode 100644 packaging/win/deluge-win-installer.nsi create mode 100644 packaging/win/delugewin.spec create mode 100644 packaging/win/installer-side.bmp create mode 100644 packaging/win/installer-top.bmp create mode 100644 packaging/win/pyi_rth_gtk_csd.py create mode 100644 packaging/win/setup_nsis.py (limited to 'packaging/win') diff --git a/packaging/win/README.md b/packaging/win/README.md new file mode 100644 index 0000000..272792c --- /dev/null +++ b/packaging/win/README.md @@ -0,0 +1,34 @@ += Deluge Installer for Windows = + +Instructions for building the Deluge NSIS Installer for Windows Vista/7/8/8.1/10/11. + +== Dependencies == + +- Deluge build: https://deluge.readthedocs.io/en/latest/depends.html +- PyInstaller: https://pypi.org/project/pyinstaller/ +- NSIS: http://nsis.sourceforge.net/Download + +== Build Steps == + +1. Build and Install Deluge on Windows. +2. Run pyinstaller from the deluge\packaging\win directory: + + `pyinstaller --clean delugewin.spec --distpath freeze` + + The result is a PyInstaller version of Deluge in `packaging\win\freeze`. + +3. Run the NSIS scripts: + + `python setup_nsis.py` + + 64-bit python: + + `makensis /Darch=x64 deluge-win-installer.nsi` + + 32-bit python: + + `makensis /Darch=x86 deluge-win-installer.nsi` + + Note: If you don't specify arch defaults to trying x64 + +The result is a standalone installer in the `packaging\win` directory. diff --git a/packaging/win/deluge-win-installer.nsi b/packaging/win/deluge-win-installer.nsi new file mode 100644 index 0000000..1f9c2e2 --- /dev/null +++ b/packaging/win/deluge-win-installer.nsi @@ -0,0 +1,234 @@ +# Deluge Windows installer script +# +# Copyright (C) 2009 Jesper Lund +# Copyright (C) 2009 Andrew Resch +# Copyright (C) 2009 John Garland +# +# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later. +# See LICENSE for more details. +# + +# Script version; displayed when running the installer +!define DELUGE_INSTALLER_VERSION "2.0" + +# Deluge program information +!define PROGRAM_NAME "Deluge" +# Detect version from file +!searchparse /file VERSION.tmp `build_version = "` PROGRAM_VERSION `"` +!ifndef PROGRAM_VERSION + !error "Program Version Undefined" +!endif +!define PROGRAM_WEB_SITE "http://deluge-torrent.org" +!define LICENSE_FILEPATH "..\..\LICENSE" + +!include FileFunc.nsh + +!ifndef arch +!define INSTALLER_FILENAME "deluge-${PROGRAM_VERSION}-win64-setup.exe" +!endif +!If "${arch}" == "x64" +!define INSTALLER_FILENAME "deluge-${PROGRAM_VERSION}-win64-setup.exe" +!EndIf +!If "${arch}" == "x86" +!define INSTALLER_FILENAME "deluge-${PROGRAM_VERSION}-win32-setup.exe" +!EndIf + +# Set default compressor +SetCompressor /FINAL /SOLID lzma +SetCompressorDictSize 64 + +# --- Interface settings --- +# Modern User Interface 2 +!include MUI2.nsh +# Installer +!define MUI_ICON "..\..\deluge\ui\data\pixmaps\deluge.ico" +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_RIGHT +!define MUI_HEADERIMAGE_BITMAP "installer-top.bmp" +!define MUI_WELCOMEFINISHPAGE_BITMAP "installer-side.bmp" +!define MUI_COMPONENTSPAGE_SMALLDESC +!define MUI_FINISHPAGE_NOAUTOCLOSE +!define MUI_ABORTWARNING +# Start Menu Folder Page Configuration +!define MUI_STARTMENUPAGE_DEFAULTFOLDER ${PROGRAM_NAME} +!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCR" +!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Deluge" +!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder" +# Uninstaller +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" +!define MUI_HEADERIMAGE_UNBITMAP "installer-top.bmp" +!define MUI_WELCOMEFINISHPAGE_UNBITMAP "installer-side.bmp" +!define MUI_UNFINISHPAGE_NOAUTOCLOSE + +!define MUI_FINISHPAGE_SHOWREADME "" +!define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED +!define MUI_FINISHPAGE_SHOWREADME_TEXT "Create Desktop Shortcut" +!define MUI_FINISHPAGE_SHOWREADME_FUNCTION finishpageaction + +# --- Start of Modern User Interface --- +Var StartMenuFolder +# Welcome, License & Components pages +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE ${LICENSE_FILEPATH} +!insertmacro MUI_PAGE_COMPONENTS +# Let the user select the installation directory +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder +# Run installation +!insertmacro MUI_PAGE_INSTFILES +# Display 'finished' page +!insertmacro MUI_PAGE_FINISH +# Uninstaller pages +!insertmacro MUI_UNPAGE_INSTFILES +# Language files +!insertmacro MUI_LANGUAGE "English" + + +# --- Functions --- + +# Check for running Deluge instance. +Function .onInit + System::Call 'kernel32::OpenMutex(i 0x100000, b 0, t "deluge") i .R0' + IntCmp $R0 0 notRunning + System::Call 'kernel32::CloseHandle(i $R0)' + MessageBox MB_OK|MB_ICONEXCLAMATION "Deluge is running. Please close it first" /SD IDOK + Abort + notRunning: +FunctionEnd + +Function un.onUninstSuccess + HideWindow + MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer." /SD IDOK +FunctionEnd + +Function un.onInit + MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Do you want to completely remove $(^Name)?" /SD IDYES IDYES +2 + Abort +FunctionEnd + +Function finishpageaction + CreateShortCut "$DESKTOP\Deluge.lnk" "$INSTDIR\deluge.exe" +FunctionEnd + +# --- Installation sections --- +!define PROGRAM_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}" +!define PROGRAM_UNINST_ROOT_KEY "HKLM" +!define PROGRAM_UNINST_FILENAME "$INSTDIR\deluge-uninst.exe" + +BrandingText "${PROGRAM_NAME} Windows Installer v${DELUGE_INSTALLER_VERSION}" +Name "${PROGRAM_NAME} ${PROGRAM_VERSION}" +OutFile "${INSTALLER_FILENAME}" + +!ifndef arch +InstallDir "$PROGRAMFILES64\Deluge" +!endif +!If "${arch}" == "x64" +InstallDir "$PROGRAMFILES64\Deluge" +!endIf +!If "${arch}" == "x86" +InstallDir "$PROGRAMFILES32\Deluge" +!endIf + +ShowInstDetails show +ShowUnInstDetails show + +# Install main application +Section "Deluge Bittorrent Client" Section1 + SectionIn RO + !include "install_files.nsh" + + SetOverwrite ifnewer + SetOutPath "$INSTDIR" + File ${LICENSE_FILEPATH} + WriteIniStr "$INSTDIR\homepage.url" "InternetShortcut" "URL" "${PROGRAM_WEB_SITE}" + + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + SetShellVarContext all + CreateDirectory "$SMPROGRAMS\$StartMenuFolder" + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Deluge.lnk" "$INSTDIR\deluge.exe" + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Website.lnk" "$INSTDIR\homepage.url" + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Uninstall Deluge.lnk" ${PROGRAM_UNINST_FILENAME} + !insertmacro MUI_STARTMENU_WRITE_END +SectionEnd + +# Create .torrent file association. +Section "Associate .torrent files with Deluge" Section2 + DeleteRegKey HKCR ".torrent" + WriteRegStr HKCR ".torrent" "" "Deluge" + WriteRegStr HKCR ".torrent" "Content Type" "application/x-bittorrent" + + DeleteRegKey HKCR "Deluge" + WriteRegStr HKCR "Deluge" "" "Deluge" + WriteRegStr HKCR "Deluge\Content Type" "" "application/x-bittorrent" + WriteRegStr HKCR "Deluge\DefaultIcon" "" "$INSTDIR\deluge.exe,0" + WriteRegStr HKCR "Deluge\shell" "" "open" + WriteRegStr HKCR "Deluge\shell\open\command" "" '"$INSTDIR\deluge.exe" "%1"' +SectionEnd + +# Create magnet uri association. +Section "Associate Magnet URI links with Deluge" Section3 + DeleteRegKey HKCR "Magnet" + WriteRegStr HKCR "Magnet" "" "URL:Magnet Protocol" + WriteRegStr HKCR "Magnet" "URL Protocol" "" + WriteRegStr HKCR "Magnet\shell\open\command" "" '"$INSTDIR\deluge.exe" "%1"' +SectionEnd + +LangString DESC_Section1 ${LANG_ENGLISH} "Install Deluge Bittorrent client." +LangString DESC_Section2 ${LANG_ENGLISH} "Select this option to let Deluge handle the opening of .torrent files." +LangString DESC_Section3 ${LANG_ENGLISH} "Select this option to let Deluge handle Magnet URI links from the web-browser." + +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${Section1} $(DESC_Section1) + !insertmacro MUI_DESCRIPTION_TEXT ${Section2} $(DESC_Section2) + !insertmacro MUI_DESCRIPTION_TEXT ${Section3} $(DESC_Section3) +!insertmacro MUI_FUNCTION_DESCRIPTION_END + +# Create uninstaller. +Section -Uninstaller + WriteUninstaller ${PROGRAM_UNINST_FILENAME} + WriteRegStr ${PROGRAM_UNINST_ROOT_KEY} "${PROGRAM_UNINST_KEY}" "DisplayName" "$(^Name)" + WriteRegStr ${PROGRAM_UNINST_ROOT_KEY} "${PROGRAM_UNINST_KEY}" "DisplayVersion" ${PROGRAM_VERSION} + WriteRegStr ${PROGRAM_UNINST_ROOT_KEY} "${PROGRAM_UNINST_KEY}" "UninstallString" ${PROGRAM_UNINST_FILENAME} +SectionEnd + +# --- Uninstallation section --- +Section Uninstall + # Delete Deluge files. + Delete "$INSTDIR\LICENSE" + Delete "$INSTDIR\homepage.url" + Delete ${PROGRAM_UNINST_FILENAME} + !include "uninstall_files.nsh" + + # Delete Start Menu items. + !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder + SetShellVarContext all + Delete "$SMPROGRAMS\$StartMenuFolder\Deluge.lnk" + Delete "$SMPROGRAMS\$StartMenuFolder\Website.lnk" + Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall Deluge.lnk" + RmDir "$SMPROGRAMS\$StartMenuFolder" + DeleteRegKey /ifempty HKCR "Software\Deluge" + + Delete "$DESKTOP\Deluge.lnk" + + # Delete registry keys. + DeleteRegKey ${PROGRAM_UNINST_ROOT_KEY} "${PROGRAM_UNINST_KEY}" + # Only delete the .torrent association if Deluge owns it + ReadRegStr $1 HKCR ".torrent" "" + StrCmp $1 "Deluge" 0 DELUGE_skip_delete + # Delete the key since it is owned by Deluge; afterwards there is no .torrent association + DeleteRegKey HKCR ".torrent" + DELUGE_skip_delete: + # This key is only used by Deluge, so we should always delete it + DeleteRegKey HKCR "Deluge" +SectionEnd + +# Add version info to installer properties. +VIProductVersion "${DELUGE_INSTALLER_VERSION}.0.0" +VIAddVersionKey ProductName ${PROGRAM_NAME} +VIAddVersionKey Comments "Deluge Bittorrent Client" +VIAddVersionKey CompanyName "Deluge Team" +VIAddVersionKey LegalCopyright "Deluge Team" +VIAddVersionKey FileDescription "${PROGRAM_NAME} Application Installer" +VIAddVersionKey FileVersion "${DELUGE_INSTALLER_VERSION}.0.0" +VIAddVersionKey ProductVersion "${PROGRAM_VERSION}.0" +VIAddVersionKey OriginalFilename ${INSTALLER_FILENAME} diff --git a/packaging/win/delugewin.spec b/packaging/win/delugewin.spec new file mode 100644 index 0000000..b6b5573 --- /dev/null +++ b/packaging/win/delugewin.spec @@ -0,0 +1,183 @@ +# -*- mode: python -*- +import os + +from PyInstaller.utils.hooks import ( + collect_data_files, + collect_submodules, + copy_metadata, +) + +datas = [] +binaries = [] +hiddenimports = ['pygame', 'ifaddr'] + +# Collect Meta Data +datas += copy_metadata('deluge', recursive=True) +datas += copy_metadata('service-identity', recursive=True) + +# Add Deluge Hidden Imports +hiddenimports += collect_submodules('deluge') + +# Add stdlib as Hidden Imports. +# This is filtered list that excludes some common examples or stuff not useful in +# plugins (such as tty, mailbox, turtledemo etc.). +# It is safe to assume that 90% of that list would already be included anyway. +stdlib = [ + 'string', + 're', + 'unicodedata', + 'struct', + 'codecs', + 'datetime', + 'zoneinfo', + 'calendar', + 'collections', + 'array', + 'weakref', + 'types', + 'copy', + 'enum', + 'numbers', + 'math', + 'cmath', + 'decimal', + 'fractions', + 'random', + 'statistics', + 'itertools', + 'functools', + 'operator', + 'pathlib', + 'fileinput', + 'stat', + 'tempfile', + 'glob', + 'fnmatch', + 'shutil', + 'pickle', + 'copyreg', + 'shelve', + 'marshal', + 'dom', + 'sqlite3', + 'zlib', + 'gzip', + 'bz2', + 'lzma', + 'csv', + 'hashlib', + 'hmac', + 'secrets', + 'os', + 'io', + 'time', + 'logging', + 'platform', + 'errno', + 'queue', + 'socket', + 'ssl', + 'email', + 'json', + 'mimetypes', + 'base64', + 'binhex', + 'binascii', + 'quopri', + 'uu', + 'html', + 'xml', + 'urllib', + 'http', + 'ftplib', + 'smtplib', + 'uuid', + 'xmlrpc.client', + 'ipaddress', + 'locale', + 'sys', +] +for module in stdlib: + hiddenimports += collect_submodules(module, filter=lambda name: 'test' not in name) + +# Add Hidden Imports for Plugins +hiddenimports += collect_submodules('twisted', filter=lambda name: 'test' not in name) +datas += copy_metadata('twisted', recursive=True) + +# Copy UI/Plugin and translation files to where pyinstaller expects +package_data = collect_data_files('deluge') +datas += package_data + +icon = [src for src, dest in package_data if src.endswith('deluge.ico')][0] + +# List of executables to produce +executables = { + 'deluge-script.pyw': {'name': 'deluge', 'console': False, 'gtk': True}, + 'deluge-gtk-script.pyw': {'name': 'deluge-gtk', 'console': False, 'gtk': True}, + 'deluge-debug-script.py': {'name': 'deluge-debug', 'console': True, 'gtk': True}, + 'deluge-console-script.py': { + 'name': 'deluge-console', + 'console': True, + 'gtk': False, + }, + 'deluged-script.pyw': {'name': 'deluged', 'console': False, 'gtk': False}, + 'deluged-debug-script.py': {'name': 'deluged-debug', 'console': True, 'gtk': False}, + 'deluge-web-debug-script.py': { + 'name': 'deluge-web-debug', + 'console': True, + 'gtk': False, + }, + 'deluge-web-script.pyw': {'name': 'deluge-web', 'console': False, 'gtk': False}, +} + +analysis = {} +exe = {} +coll = [] + +# Perform analysis +for e, d in executables.items(): + runtime_hooks = [] + if d['gtk']: + runtime_hooks += [os.path.join(SPECPATH, 'pyi_rth_gtk_csd.py')] + + analysis[e] = Analysis( + [os.path.abspath(os.path.join(HOMEPATH, os.pardir, os.pardir, 'Scripts', e))], + pathex=[], + binaries=binaries, + datas=datas, + hiddenimports=hiddenimports, + hookspath=[], + hooksconfig={}, + runtime_hooks=runtime_hooks, + excludes=[], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=None, + noarchive=False, + ) + +# Executable +for e, d in executables.items(): + exe[e] = EXE( + PYZ(analysis[e].pure, analysis[e].zipped_data, cipher=None), + analysis[e].scripts, + [], + exclude_binaries=True, + name=d['name'], + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + icon=icon, + console=d['console'], + disable_windowed_traceback=False, + target_arch=None, + codesign_identity=None, + entitlements_file=None, + ) + +# Collect +for e, d in executables.items(): + coll += exe[e], analysis[e].binaries, analysis[e].zipfiles, analysis[e].datas + +COLLECT(*coll, strip=False, upx=True, upx_exclude=[], name='Deluge') diff --git a/packaging/win/installer-side.bmp b/packaging/win/installer-side.bmp new file mode 100644 index 0000000..58c2bed Binary files /dev/null and b/packaging/win/installer-side.bmp differ diff --git a/packaging/win/installer-top.bmp b/packaging/win/installer-top.bmp new file mode 100644 index 0000000..1e1a94c Binary files /dev/null and b/packaging/win/installer-top.bmp differ diff --git a/packaging/win/pyi_rth_gtk_csd.py b/packaging/win/pyi_rth_gtk_csd.py new file mode 100644 index 0000000..345122d --- /dev/null +++ b/packaging/win/pyi_rth_gtk_csd.py @@ -0,0 +1,3 @@ +import os + +os.environ['GTK_CSD'] = os.getenv('GTK_CSD', '0') diff --git a/packaging/win/setup_nsis.py b/packaging/win/setup_nsis.py new file mode 100644 index 0000000..f34a941 --- /dev/null +++ b/packaging/win/setup_nsis.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python +# +# Copyright (C) 2012-2015 Calum Lind +# Copyright (C) 2010 Damien Churchill +# Copyright (C) 2009-2010 Andrew Resch +# Copyright (C) 2009 Jesper Lund +# +# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with +# the additional special exception to link portions of this program with the OpenSSL library. +# See LICENSE for more details. +# + +import os + +import deluge.common + +# Get build_version from installed deluge. +build_version = deluge.common.get_version() +build_dir = os.path.join('freeze', 'Deluge') + +# Copy version info to file for nsis script. +with open('VERSION.tmp', 'w') as ver_file: + ver_file.write('build_version = "%s"' % build_version) + +# Create the install and uninstall file list for NSIS. +filedir_list = [] +for root, dirnames, filenames in os.walk(build_dir): + dirnames.sort() + filenames.sort() + filedir_list.append((root[len(build_dir) :], filenames)) + +with open('install_files.nsh', 'w') as f: + f.write('; Files to install\n') + for dirname, files in filedir_list: + if not dirname: + dirname = os.sep + f.write('\nSetOutPath "$INSTDIR%s"\n' % dirname) + for filename in files: + f.write('File ' + build_dir + os.path.join(dirname, filename) + '\n') + +with open('uninstall_files.nsh', 'w') as f: + f.write('; Files to uninstall\n') + for dirname, files in reversed(filedir_list): + f.write('\n') + if not dirname: + dirname = os.sep + for filename in files: + f.write('Delete "$INSTDIR%s"\n' % os.path.join(dirname, filename)) + f.write('RMDir "$INSTDIR%s"\n' % dirname) -- cgit v1.2.3