Skip to content

Commit

Permalink
For Linux (x11): added auto adding of png icons as external stand-alo…
Browse files Browse the repository at this point in the history
…ne resources, and referrences to them within .desktop files created by an installer.
  • Loading branch information
BuvinJ committed Jan 16, 2019
1 parent 7cfcdd1 commit b25ff99
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 30 deletions.
24 changes: 14 additions & 10 deletions distbuilder/master.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ def opyConfig( self ):
bundleLibs=self.opyBundleLibs,
patches=self.opyPatches )

def qtIfwConfig( self ):
def qtIfwConfig( self, pyInstConfig=None ):
return QtIfwConfig( pkgSrcDirPath=self.__pkgSrcDirPath(),
pkgName=self.__ifwPkgName(),
installerDefDirPath=self.ifwDefDirPath,
configXml=self.qtIfwConfigXml(),
pkgXml=self.qtIfwPackageXml(),
pkgScript=self.qtIfwPackageScript(),
pkgScript=self.qtIfwPackageScript( pyInstConfig ),
setupExeName=self.setupName )

def qtIfwConfigXml( self ) :
Expand All @@ -93,13 +93,17 @@ def qtIfwPackageXml( self ) :
return QtIfwPackageXml( self.__ifwPkgName(), self.productName, self.description,
self.__versionStr(), self.ifwScriptName )

def qtIfwPackageScript( self ) :
return QtIfwPackageScript( self.__ifwPkgName(),
fileName=self.ifwScriptName,
exeName=self.binaryName,
exeVersion=self.__versionStr(),
script=self.ifwScriptPath,
srcPath=self.ifwScriptPath )
def qtIfwPackageScript( self, pyInstConfig=None ) :
script = QtIfwPackageScript( self.__ifwPkgName(),
fileName=self.ifwScriptName,
exeName=self.binaryName,
script=self.ifwScriptPath,
srcPath=self.ifwScriptPath )
if IS_LINUX:
script.exeVersion = self.__versionStr()
if pyInstConfig is not None:
script.pngIconResPath = pyInstConfig._pngIconResPath
return script

def __versionStr( self ):
return "%d.%d.%d.%d" % self.version
Expand Down Expand Up @@ -174,7 +178,7 @@ def run( self ):
run( binPath, self.exeTestArgs,
isElevated=self.isElevatedTest, isDebug=True )

ifwConfig = self.configFactory.qtIfwConfig()
ifwConfig = self.configFactory.qtIfwConfig( pyInstConfig )
self.onQtIfwConfig( ifwConfig )
setupPath = buildInstaller( ifwConfig, isPkgSrcRemoved=True )
if self.isDesktopTarget :
Expand Down
36 changes: 29 additions & 7 deletions distbuilder/py_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def __init__( self ) :

self.isGui = False
self.iconFilePath = None
self._pngIconResPath = None

self.versionInfo = None
self.versionFilePath = None # TODO: offer programmatic version info
Expand All @@ -61,7 +62,7 @@ def __init__( self ) :

self.isAutoElevated = False
self.otherPyInstArgs = "" # open ended

def __str__( self ):
nameSpec = ( "--name %s" % (self.name,)
if self.name else "" )
Expand Down Expand Up @@ -90,15 +91,22 @@ def toPyInstallerSrcDestSpec( pyInstArg, paths ):
binarySpec += toPyInstallerSrcDestSpec( "--add-binary", paths )

