Update Windows Packaging

* Rename instances of win32 to generic win or the appropriate bit where applicable
* Remove files used in GTK2
* Add spec file for use with PyInstaller
* Remove Python bbfreeze Script
* Add Github Action To Build Releases
* Add Modified script to make files used by NSIS
* Update Readme

Closes: https://github.com/deluge-torrent/deluge/pull/331
This commit is contained in:
tbkizle 2022-01-04 00:56:11 -05:00 committed by Calum Lind
parent 6da4c4bf66
commit b9a208f18f
No known key found for this signature in database
GPG Key ID: 90597A687B836BA3
39 changed files with 499 additions and 1291 deletions

79
.github/workflows/cd.yml vendored Normal file
View File

@ -0,0 +1,79 @@
name: CD
on:
push:
tags-ignore:
- "*.dev0"
pull_request:
branches:
- develop
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
Build:
runs-on: windows-latest
strategy:
matrix:
arch: [x64, x86]
python: [3.9]
libtorrent: [1.2.15]
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python}}
architecture: ${{ matrix.arch }}
- name: Cache pip
uses: actions/cache@v2
with:
path: '%LOCALAPPDATA%\pip\Cache'
# Look to see if there is a cache hit for the corresponding requirements file
key: ${{ runner.os }}-pip-${{ hashFiles('tox.ini', 'setup.py', 'requirements*.txt') }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-
- name: Install dependencies
run: |
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile("https://github.com/deluge-torrent/gvsbuild-release/releases/download/latest/gvsbuild-py${{ matrix.python }}-vs16-${{ matrix.arch }}.zip","C:\GTK.zip")
7z x C:\GTK.zip -oc:\GTK
$env:Path = "C:\GTK\release;C:\GTK\release\bin;C:\GTK\release\lib;$env:Path"
python -m pip install --upgrade pip wheel
$pycairopath = Get-Childitem Path "C:\GTK\release\python\" -Include pycairo*.whl -File -Recurse -ErrorAction SilentlyContinue | select -expand FullName
$PyGObjectpath = Get-Childitem Path "C:\GTK\release\python\" -Include PyGObject*.whl -File -Recurse -ErrorAction SilentlyContinue | select -expand FullName
pip install $pycairopath
pip install $PyGObjectpath
python -m pip install libtorrent==${{ matrix.libtorrent }}
pip install -r requirements.txt
pip install pyinstaller
- name: Install Deluge
run: |
pip install .
python setup.py install_scripts
- name: Freeze Deluge
run: |
$env:Path = "C:\GTK\release;C:\GTK\release\bin;C:\GTK\release\lib;$env:Path"
pyinstaller --clean $env:GITHUB_WORKSPACE\packaging\win\delugewin.spec --distpath $env:GITHUB_WORKSPACE\packaging\win\freeze
- name: Make Deluge Installer
working-directory: ./packaging/win
run: |
python setup_nsis.py
makensis /Darch=${{ matrix.arch }} deluge-win-installer.nsi
- uses: actions/upload-artifact@v2
with:
name: deluge-py${{matrix.python}}-lt${{matrix.libtorrent}}
path: packaging/win/*.exe

32
packaging/win/README.md Normal file
View File

@ -0,0 +1,32 @@
= 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 the pyinstaller from the deluge\packaging\win directory.spec:
`pyinstaller --clean delugewin.spec --distpath .\packaging\win\freeze`
The result is a PyInstaller version of Deluge in `packaging\win\freeze`.
3. Run the NSIS script:
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.

View File

@ -9,7 +9,7 @@
#
# Script version; displayed when running the installer
!define DELUGE_INSTALLER_VERSION "1.0"
!define DELUGE_INSTALLER_VERSION "2.0"
# Deluge program information
!define PROGRAM_NAME "Deluge"
@ -21,10 +21,17 @@
!define PROGRAM_WEB_SITE "http://deluge-torrent.org"
!define LICENSE_FILEPATH "..\..\LICENSE"
# Python files generated with bbfreeze
!define BUILD_DIR "build-win32"
!define BBFREEZE_DIR "${BUILD_DIR}\deluge-bbfreeze-${PROGRAM_VERSION}"
!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
@ -69,8 +76,6 @@ Var StartMenuFolder
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
# Run installation
!insertmacro MUI_PAGE_INSTFILES
# Popup Message if VC Redist missing
Page Custom VCRedistMessage
# Display 'finished' page
!insertmacro MUI_PAGE_FINISH
# Uninstaller pages
@ -105,45 +110,6 @@ Function finishpageaction
CreateShortCut "$DESKTOP\Deluge.lnk" "$INSTDIR\deluge.exe"
FunctionEnd
# Test if Visual Studio Redistributables 2008 SP1 installed and returns -1 if none installed
Function CheckVCRedist2008
Push $R0
ClearErrors
ReadRegDword $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{FF66E9F6-83E7-3A3E-AF14-8DE9A809A6A4}" "Version"
IfErrors 0 +2
StrCpy $R0 "-1"
Push $R1
ClearErrors
ReadRegDword $R1 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{9BE518E6-ECC6-35A9-88E4-87755C07200F}" "Version"
IfErrors 0 VSRedistInstalled
StrCpy $R1 "-1"
StrCmp $R0 "-1" +3 0
Exch $R0
Goto VSRedistInstalled
StrCmp $R1 "-1" +3 0
Exch $R1
Goto VSRedistInstalled
# else
Push "-1"
VSRedistInstalled:
FunctionEnd
Function VCRedistMessage
Call CheckVCRedist2008
Pop $R0
StrCmp $R0 "-1" 0 end
MessageBox MB_YESNO|MB_ICONEXCLAMATION "Deluge requires an MSVC package to run \
but the recommended package does not appear to be installed:$\r$\n$\r$\n\
Microsoft Visual C++ 2008 SP1 Redistributable Package (x86)$\r$\n$\r$\n\
Would you like to download it now?" /SD IDNO IDYES clickyes
Goto end
clickyes:
ExecShell open "https://www.microsoft.com/en-us/download/details.aspx?id=26368"
end:
FunctionEnd
# --- Installation sections ---
!define PROGRAM_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PROGRAM_NAME}"
!define PROGRAM_UNINST_ROOT_KEY "HKLM"
@ -151,8 +117,17 @@ FunctionEnd
BrandingText "${PROGRAM_NAME} Windows Installer v${DELUGE_INSTALLER_VERSION}"
Name "${PROGRAM_NAME} ${PROGRAM_VERSION}"
OutFile "${BUILD_DIR}\${INSTALLER_FILENAME}"
InstallDir "$PROGRAMFILES\Deluge"
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

View File

@ -0,0 +1,316 @@
# -*- mode: python ; coding: utf-8 -*-
import os
import sys
import deluge.common
from PyInstaller.compat import is_win
from PyInstaller.utils.hooks import collect_all, copy_metadata
datas = []
binaries = []
hiddenimports = []
# Collect Meta Data
datas += copy_metadata('deluge', recursive=True)
datas += copy_metadata('service-identity', recursive=True)
# Add Deluge Hidden Imports
tmp_ret = collect_all('deluge')
hiddenimports += tmp_ret[2]
# Get build_version from installed deluge.
build_version = deluge.common.get_version()
#Copy UI/Plugin files to where pyinstaller expects
datas += [ ('../../deluge/ui', 'deluge/ui'),
('../../deluge/plugins', 'deluge/plugins') ]
block_cipher = None
a = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-console-script.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='deluge-console',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
b = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-gtk-script.pyw'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzb = PYZ(b.pure, b.zipped_data,
cipher=block_cipher)
exeb = EXE(pyzb,
b.scripts,
[],
exclude_binaries=True,
name='deluge-gtk',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
c = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluged-script.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzc = PYZ(c.pure, c.zipped_data,
cipher=block_cipher)
exec = EXE(pyzc,
c.scripts,
[],
exclude_binaries=True,
name='deluged',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
d = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluged-debug-script.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzd = PYZ(d.pure, d.zipped_data,
cipher=block_cipher)
exed = EXE(pyzd,
d.scripts,
[],
exclude_binaries=True,
name='deluged-debug',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
e = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-debug-script.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyze = PYZ(e.pure, e.zipped_data,
cipher=block_cipher)
exee = EXE(pyze,
e.scripts,
[],
exclude_binaries=True,
name='deluge-debug',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
f = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-script.pyw'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzf = PYZ(f.pure, f.zipped_data,
cipher=block_cipher)
exef = EXE(pyzf,
f.scripts,
[],
exclude_binaries=True,
name='deluge',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
g = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-web-debug-script.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzg = PYZ(g.pure, g.zipped_data,
cipher=block_cipher)
exeg = EXE(pyzg,
g.scripts,
[],
exclude_binaries=True,
name='deluge-web-debug',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
h = Analysis([os.path.abspath(os.path.join(HOMEPATH,os.pardir,os.pardir)) + '\Scripts\deluge-web-script.py'],
pathex=[],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyzh = PYZ(h.pure, h.zipped_data,
cipher=block_cipher)
exeh = EXE(pyzh,
h.scripts,
[],
exclude_binaries=True,
name='deluge-web',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
icon='../../deluge/ui/data/pixmaps/deluge.ico',
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
exeb,
b.binaries,
b.zipfiles,
b.datas,
exec,
c.binaries,
c.zipfiles,
c.datas,
exed,
d.binaries,
d.zipfiles,
d.datas,
exee,
e.binaries,
e.zipfiles,
e.datas,
exef,
f.binaries,
f.zipfiles,
f.datas,
exeg,
g.binaries,
g.zipfiles,
g.datas,
exeh,
h.binaries,
h.zipfiles,
h.datas,
strip=False,
upx=True,
upx_exclude=[],
name='Deluge')

View File

Before

Width:  |  Height:  |  Size: 201 KiB

After

Width:  |  Height:  |  Size: 201 KiB

View File

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,50 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2012-2015 Calum Lind <calumlind@gmail.com>
# Copyright (C) 2010 Damien Churchill <damoxc@gmail.com>
# Copyright (C) 2009-2010 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Jesper Lund <mail@jesperlund.com>
#
# 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)

View File

@ -1,25 +0,0 @@
gtk-theme-name = "DelugeStart"
gtk-icon-theme-name = "Tango"
gtk-fallback-icon-theme = "hicolor"
gtk-alternative-button-order = 1
gtk-alternative-sort-arrows = 1
gtk-auto-mnemonics = 1
gtk-show-input-method-menu = 0
gtk-show-unicode-menu = 0
#gtk-toolbar-icon-size = small-toolbar
gtk-button-images = 0
gtk-menu-images = 1
style "notebook"
{
xthickness = 1
ythickness = 1
}
widget_class "*<GtkNotebook>" style "notebook"
style "user-font"
{
font_name="9"
}
widget_class "*" style "user-font"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 B

View File

@ -1,519 +0,0 @@
# DelugeStart ( based upon ANewStart by alecive )
# Licensed under the GPL.
# Requires Murrine v0.91.0
gtk_color_scheme = "bg_color:#F5F5F5\nselected_bg_color:#8DCCF0\nbase_color:#FFFFFF" # Background, base
gtk_color_scheme = "fg_color:#3C4343\nselected_fg_color:#1E2222\ntext_color:#3C4343" # Foreground, text
#gtk_color_scheme = "sidebar_color:#DEDEDE" # Custom colors
gtk_color_scheme = "tooltip_bg_color:#B7DB67\ntooltip_fg_color:#F5F5F5" # Tooltips
gtk_color_scheme = "theme_color_04:#a9a49c\ntheme_color_26:#292421\ntheme_color_27:#C7C7C7" # Other colors
#gtk_color_scheme = "link_color:#08C" # Hyperlinks
gtk-icon-sizes = "panel-menu=23,23:panel=21,21:gtk-button=17,17:gtk-large-toolbar=22,22"
gtk-button-images = 0 # Disables icons for buttons with text
gtk-toolbar-style = 0 # Disables text in toolbar
gtk-auto-mnemonics = 1 # Disables lines under menu items
style "default"
{
xthickness = 1
ythickness = 1
GtkArrow::arrow-scaling = 0.6
GtkComboBox::arrow-scaling = 0.2
GtkScrolledWindow ::scrollbar-spacing = 0
GtkScrolledWindow ::scrollbar-within-bevel = 0
GtkScrollbar::slider_width = 11
GtkScrollbar::has-backward-stepper = 0
GtkScrollbar::has-forward-stepper = 0
GtkScrollbar::min-slider-length = 30
GtkButton::child-displacement-x = 1
GtkButton::child-displacement-y = 1
GtkButton::default-border = { 0, 0, 0, 0 }
GtkCheckButton::indicator-size = 12
GtkPaned::handle-size = 6
GtkRange::trough-border = 1
GtkRange::stepper-size = 12
GtkRange::trough-under-steppers = 1
GtkRange::slider-width = 14
GtkScale::slider-length = 14
GtkScale::slider-width = 14
GtkScale::trough-side-details = 1
GtkScale::trough-border = 1
GtkExpander::expander-size = 14
GtkTreeView::expander-size = 14
GtkTreeView::indent-expanders = 0
GtkMenu::horizontal-offset = 2
GtkMenu::vertical-offset = 2
GtkMenu::horizontal-padding = 2
GtkMenu::vertical-padding = 2
GtkMenuItem::arrow-spacing = 0
GtkMenuBar::internal-padding = 2
GtkMenuBar::shadow_type = GTK_SHADOW_NONE
#set to the same as roundness, used for better hotspot selection of tabs
GtkNotebook::tab-curvature = 3
GtkNotebook::tab-overlap = -1
GtkToolbar::internal-padding = 2
GtkToolbar::horizontal-padding = 0
GtkToolbar::vertical-padding = 0
GtkToolbar::shadow_type = GTK_SHADOW_NONE #gtk.SHADOW_IN, gtk.SHADOW_OUT, gtk.SHADOW_ETCHED_IN or gtk.SHADOW_ETCHED_OUT
WnckTasklist::fade-overlay-rect = 0
# The following line hints to gecko (and possibly other appliations)
# that the entry should be drawn transparently on the canvas.
# Without this, gecko will fill in the background of the entry.
# GtkEntry::honors-transparent-bg-hint = 1
GtkEntry::progress-border = { 2, 2, 2, 2 }
fg[NORMAL] = @fg_color
fg[PRELIGHT] = @fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @fg_color
fg[INSENSITIVE] = darker (@bg_color)
bg[NORMAL] = @bg_color
bg[PRELIGHT] = shade (1.04, @bg_color)
bg[SELECTED] = @selected_bg_color
bg[INSENSITIVE] = @bg_color
bg[ACTIVE] = shade (0.9, @bg_color)
base[NORMAL] = @base_color
base[PRELIGHT] = shade (0.95, @bg_color)
base[ACTIVE] = mix (0.7, @selected_bg_color, @bg_color)
base[SELECTED] = @selected_bg_color
base[INSENSITIVE] = @bg_color
text[NORMAL] = @text_color
text[PRELIGHT] = @text_color
text[ACTIVE] = @selected_fg_color
text[SELECTED] = @selected_fg_color
text[INSENSITIVE] = darker (@bg_color)
engine "murrine"
{
animation = TRUE # FALSE = disabled, TRUE = enabled
arrowstyle = 1
# border_shades = { 1.0, 1.0} # draw a gradient on the border.
# border_colors = { "#E6DDD5", "#E6DDD5" }
colorize_scrollbar = FALSE # FALSE = disabled, TRUE = enabled
comboboxstyle = 0 # colorize the GtkComboBox below the arrow.
contrast = .85 # 0.8 for less contrast, more than 1.0 for more contrast on borders
# focus_color = @selected_bg_color
# glazestyle = 5 # 0 = flat, 1 = curved, 2 = concave, 3 = top-curved, 4 = beryl
glazestyle = 4 # 0 = flat, 1 = curved, 2 = concave, 3 = top-curved, 4 = beryl
glow_shade = 1.15 # sets glow amount for buttons or widgets
glowstyle = 0 # 0 = top, 1 = bottom, 2 = top and bottom, 3 = center (vertical), 4 = center (horizontal)
gradient_shades = { 1.13, 1.02, 1.00, 1.02 } # default: {1.1,1.0,1.0,1.1}
highlight_shade = 1.0 # set highlight amount for buttons or widgets
lightborder_shade = 1.2 # sets lightborder amount for buttons or widgets
lightborderstyle = 1 # 0 = lightborder on top side, 1 = lightborder on all sides
listviewheaderstyle = 1 # 0 = flat, 1 = glassy, 2 = raised
listviewstyle = 0 # 0 = nothing, 1 = dotted
menubaritemstyle = 0 # 0 = menuitem look, 1 = button look
menubarstyle = 0 # 0 = flat, 1 = glassy, 2 = gradient, 3 = striped
menuitemstyle = 1 # 0 = flat, 1 = glassy, 2 = striped
menustyle = 0 # 0 = no vertical menu stripe, 1 = display vertical menu stripe
prelight_shade = 1.20 #to select the shade level used in the scrollbar's slider, GtkComboBox with comboboxstyle = 1 and in the prelight state with gradient_colors.
progressbarstyle = 0 # 0 = no stripes, 1 = diagonal stripes, 2 = vertical stripes
reliefstyle = 4 # 0 = flat, 1 = inset, 2 = shadow, = 3 for a gradient on shadow, = 4 for a stronger shadow.
rgba = FALSE # FALSE = disabled, TRUE = enabled
roundness = 2 # 0 = squared, 1 = old default, more will increase roundness
scrollbarstyle = 0 # 0 = nothing, 1 = circles, 2 = handles, 3 = diagonal stripes, 4 = diagonal stripes and handles, 5 = horizontal stripes, 6 = horizontal stripes and handles
shadow_shades = { 0.8, 2.2 }
sliderstyle = 0 # 0 = nothing added, 1 = handles
spinbuttonstyle = 1
stepperstyle = 1 # 0 = standard, 1 = integrated stepper handles, 2 = squared steppers with a rounded slider
# textstyle = 1
trough_shades = {1.1,0.87}
toolbarstyle = 0 # 0 = flat, 1 = glassy, 2 = gradient
separatorstyle = 1 # 0 = solid line, 1 = smooth separator
}
}
style "wide"
{
xthickness = 2
ythickness = 2
}
style "wider"
{
xthickness = 3
ythickness = 3
}
style "dark"
{
#bg[NORMAL] = @bg_color
#bg[SELECTED] = @selected_bg_color
#bg[PRELIGHT] = @selected_bg_color
#bg[ACTIVE] = @selected_bg_color
#bg[INSENSITIVE] = @bg_color
#fg[NORMAL] = @bg_color
#fg[PRELIGHT] = @selected_fg_color
#fg[SELECTED] = @selected_fg_color
#fg[ACTIVE] = @selected_fg_color
#fg[INSENSITIVE] = @selected_fg_color
}
style "button" = "wide"
{
engine "murrine"
{
roundness = 3
gradient_shades = { 1.06, 0.95, 1.06, 0.95}
border_shades = { .7, .6}
border_colors = { @bg_color, @bg_color }
lightborderstyle = 1
lightborder_shade = 1.26
shadow_shades = {2.5,2.2}
reliefstyle = 4
}
}
style "entry" {
xthickness = 3
ythickness = 3
bg[SELECTED] = mix (0.4, @selected_bg_color, @base_color)
fg[SELECTED] = @text_color
engine "murrine"
{
focus_color = @selected_bg_color
lightborder_shade = 1.06
glow_shade = 1.9
}
}
style "terminal"
{
text[NORMAL] = darker(@selected_bg_color)
base[NORMAL] = @bg_color
TerminalScreen::background-darkness = 0.99
}
style "toolbar"
{
ythickness = 0
engine "murrine"
{
gradient_shades = {1.00,0.95,0.95,0.90}
toolbarstyle = 1
}
}
style "toolbar-toggle" = "toolbar"
{
text[NORMAL] = @text_color
text[PRELIGHT] = @text_color
text[ACTIVE] = @selected_fg_color
text[SELECTED] = @selected_fg_color
text[INSENSITIVE] = darker (@bg_color)
engine "murrine"
{
toolbarstyle = 0
}
}
style "dark-toolbar" = "dark"
{
xthickness = 0
ythickness = 2
engine "murrine"
{
border_shades = {1.2, 1.0} # draw a gradient on the border.
border_colors = { "#62635E", "#62635E" }
glowstyle = 0
gradient_shades = {1.1,1.0,1.0,0.7}
highlight_shade = 1.0
lightborder_shade = 1.0
reliefstyle = 1 # 0 = flat, 1 = inset, 2 = shadow, = 3 for a gradient on shadow, = 4 for a stronger shadow.
}
}
style "dark-toolbar-sep" = "dark-toolbar"
{
xthickness = 2
}
style "panel"
{
xthickness = 0
ythickness = 0
bg[NORMAL] = "#E3E3E3" # # Default top/bottom panel background
bg[PRELIGHT] = "#E3E3E3" # @bg_color # panel prelight
engine "murrine"
{
#border_shades = {1.2, 1.0} # draw a gradient on the border.
#border_colors = { "#2D2416", "#2D2416" }
roundness = 1
}
}
style "panel-button" = "panel"
{
engine "murrine" {
roundness = 1
border_colors = {"#7C7C7C", "#7C7C7C"}
border_shades = {1.0, 1.0} # draw a gradient on the border.
gradient_shades = {1.0,1.0,1.0,1.0}
}
}
# Based on the default style so that the colors from the button
# style are overriden again.
style "treeview-header" = "default"
{
xthickness = 1
ythickness = 1
bg[NORMAL] = "#F2F1F0"
bg[PRELIGHT] = shade (1.04, "#F2F1F0")
bg[ACTIVE] = shade (0.96, "#F2F1F0")
bg[INSENSITIVE] = "#F2F1F0"
engine "murrine" {
textstyle = 1
border_shades = {0.90, 0.78}
glowstyle = 5
glazestyle = 1
contrast = 0.8
lightborder_shade = 1.16
textstyle = 1
glow_shade = 1.0
}
}
style "progressbar"
{
xthickness = 0
ythickness = 0
bg[ACTIVE] = @bg_color
fg[PRELIGHT] = @selected_fg_color
engine "murrine" {
trough_shades = {0.9, 0.98}
roundness = 2
lightborderstyle = 1
lightborder_shade = 1.26
border_shades = {0.8, 0.8}
gradient_shades = {0.95, 1.1, 0.95, 1.1}
#trough_border_shades = {0.9, 0.9}
}
}
style "statusbar"
{
ythickness = 0
xthickness = 0
}
style "comboboxentry"
{
ythickness = 3
xthickness = 3
engine "murrine"
{
contrast = .8
}
}
style "spinbutton"
{
}
style "scale"
{
bg[ACTIVE] = @bg_color
bg[PRELIGHT] = shade(1.1, @bg_color)
fg[PRELIGHT] = @selected_fg_color
engine "murrine" {
trough_shades = {0.9, 0.98}
roundness = 6
lightborderstyle = 1
lightborder_shade = 1.26
border_shades = {0.8, 0.8}
gradient_shades = {0.95, 1.1, 0.95, 1.1}
#trough_border_shades = {0.9, 0.9}
highlight_shade = 1.02
contrast = 1.1
reliefstyle = 1
}
}
style "frame"
{
}
style "frame-title" = "frame"
{
fg[NORMAL] = lighter (@fg_color)
}
style "font"
{
font_name="9"
}
widget_class "*" style "font"
#########################################
# Matches
#########################################
# default style is applied to every widget
class "GtkWidget" style "default"
# Increase the x/ythickness in some widgets
class "GtkRange" style "default"
class "GtkFrame" style "frame"
class "GtkSeparator" style "wide"
class "GtkEntry" style "entry"
class "GtkStatusbar" style "statusbar"
widget_class "*<GtkComboBoxEntry>*" style "comboboxentry"
widget_class "*<GtkCombo>*" style "comboboxentry"
# Toolbar default: light
class "*HandleBox" style "toolbar"
class "GtkToolbar" style "toolbar"
widget_class "*HandleBox" style "toolbar"
widget_class "*<GtkToolbar>.*" style "toolbar"
#
# Toolbar exceptions:
# Browser-type and viewer-type applications get a dark toolbar.
# Everything below the toolbar for these apps are the content. This will make
# a separation on function (toolbar) and content (client area)
# Work around for http://bugzilla.gnome.org/show_bug.cgi?id=382646
style "text-is-fg-color-workaround"
{
text[NORMAL] = @fg_color
text[PRELIGHT] = mix (0.8, @fg_color, '#ffffff')
text[SELECTED] = @selected_fg_color
text[ACTIVE] = @fg_color
text[INSENSITIVE] = darker (@bg_color)
}
style "text-is-fg-color-workaround-dark"
{
#Make it work with this theme!
text[NORMAL] = @bg_color
text[PRELIGHT] = mix (1.0, @bg_color, '#ffffff')
}
# Workaround style for menus where the text color is used instead of the fg color.
style "menuitem-text-is-fg-color-workaround" {
text[NORMAL] = @fg_color
text[PRELIGHT] = @fg_color
text[SELECTED] = @selected_fg_color
text[ACTIVE] = @fg_color
text[INSENSITIVE] = darker (@bg_color)
}
# Work around for http://bugzilla.gnome.org/show_bug.cgi?id=382646
# Note that this work around assumes that the combobox is _not_ in appears-as-list mode.
widget_class "*.<GtkComboBox>.<GtkCellView>"style "text-is-fg-color-workaround"
# This is the part of the workaround that fixes the menus
widget "*.gtk-combobox-popup-menu.*" style "menuitem-text-is-fg-color-workaround"
widget "*fullscreen-toolbar" style "dark-toolbar"
widget "*fullscreen-toolbar.*" style "dark-toolbar"
widget "*fullscreen-toolbar*.GtkComboBox.GtkCellView" style "text-is-fg-color-workaround-dark"
class "GtkSpinButton" style "spinbutton"
class "GtkScale" style "scale"
class "GtkVScale" style "scale"
class "GtkHScale" style "scale"
class "GtkButton" style "button"
# General matching following, the order is choosen so that the right styles override each other
# eg. progressbar needs to be more important then the menu match.
widget_class "*<GtkFrame>" style "frame"
widget_class "*.<GtkFrame>.<GtkLabel>" style "frame-title"
widget_class "*<GtkStatusbar>*" style "wider"
widget_class "*<GtkProgressBar>" style "progressbar"
# Treeview header
widget_class "*.<GtkTreeView>.<GtkButton>" style "treeview-header"
widget_class "*.<GtkCTree>.<GtkButton>" style "treeview-header"
widget_class "*.<GtkList>.<GtkButton>" style "treeview-header"
widget_class "*.<GtkCList>.<GtkButton>" style "treeview-header"
###################################################
# Special cases and work arounds
###################################################
# Work around the usage of GtkLabel inside GtkListItems to display text.
# This breaks because the label is shown on a background that is based on the
# base color set.
style "fg-is-text-color-workaround"
{
fg[NORMAL] = @text_color
fg[PRELIGHT] = @text_color
fg[ACTIVE] = @selected_fg_color
fg[SELECTED] = @selected_fg_color
fg[INSENSITIVE] = darker (@bg_color)
}
widget_class "*<GtkListItem>*" style "fg-is-text-color-workaround"
# The same problem also exists for GtkCList and GtkCTree
# Only match GtkCList and not the parent widgets, because that would also change the headers.
widget_class "*<GtkCList>" style "fg-is-text-color-workaround"
style "dialog" = "dark"
{
bg[NORMAL] = mix(0.4, @selected_bg_color, shade(0.7, @bg_color))
fg[NORMAL] = shade(0.5, @fg_color)
text[NORMAL] = shade(0.5, @text_color)
}
style "dialog-button" = "dark"
{
bg[NORMAL] = shade(0.15, @bg_color)
bg[PRELIGHT] = shade(0.18, @bg_color)
}
include"styles/checkradiobutton"
include"styles/menu-menubar"
include"styles/notebook"
include"styles/scrollbar"
include"styles/tooltips"
style "gnome-color-chooser-combobox"
{
text[NORMAL] = @fg_color
text[PRELIGHT] = mix (0.8, @fg_color, '#ffffff')
}
widget_class "*.<GtkComboBox>.<GtkCellView>" style "gnome-color-chooser-combobox"
class "TerminalScreen" style "terminal"

View File

@ -1,179 +0,0 @@
style "checkbutton" = "default"
{
engine "pixmap"
{
image
{
function = CHECK
recolorable = TRUE
state = NORMAL
shadow = OUT
overlay_file = "Check-Radio/check1.png"
overlay_stretch = FALSE
}
image
{
function = CHECK
recolorable = TRUE
state = PRELIGHT
shadow = OUT
overlay_file = "Check-Radio/check3.png"
overlay_stretch = FALSE
}
image
{
function = CHECK
recolorable = TRUE
state = ACTIVE
shadow = OUT
overlay_file = "Check-Radio/check3.png"
overlay_stretch = FALSE
}
image
{
function = CHECK
recolorable = TRUE
state = INSENSITIVE
shadow = OUT
overlay_file = "Check-Radio/check1.png"
overlay_stretch = FALSE
}
image
{
function = CHECK
recolorable = TRUE
state = NORMAL
shadow = IN
overlay_file = "Check-Radio/check2.png"
overlay_stretch = FALSE
}
image
{
function = CHECK
recolorable = TRUE
state = PRELIGHT
shadow = IN
overlay_file = "Check-Radio/check4.png"
overlay_stretch = FALSE
}
image
{
function = CHECK
recolorable = TRUE
state = ACTIVE
shadow = IN
overlay_file = "Check-Radio/check4.png"
overlay_stretch = FALSE
}
image
{
function = CHECK
recolorable = TRUE
state = INSENSITIVE
shadow = IN
overlay_file = "Check-Radio/check5.png"
overlay_stretch = FALSE
}
image
{
function = FLAT_BOX
recolorable = TRUE
stretch = TRUE
file = "Check-Radio/checklight.png"
border = { 2, 2, 2, 2 }
}
}
}
style "radiobutton" = "default"
{
engine "pixmap"
{
image
{
function = OPTION
recolorable = TRUE
state = NORMAL
shadow = OUT
overlay_file = "Check-Radio/option1.png"
overlay_stretch = FALSE
}
image
{
function = OPTION
recolorable = TRUE
state = PRELIGHT
shadow = OUT
overlay_file = "Check-Radio/option3.png"
overlay_stretch = FALSE
}
image
{
function = OPTION
recolorable = TRUE
state = ACTIVE
shadow = OUT
overlay_file = "Check-Radio/option3.png"
overlay_stretch = FALSE
}
image
{
function = OPTION
recolorable = TRUE
state = INSENSITIVE
shadow = OUT
overlay_file = "Check-Radio/option1.png"
overlay_stretch = FALSE
}
image
{
function = OPTION
recolorable = TRUE
state = NORMAL
shadow = IN
overlay_file = "Check-Radio/option2.png"
overlay_stretch = FALSE
}
image
{
function = OPTION
recolorable = TRUE
state = PRELIGHT
shadow = IN
overlay_file = "Check-Radio/option4.png"
overlay_stretch = FALSE
}
image
{
function = OPTION
recolorable = TRUE
state = ACTIVE
shadow = IN
overlay_file = "Check-Radio/option4.png"
overlay_stretch = FALSE
}
image
{
function = OPTION
recolorable = TRUE
state = INSENSITIVE
shadow = IN
overlay_file = "Check-Radio/option1.png"
overlay_stretch = FALSE
}
image
{
function = FLAT_BOX
recolorable = TRUE
stretch = TRUE
file = "Check-Radio/checklight.png"
border = { 2, 2, 2, 2 }
}
}
}
class "GtkRadioButton" style "radiobutton"
class "GtkRadioMenuItem" style "radiobutton"
class "GtkCheckButton" style "checkbutton"
class "GtkCheckMenuItem" style "checkbutton"

View File

@ -1,50 +0,0 @@
style "menu" = "default"
{
xthickness = 2
ythickness = 2
bg[PRELIGHT] = shade (1.04, @selected_bg_color)
}
style "menuitem"
{
xthickness = 0
ythickness = 0
engine "murrine" {
roundness = 1
border_colors = {"#7C7C7C", "#7C7C7C"}
border_shades = {1.0, 1.0} # draw a gradient on the border.
gradient_shades = {1.0,1.0,1.0,1.0}
}
}
style "menubar" = "dark-toolbar"
{
ythickness = 0
xthickness = 0
bg[PRELIGHT] = shade (1.04, @selected_bg_color)
engine "murrine" {
roundness = 1
border_shades = {1.0, 1.0} # draw a gradient on the border.
border_colors = {"#7C7C7C", "#7C7C7C"}
glowstyle = 0
gradient_shades = {1.0,1.0,1.0,1.0}
highlight_shade = 1.0
lightborder_shade = 1.0
reliefstyle = 0 # 0 = flat, 1 = inset, 2 = shadow, = 3 for a gradient on shadow, = 4 for a stronger shadow.
}
}
class "GtkMenu" style "menu"
class "GtkMenuBar*" style "menubar"
class "GtkMenuItem" style "menuitem"
class "GtkTearoffMenuItem" style "menuitem"
widget_class "*GtkMenu.*" style "menu"
widget_class "*MenuBar.*" style "menubar"
widget_class "*.<MenuItem>." style "menuitem"
# The panel menubar
widget_class "*Panel*<GtkMenuBar>*" style "menubar"

View File

@ -1,29 +0,0 @@
style "notebook-close" {
stock["gtk-close"] = {
{ "Icons/close.png", *, *, * }
}
}
style "notebook" = "wider" {
bg[NORMAL] = shade (1.0615, @bg_color)
bg[ACTIVE] = shade (0.85, @bg_color)
engine "murrine" {
lightborder_shade = 1.1
highlight_shade = 1.01
}
}
style "notebookthin" = "notebook" {
xthickness = 2
ythickness = 2
}
widget_class "*<GtkNotebook>*<GtkEventBox>" style "notebook"
widget_class "*<GtkNotebook>*<GtkDrawingArea>" style "notebook"
widget_class "*<GtkNotebook>*<GtkLayout>" style "notebook"
widget_class "*<GtkNotebook>" style "notebook"
widget_class "*<GtkNotebook>*" style "notebook-close"

View File

@ -1,125 +0,0 @@
style "scrollbar" = "default"
{
engine "pixmap"
{
image
{
function = BOX
recolorable = TRUE
detail = "trough"
file = "Scrollbars/trough-scrollbar-horiz.png"
border = { 20, 20, 0, 0 }
stretch = TRUE
orientation = HORIZONTAL
}
image
{
function = BOX
recolorable = TRUE
detail = "trough"
file = "Scrollbars/trough-scrollbar-vert.png"
border = { 0, 0, 20, 20 }
stretch = TRUE
orientation = VERTICAL
}
###########x SLIDERS ##################x
image
{
function = SLIDER
recolorable = TRUE
state = NORMAL
file = "Scrollbars/slider-horiz.png"
border = { 10, 10, 0, 0 }
stretch = TRUE
orientation = HORIZONTAL
}
image
{
function = SLIDER
recolorable = TRUE
state = ACTIVE
shadow = IN
file = "Scrollbars/slider-horiz.png"
border = { 10, 10, 0, 0 }
stretch = TRUE
orientation = HORIZONTAL
}
image
{
function = SLIDER
recolorable = TRUE
state = PRELIGHT
file = "Scrollbars/slider-horiz-prelight.png"
border = { 10, 10, 0, 0 }
stretch = TRUE
orientation = HORIZONTAL
}
image
{
function = SLIDER
recolorable = TRUE
state = INSENSITIVE
file = "Scrollbars/slider-horiz-insens.png"
border = { 10, 10, 0, 0 }
stretch = TRUE
orientation = HORIZONTAL
}
#############x verticals################xx
image
{
function = SLIDER
recolorable = TRUE
state = NORMAL
file = "Scrollbars/slider-vert.png"
border = { 0, 0, 10, 10 }
stretch = TRUE
orientation = VERTICAL
}
image
{
function = SLIDER
recolorable = TRUE
state = ACTIVE
shadow = IN
file = "Scrollbars/slider-vert.png"
border = { 0, 0, 10, 10 }
stretch = TRUE
orientation = VERTICAL
}
image
{
function = SLIDER
recolorable = TRUE
state = PRELIGHT
file = "Scrollbars/slider-vert-prelight.png"
border = { 0, 0, 10, 10 }
stretch = TRUE
orientation = VERTICAL
}
image
{
function = SLIDER
recolorable = TRUE
state = INSENSITIVE
file = "Scrollbars/slider-vert-insens.png"
border = { 0, 0, 10, 10 }
stretch = TRUE
orientation = VERTICAL
}
########### END SLIDERS ##################
}
}
class "GtkScrollbar" style "scrollbar"
class "GtkVScrollbar" style "scrollbar"
class "GtkHScrollbar" style "scrollbar"

View File

@ -1,21 +0,0 @@
style "tooltips"
{
xthickness = 4
ythickness = 4
GtkWidget::new-tooltip-style = 1
bg[NORMAL] = @tooltip_bg_color
fg[NORMAL] = @tooltip_fg_color
}
widget "gtk-tooltips" style "tooltips"
class "*GtkTooltips*" style "tooltips"
widget_class "*Tooltips*" style "tooltips"
widget "*.nautilus-extra-view-widget" style:highest "tooltips"
style "nautilusrename" {
# fg[NORMAL] = "#e1e1e1"
}
widget_class "*.EelEditableLabel" style "nautilusrename"

View File

@ -1,12 +0,0 @@
[Desktop Entry]
Version=1.2
Encoding=UTF-8
Name=DelugeStart
Type=X-GNOME-Metatheme
Comment=DelugeStart theme by alecive
[X-GNOME-Metatheme]
GtkTheme=DelugeStart
IconTheme=AwOken-303030
CursorTheme=DMZ-White
ButtonLayout=menu:minimize,maximize,close

View File

@ -1,22 +0,0 @@
= Deluge Installer for Windows =
Instructions for building the Deluge NSIS Installer for Windows XP/Vista/7.
== Dependencies ==
* Deluge build: http://dev.deluge-torrent.org/wiki/Installing/Source#WindowsDependencies
* Bbfreeze: http://pypi.python.org/pypi/bbfreeze
* NSIS: http://nsis.sourceforge.net/Download
== Build Steps ==
1. Build and Install Deluge on Windows.
2. Run the bbfreeze script from the win32 directory:
python deluge-bbfreeze.py
The result is a bbfreeze'd version of Deluge in `build-win32/deluge-bbfreeze-build_version`.
3. Run the NSIS script (right-click and choose `Compile with NSIS`)
The result is a standalone installer in the `build-win32` directory.

View File

@ -1,262 +0,0 @@
#!/usr/bin/env python
#
# Copyright (C) 2012-2015 Calum Lind <calumlind@gmail.com>
# Copyright (C) 2010 Damien Churchill <damoxc@gmail.com>
# Copyright (C) 2009-2010 Andrew Resch <andrewresch@gmail.com>
# Copyright (C) 2009 Jesper Lund <mail@jesperlund.com>
#
# 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.
#
# isort:skip_file
import glob
import os
import re
import shutil
import sys
import bbfreeze
import gtk
from win32verstamp import stamp
import deluge.common
class VersionInfo:
def __init__(
self,
version,
internalname=None,
originalfilename=None,
comments=None,
company=None,
description=None,
_copyright=None,
trademarks=None,
product=None,
dll=False,
debug=False,
verbose=True,
):
parts = version.split('.')
while len(parts) < 4:
parts.append('0')
self.version = '.'.join(parts)
self.internal_name = internalname
self.original_filename = originalfilename
self.comments = comments
self.company = company
self.description = description
self.copyright = _copyright
self.trademarks = trademarks
self.product = product
self.dll = dll
self.debug = debug
self.verbose = verbose
DEBUG = False
if len(sys.argv) == 2 and sys.argv[1].lower() == 'debug':
DEBUG = True
# Get build_version from installed deluge.
build_version = deluge.common.get_version()
python_path = os.path.dirname(sys.executable)
if python_path.endswith('Scripts'):
python_path = python_path[:-8]
gtk_root = os.path.join(gtk.__path__[0], '..', 'runtime')
build_dir = os.path.join('build-win32', 'deluge-bbfreeze-' + build_version)
if DEBUG:
print('Python Path: %s' % python_path)
print('Gtk Path: %s' % gtk_root)
print('bbfreeze Output Path: %s' % build_dir)
print('Freezing Deluge %s...' % build_version)
# Disable printing to console for bbfreezing.
if not DEBUG:
sys.stdout = open(os.devnull, 'w')
# Include python modules not picked up automatically by bbfreeze.
includes = (
'libtorrent',
'cairo',
'pangocairo',
'atk',
'pango',
'twisted.internet.utils',
'gio',
'gzip',
'email.mime.multipart',
'email.mime.text',
'_cffi_backend',
)
excludes = ('numpy', 'OpenGL', 'psyco', 'win32ui', 'unittest')
def recipe_gtk_override(mf):
# Override bbfreeze function so that it includes all gtk libraries
# in the installer so users don't require a separate GTK+ installation.
return True
bbfreeze.recipes.recipe_gtk_and_friends = recipe_gtk_override
# Workaround for "ImportError: The 'packaging' package is required" with setuptools > 18.8.
# (https://github.com/pypa/setuptools/issues/517)
bbfreeze.recipes.recipe_pkg_resources = bbfreeze.recipes.include_whole_package(
'pkg_resources'
)
fzr = bbfreeze.Freezer(build_dir, includes=includes, excludes=excludes)
fzr.include_py = False
fzr.setIcon(
os.path.join(
os.path.dirname(deluge.common.__file__), 'ui', 'data', 'pixmaps', 'deluge.ico'
)
)
# TODO: Can/should we grab the script list from setup.py entry_points somehow.
# Hide cmd console popup for these console entries force gui_script True.
force_gui = ['deluge-web', 'deluged']
for force_script in force_gui:
script_path = os.path.join(python_path, 'Scripts', force_script + '-script.py')
shutil.copy(script_path, script_path.replace('script', 'debug-script'))
script_list = []
for script in glob.glob(os.path.join(python_path, 'Scripts\\deluge*-script.py*')):
# Copy the scripts to remove the '-script' suffix before adding to freezer.
new_script = script.replace('-script', '')
shutil.copy(script, new_script)
gui_script = False
script_splitext = os.path.splitext(os.path.basename(new_script))
if script_splitext[1] == '.pyw' or script_splitext[0] in force_gui:
gui_script = True
try:
fzr.addScript(new_script, gui_only=gui_script)
script_list.append(new_script)
except Exception:
os.remove(script)
# Start the freezing process.
fzr()
# Clean up the duplicated scripts.
for script in script_list:
os.remove(script)
# Exclude files which are already included in GTK or Windows. Also exclude unneeded pygame dlls.
exclude_dlls = (
'MSIMG32.dll',
'MSVCR90.dll',
'MSVCP90.dll',
'MSVCR120.dll',
'POWRPROF.dll',
'DNSAPI.dll',
'USP10.dll',
'MPR.dll',
'jpeg.dll',
'libfreetype-6.dll',
'libpng12-0.dll',
'libtiff.dll',
'SDL_image.dll',
'SDL_ttf.dll',
)
for exclude_dll in exclude_dlls:
try:
os.remove(os.path.join(build_dir, exclude_dll))
except OSError:
pass
# Re-enable printing.
if not DEBUG:
sys.stdout = sys.__stdout__
# Copy gtk locale files.
gtk_locale = os.path.join(gtk_root, 'share/locale')
locale_include_list = ['gtk20.mo', 'locale.alias']
def ignored_files(adir, ignore_filenames):
return [
ignore_file
for ignore_file in ignore_filenames
if not os.path.isdir(os.path.join(adir, ignore_file))
and ignore_file not in locale_include_list
]
shutil.copytree(
gtk_locale, os.path.join(build_dir, 'share/locale'), ignore=ignored_files
)
# Copy gtk theme files.
theme_include_list = [
[gtk_root, 'share/icons/hicolor/index.theme'],
[gtk_root, 'lib/gtk-2.0/2.10.0/engines'],
[gtk_root, 'share/themes/MS-Windows'],
['DelugeStart Theme', 'lib/gtk-2.0/2.10.0/engines/libmurrine.dll'],
['DelugeStart Theme', 'share/themes/DelugeStart'],
['DelugeStart Theme', 'etc/gtk-2.0/gtkrc'],
]
for path_root, path in theme_include_list:
full_path = os.path.join(path_root, path)
if os.path.isdir(full_path):
shutil.copytree(full_path, os.path.join(build_dir, path))
else:
dst_dir = os.path.join(build_dir, os.path.dirname(path))
try:
os.makedirs(dst_dir)
except OSError:
pass
shutil.copy(full_path, dst_dir)
# Add version information to exe files.
for script in script_list:
script_exe = os.path.splitext(os.path.basename(script))[0] + '.exe'
# Don't add to dev build versions.
if not re.search('[a-zA-Z_-]', build_version):
version_info = VersionInfo(
build_version,
description='Deluge Bittorrent Client',
company='Deluge Team',
product='Deluge',
_copyright='Deluge Team',
)
stamp(os.path.join(build_dir, script_exe), version_info)
# 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 "${BBFREEZE_DIR}%s"\n' % os.path.join(dirname, filename))
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)