From 1c3e14919f41cac16df3909bc1ef07252e58b6f6 Mon Sep 17 00:00:00 2001 From: Calum Lind Date: Mon, 24 Aug 2015 12:39:25 +0100 Subject: [PATCH] [Win32] Refactor bbreeze script * In setup.py put web and deluged back into console_script as the gtkui hack in bbfreeze is a windows only issue for popup cmd windows showing. * Altered the bbreeze script to find any deluge scripts in pythonpath. * Use setIcon now in bbfreeze and use icon from package. * Use version stamp from pywin32. --- packaging/win32/VersionInfo.py | 292 ----------------------------- packaging/win32/deluge-bbfreeze.py | 129 ++++++++----- packaging/win32/deluge.ico | Bin 25214 -> 0 bytes packaging/win32/icon.py | 205 -------------------- setup.py | 8 +- 5 files changed, 81 insertions(+), 553 deletions(-) delete mode 100644 packaging/win32/VersionInfo.py delete mode 100644 packaging/win32/deluge.ico delete mode 100644 packaging/win32/icon.py diff --git a/packaging/win32/VersionInfo.py b/packaging/win32/VersionInfo.py deleted file mode 100644 index fbbc9eb91..000000000 --- a/packaging/win32/VersionInfo.py +++ /dev/null @@ -1,292 +0,0 @@ -# -*- coding: latin-1 -*- -## -## Copyright (c) 2000-2013 Thomas Heller -## -## Permission is hereby granted, free of charge, to any person obtaining -## a copy of this software and associated documentation files (the -## "Software"), to deal in the Software without restriction, including -## without limitation the rights to use, copy, modify, merge, publish, -## distribute, sublicense, and/or sell copies of the Software, and to -## permit persons to whom the Software is furnished to do so, subject to -## the following conditions: -## -## The above copyright notice and this permission notice shall be -## included in all copies or substantial portions of the Software. -## -## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -## LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -## OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -## WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -## - -# -# $Id: VersionInfo.py 738 2013-09-07 10:11:45Z theller $ -# -# $Log$ -# Revision 1.3 2004/01/16 10:45:31 theller -# Move py2exe from the sandbox directory up to the root dir. -# -# Revision 1.3 2003/12/29 13:44:57 theller -# Adapt for Python 2.3. -# -# Revision 1.2 2003/09/18 20:19:57 theller -# Remove a 2.3 warning, but mostly this checkin is to test the brand new -# py2exe-checkins mailing list. -# -# Revision 1.1 2003/08/29 12:30:52 mhammond -# New py2exe now uses the old resource functions :) -# -# Revision 1.1 2002/01/29 09:30:55 theller -# version 0.3.0 -# -# Revision 1.2 2002/01/14 19:08:05 theller -# Better (?) Unicode handling. -# -# Revision 1.1 2002/01/07 10:30:32 theller -# Create a version resource. -# -# -import struct - -VOS_NT_WINDOWS32 = 0x00040004 -VFT_APP = 0x00000001 - -RT_VERSION = 16 - -class VersionError(Exception): - pass - -def w32_uc(text): - """convert a string into unicode, then encode it into UTF-16 - little endian, ready to use for win32 apis""" - if type(text) is str: - return unicode(text, "unicode-escape").encode("utf-16-le") - return unicode(text).encode("utf-16-le") - -class VS_FIXEDFILEINFO: - dwSignature = 0xFEEF04BDL - dwStrucVersion = 0x00010000 - dwFileVersionMS = 0x00010000 - dwFileVersionLS = 0x00000001 - dwProductVersionMS = 0x00010000 - dwProductVersionLS = 0x00000001 - dwFileFlagsMask = 0x3F - dwFileFlags = 0 - dwFileOS = VOS_NT_WINDOWS32 - dwFileType = VFT_APP - dwFileSubtype = 0 - dwFileDateMS = 0 - dwFileDateLS = 0 - - fmt = "13L" - - def __init__(self, version): - import string - version = string.replace(version, ",", ".") - fields = string.split(version + '.0.0.0.0', ".")[:4] - fields = map(string.strip, fields) - try: - self.dwFileVersionMS = int(fields[0]) * 65536 + int(fields[1]) - self.dwFileVersionLS = int(fields[2]) * 65536 + int(fields[3]) - except ValueError: - raise VersionError("could not parse version number '%s'" % version) - - def __str__(self): - return struct.pack(self.fmt, - self.dwSignature, - self.dwStrucVersion, - self.dwFileVersionMS, - self.dwFileVersionLS, - self.dwProductVersionMS, - self.dwProductVersionLS, - self.dwFileFlagsMask, - self.dwFileFlags, - self.dwFileOS, - self.dwFileType, - self.dwFileSubtype, - self.dwFileDateMS, - self.dwFileDateLS) - -def align(data): - pad = - len(data) % 4 - return data + '\000' * pad - -class VS_STRUCT: - items = () - - def __str__(self): - szKey = w32_uc(self.name) - ulen = len(szKey)+2 - - value = self.get_value() - data = struct.pack("h%ss0i" % ulen, self.wType, szKey) + value - - data = align(data) - - for item in self.items: - data = data + str(item) - - wLength = len(data) + 4 # 4 bytes for wLength and wValueLength - wValueLength = len(value) - - return self.pack("hh", wLength, wValueLength, data) - - def pack(self, fmt, len, vlen, data): - return struct.pack(fmt, len, vlen) + data - - def get_value(self): - return "" - - -class String(VS_STRUCT): - wType = 1 - items = () - - def __init__(self, name_value): - (name, value) = name_value - self.name = name - if value: - self.value = value + '\000' # strings must be zero terminated - else: - self.value = value - - def pack(self, fmt, len, vlen, data): - # ValueLength is measured in WORDS, not in BYTES! - return struct.pack(fmt, len, vlen/2) + data - - def get_value(self): - return w32_uc(self.value) - - -class StringTable(VS_STRUCT): - wType = 1 - - def __init__(self, name, strings): - self.name = name - self.items = map(String, strings) - - -class StringFileInfo(VS_STRUCT): - wType = 1 - name = "StringFileInfo" - - def __init__(self, name, strings): - self.items = [StringTable(name, strings)] - -class Var(VS_STRUCT): - # MSDN says: - # If you use the Var structure to list the languages your - # application or DLL supports instead of using multiple version - # resources, use the Value member to contain an array of DWORD - # values indicating the language and code page combinations - # supported by this file. The low-order word of each DWORD must - # contain a Microsoft language identifier, and the high-order word - # must contain the IBM® code page number. Either high-order or - # low-order word can be zero, indicating that the file is language - # or code page independent. If the Var structure is omitted, the - # file will be interpreted as both language and code page - # independent. - wType = 0 - name = "Translation" - - def __init__(self, value): - self.value = value - - def get_value(self): - return struct.pack("l", self.value) - -class VarFileInfo(VS_STRUCT): - wType = 1 - name = "VarFileInfo" - - def __init__(self, *names): - self.items = map(Var, names) - - def get_value(self): - return "" - -class VS_VERSIONINFO(VS_STRUCT): - wType = 0 # 0: binary data, 1: text data - name = "VS_VERSION_INFO" - - def __init__(self, version, items): - self.value = VS_FIXEDFILEINFO(version) - self.items = items - - def get_value(self): - return str(self.value) - -class Version(object): - def __init__(self, - version, - comments = None, - company_name = None, - file_description = None, - internal_name = None, - legal_copyright = None, - legal_trademarks = None, - original_filename = None, - private_build = None, - product_name = None, - product_version = None, - special_build = None): - self.version = version - strings = [] - if comments is not None: - strings.append(("Comments", comments)) - if company_name is not None: - strings.append(("CompanyName", company_name)) - if file_description is not None: - strings.append(("FileDescription", file_description)) - strings.append(("FileVersion", version)) - if internal_name is not None: - strings.append(("InternalName", internal_name)) - if legal_copyright is not None: - strings.append(("LegalCopyright", legal_copyright)) - if legal_trademarks is not None: - strings.append(("LegalTrademarks", legal_trademarks)) - if original_filename is not None: - strings.append(("OriginalFilename", original_filename)) - if private_build is not None: - strings.append(("PrivateBuild", private_build)) - if product_name is not None: - strings.append(("ProductName", product_name)) - strings.append(("ProductVersion", product_version or version)) - if special_build is not None: - strings.append(("SpecialBuild", special_build)) - self.strings = strings - - def resource_bytes(self): - vs = VS_VERSIONINFO(self.version, - [StringFileInfo("040904B0", - self.strings), - VarFileInfo(0x04B00409)]) - return str(vs) - -def test(): - import sys - sys.path.append("c:/tmp") - from hexdump import hexdump - version = Version("1, 0, 0, 1", - comments = "ümläut comments", - company_name = "No Company", - file_description = "silly application", - internal_name = "silly", - legal_copyright = u"Copyright © 2003", -## legal_trademark = "", - original_filename = "silly.exe", - private_build = "test build", - product_name = "silly product", - product_version = None, -## special_build = "" - ) - hexdump(version.resource_bytes()) - -if __name__ == '__main__': - import sys - sys.path.append("d:/nbalt/tmp") - from hexdump import hexdump - test() diff --git a/packaging/win32/deluge-bbfreeze.py b/packaging/win32/deluge-bbfreeze.py index 7b2d2f0e3..a9f834e32 100644 --- a/packaging/win32/deluge-bbfreeze.py +++ b/packaging/win32/deluge-bbfreeze.py @@ -1,35 +1,56 @@ import glob import os +import re import shutil import sys -import bbfreeze.recipes +import bbfreeze import gtk import icon import win32api -from bbfreeze import Freezer -from VersionInfo import Version +from win32verstamp import stamp import deluge.common -# Get build_version from installed deluge +class VersionInfo(object): + 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 + +# Get build_version from installed deluge. build_version = deluge.common.get_version() print "Deluge Version: %s" % build_version + python_path = os.path.dirname(sys.executable) if python_path.endswith("Scripts"): python_path = python_path[:-8] python_path += os.path.sep - print "Python Path: %s" % python_path -gtk_root = os.path.join(gtk.__path__[0], "..\\runtime\\") -# Include python modules not picked up automatically by bbfreeze +gtk_root = os.path.join(gtk.__path__[0], "..", "runtime") + os.path.sep + +# 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") -dst = "..\\build-win32\\deluge-bbfreeze-" + build_version + "\\" - +build_dir = "..\\build-win32\\deluge-bbfreeze-" + build_version + "\\" # Need to override bbfreeze function so that it includes all gtk libraries # in the installer so users don't require a separate GTK+ installation. @@ -37,55 +58,58 @@ def recipe_gtk_override(mf): return True bbfreeze.recipes.recipe_gtk_and_friends = recipe_gtk_override -f = Freezer(dst, includes=includes, excludes=excludes) -f.include_py = False -# Can/should we grab this from setup.py entry_points somehow -gui_scripts = ["deluge", "deluged", "deluge-web", "deluge-gtk"] -console_scripts = ["deluge-debug", "deluged-debug", "deluge-web-debug", "deluge-console"] +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")) -# Copy the scripts to get rid of the '-script' suffix before adding to freezer -for script in gui_scripts: - shutil.copy(python_path + "Scripts/%s-script.pyw" % script, python_path + "Scripts/%s.pyw" % script) - f.addScript(python_path + "Scripts/%s.pyw" % script, gui_only=True) -for script in console_scripts: - shutil.copy(python_path + "Scripts/%s-script.py" % script, python_path + "Scripts/%s.py" % script) - f.addScript(python_path + "Scripts/%s.py" % script, gui_only=False) -f() # starts the freezing process +# TODO: Can/should we grab the script list from setup.py entry_points somehow. -# Clean up the duplicated scripts -for script in gui_scripts: - os.remove(python_path + "Scripts/%s.pyw" % script) -for script in console_scripts: - os.remove(python_path + "Scripts/%s.py" % script) +# Hide cmd console popup for these console entries force gui_script True. +force_gui = ["deluge-web", "deluged", "deluge-console"] +script_list = [] +for script in glob.glob(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) -# add icons to the exe files -icon_path = os.path.join(os.path.dirname(__file__), "deluge.ico") -for script in console_scripts + gui_scripts: - icon.CopyIcons(dst + script + ".exe", icon_path) + 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 + else: + gui_script = False + try: + fzr.addScript(new_script, gui_only=gui_script) + + script_list.append(new_script) + except: + os.remove(script) + +# Start the freezing process. +fzr() + +# Clean up the duplicated scripts. +for script in script_list: + os.remove(script) # Add version information to exe files. -for script in console_scripts + gui_scripts: - script_exe = script + ".exe" - version = Version(build_version, - file_description="Deluge Bittorrent Client", - company_name="Deluge Team", - legal_copyright="GPLv3", - original_filename=script_exe, - product_name="Deluge", - product_version=build_version) +for script in script_list: + script_exe = os.path.splitext(os.path.basename(script))[0] + ".exe" + if not re.search('[a-zA-Z_-]', build_version): + versionInfo = VersionInfo(build_version, + description="Deluge Bittorrent Client", + company="Deluge Team", + product="Deluge", + copyright="GPLv3") + stamp(os.path.join(build_dir, script_exe), versionInfo) - pyhandle = win32api.BeginUpdateResource(os.path.join(dst, script_exe), 0) - win32api.UpdateResource(pyhandle, 16, 1, version.resource_bytes()) - win32api.EndUpdateResource(pyhandle, 0) - -# exclude files which are already included in GTK or Windows +# Exclude files which are already included in GTK or Windows. excludeDlls = ("MSIMG32.dll", "MSVCR90.dll", "MSVCP90.dll", "POWRPROF.dll", "DNSAPI.dll", "USP10.dll") -for file in excludeDlls: - for filename in glob.glob(dst + file): +for dll in excludeDlls: + for filename in glob.glob(os.path.join(build_dir, dll)): print "removing file:", filename os.remove(filename) -# copy gtk locale files +# Copy gtk locale files. gtk_locale = os.path.join(gtk_root, 'share/locale') locale_include_list = ['gtk20.mo', 'locale.alias'] @@ -96,9 +120,9 @@ def ignored_files(adir, filenames): if not os.path.isdir(os.path.join(adir, filename)) and filename not in locale_include_list ] -shutil.copytree(gtk_locale, os.path.join(dst, 'share/locale'), ignore=ignored_files) +shutil.copytree(gtk_locale, os.path.join(build_dir, 'share/locale'), ignore=ignored_files) -# copy gtk theme 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"], @@ -110,15 +134,16 @@ theme_include_list = [ 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(dst, path)) + shutil.copytree(full_path, os.path.join(build_dir, path)) else: - dst_dir = os.path.join(dst, os.path.dirname(path)) + dst_dir = os.path.join(build_dir, os.path.dirname(path)) try: os.makedirs(dst_dir) except: pass shutil.copy(full_path, dst_dir) +# Copy version info to file for nsis script. file = open('VERSION.tmp', 'w') file.write("build_version = \"%s\"" % build_version) file.close() diff --git a/packaging/win32/deluge.ico b/packaging/win32/deluge.ico deleted file mode 100644 index ef5c3dd342897225cc1581498a9f7adddab9cf4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25214 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 Nh+u=y-o 1: - # At the moment, we support multiple icons only from .ico files - srcs = [] - for s in srcpath: - e = os.path.splitext(s[0])[1] - if string.lower(e) != '.ico': - raise ValueError("multiple icons supported only from .ico files") - if s[1] is not None: - raise ValueError("index not allowed for .ico files") - srcs.append(s[0]) - return CopyIcons_FromIco(dstpath, srcs) - - srcpath, index = srcpath[0] - srcext = os.path.splitext(srcpath)[1] - if string.lower(srcext) == '.ico': - return CopyIcons_FromIco(dstpath, [srcpath]) - if index is not None: - print "I: Updating icons from", srcpath, ", %d to" % index, dstpath - else: - print "I: Updating icons from", srcpath, "to", dstpath - import win32api - hdst = win32api.BeginUpdateResource(dstpath, 0) - hsrc = win32api.LoadLibraryEx(srcpath, 0, LOAD_LIBRARY_AS_DATAFILE) - if index is None: - grpname = win32api.EnumResourceNames(hsrc, RT_GROUP_ICON)[0] - elif index >= 0: - grpname = win32api.EnumResourceNames(hsrc, RT_GROUP_ICON)[index] - else: - grpname = -index - data = win32api.LoadResource(hsrc, RT_GROUP_ICON, grpname) - win32api.UpdateResource(hdst, RT_GROUP_ICON, grpname, data) - for iconname in win32api.EnumResourceNames(hsrc, RT_ICON): - data = win32api.LoadResource(hsrc, RT_ICON, iconname) - win32api.UpdateResource(hdst, RT_ICON, iconname, data) - win32api.FreeLibrary(hsrc) - win32api.EndUpdateResource(hdst, 0) - -if __name__ == "__main__": - import sys - - dstpath = sys.argv[1] - srcpath = sys.argv[2:] - CopyIcons(dstpath, srcpath) diff --git a/setup.py b/setup.py index 83434b8c0..8f3c72967 100755 --- a/setup.py +++ b/setup.py @@ -283,13 +283,13 @@ if not windows_check() and os.path.exists(desktop_data): entry_points = { "console_scripts": [ - "deluge-console = deluge.ui.console:start" + "deluge-console = deluge.ui.console:start", + "deluge-web = deluge.ui.web:start", + "deluged = deluge.main:start_daemon" ], "gui_scripts": [ "deluge = deluge.main:start_ui", - "deluge-gtk = deluge.ui.gtkui:start", - "deluge-web = deluge.ui.web:start", - "deluged = deluge.main:start_daemon" + "deluge-gtk = deluge.ui.gtkui:start" ] }