try:
# if the iconFilePath is a tuple or list,
# it represents an exe path and an icon index embedded within that
if( isinstance( self.iconFilePath, tuple ) or
isinstance( self.iconFilePath, list ) ):
if IS_LINUX :
# icon emmbedding is not supported by PyInstaller for Linux,
# this is handled by the library wrapper independently
self._pngIconResPath = splitExt( self.iconFilePath )[0] +".png"
self.iconFilePath = None
elif( isinstance( self.iconFilePath, tuple ) or
isinstance( self.iconFilePath, list ) ):
# if the iconFilePath is a tuple or list,
# it represents a windows exe path and an
# icon index embedded within that
if splitExt( self.iconFilePath[0] )[1]==".exe" :
self.iconFilePath = "%s,%d" % (
self.iconFilePath[0], self.iconFilePath[1] )
else : raise
else : raise
else :
# auto convert between Windows and Mac icon extensions
self.iconFilePath = ( splitExt( self.iconFilePath )[0] +
(".icns" if IS_MACOS else ".ico") )
except: self.iconFilePath = None
Expand Down Expand Up @@ -237,7 +245,21 @@ def buildExecutable( name=None, entryPointPy=None,

# Discard all temp files (but not distDir!)
__clean( pyInstConfig )


# automatically add a png icon for Linux to the
# external resources, if one exists and is not already included
if IS_LINUX :
try:
pngPath = pyInstConfig._pngIconResPath
if exists( pngPath ):
pngName = basename( pngPath )
isRes = False
for res in distResources :
isRes = res.endswith( pngName )
if isRes: break
if not isRes: distResources.append( pngPath )
except: pass

# Confirm success
exePath = joinPath( distDirPath, util._normExeName( name ) )
if not exists(exePath) :
Expand Down
28 changes: 18 additions & 10 deletions distbuilder/qt_installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,13 @@ def __init__( self, name, exeName, version, publisher,
QtIfwConfigXml.__TAGS )

self.exeName = util._normExeName( exeName )
self.iconFilePath = iconFilePath
try: iconBaseName = splitExt( basename(iconFilePath) )[0]
except: iconBaseName = None
if IS_LINUX :
# qt installer does not support icon embedding in Linux
iconBaseName = self.iconFilePath = None
else :
self.iconFilePath = iconFilePath
try: iconBaseName = splitExt( basename(iconFilePath) )[0]
except: iconBaseName = None
self.companyTradeName = ( companyTradeName if companyTradeName
else publisher.replace(".","") )
self.runProgramArgList = None
Expand Down Expand Up @@ -331,7 +335,7 @@ def __winAddShortcut( location, exeName,
def __linuxAddDesktopEntry( location, exeName, version,
label="@ProductName@",
directory="@TargetDir@",
pngPath="",
pngPath=None,
isGui=True ):
exePath = "%s/%s" % (directory, util._normExeName( exeName ))
locDir = QtIfwPackageScript.__X11_SHORTCUT_LOCATIONS[location]
Expand All @@ -341,22 +345,24 @@ def __linuxAddDesktopEntry( location, exeName, version,
s = s.replace( "[SHORTCUT_PATH]", shortcutPath )
s = s.replace( "[LABEL]", label )
s = s.replace( "[VERSION]", version )
s = s.replace( "[PNG_PATH]", pngPath )
s = s.replace( "[PNG_PATH]", "" if pngPath is None else
joinPath( "@TargetDir@", pngPath ) )
s = s.replace( "[IS_TERMINAL]", "false" if isGui else "true" )
s = s.replace( "[WORKING_DIR]", directory )
return s

def __init__( self, pkgName, fileName=DEFAULT_QT_IFW_SCRIPT_NAME,
exeName=None, exeVersion="0.0.0.0",
script=None, srcPath=None ) :
exeName=None, script=None, srcPath=None ) :
self.pkgName = pkgName
self.fileName = fileName
if srcPath :
with open( srcPath, 'rb' ) as f: self.script = f.read()
else : self.script = script

self.exeName = exeName
self.exeVersion = exeVersion

self.exeVersion = "0.0.0.0"
self.pngIconResPath = None

self.isAppShortcut = True
self.isDesktopShortcut = False
Expand Down Expand Up @@ -407,10 +413,12 @@ def __genComponentCreateOperationsBody( self ):
x11Ops = ""
if self.exeName and self.isAppShortcut :
x11Ops += QtIfwPackageScript.__linuxAddDesktopEntry(
APPS_X11_SHORTCUT, self.exeName, self.exeVersion )
APPS_X11_SHORTCUT, self.exeName, self.exeVersion,
pngPath=self.pngIconResPath )
if self.exeName and self.isDesktopShortcut:
x11Ops += QtIfwPackageScript.__linuxAddDesktopEntry(
DESKTOP_X11_SHORTCUT, self.exeName, self.exeVersion )
DESKTOP_X11_SHORTCUT, self.exeName, self.exeVersion,
pngPath=self.pngIconResPath )
if x11Ops!="" :
self.componentCreateOperationsBody += (
' if( systemInfo.kernelType === "linux" ){\n' +
Expand Down
6 changes: 5 additions & 1 deletion docs/QuickStart.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ Alternatively, you may download/copy the source files directly from GitHub into

[build.py](https://raw.githubusercontent.com/BuvinJT/distbuilder/master/examples/hello_world_tk/build.py)

[demo.ico](https://raw.githubusercontent.com/BuvinJT/distbuilder/master/examples/hello_world_tk/demo.ico)
Windows: [demo.ico](https://raw.githubusercontent.com/BuvinJT/distbuilder/master/examples/hello_world_tk/demo.ico)

Mac: [demo.icns](https://raw.githubusercontent.com/BuvinJT/distbuilder/master/examples/hello_world_tk/demo.icns)

Linux: [demo.png](https://raw.githubusercontent.com/BuvinJT/distbuilder/master/examples/hello_world_tk/demo.png)

Start by confirming you can run the program
script in the "natural" manner:
Expand Down
6 changes: 4 additions & 2 deletions docs/Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@ Attributes & default values:
isGui = False
iconFilePath = None
_pngIconResPath = None
versionInfo = None
versionFilePath = None
Expand Down Expand Up @@ -791,8 +792,7 @@ automating the generation common script directives.
Constructor:

QtIfwPackageScript( pkgName, fileName="installscript.qs",
exeName=None, exeVersion="0.0.0.0",
script=None, srcPath=None )
exeName=None, script=None, srcPath=None )
Attributes & default values:

Expand All @@ -804,6 +804,8 @@ Attributes & default values:
exeName = None
exeVersion = "0.0.0.0"

pngIconResPath = None

isAppShortcut = True
isDesktopShortcut = False

Expand Down
Binary file added examples/hello_world_tk/demo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b25ff99

Please sign in to comment.