forked from openlp/openlp
added initial version of build scripts used for os x to create an installable dmg image
to configure adjust the openlp.cfg with the correct environment values and then run make attention: it depends on pyinstaller (currently in the most recent trunk version) modified openlp.pyw to include the plugin directory on os x
This commit is contained in:
parent
ccfb472aa6
commit
801a2b17c9
@ -273,6 +273,8 @@ def main():
|
|||||||
qInitResources()
|
qInitResources()
|
||||||
# Now create and actually run the application.
|
# Now create and actually run the application.
|
||||||
app = OpenLP(qt_args)
|
app = OpenLP(qt_args)
|
||||||
|
if sys.platform == 'darwin':
|
||||||
|
QtGui.QApplication.addLibraryPath(QtGui.QApplication.applicationDirPath() + "/qt4_plugins")
|
||||||
#i18n Set Language
|
#i18n Set Language
|
||||||
language = LanguageManager.get_language()
|
language = LanguageManager.get_language()
|
||||||
appTranslator = LanguageManager.get_translator(language)
|
appTranslator = LanguageManager.get_translator(language)
|
||||||
|
32
resources/osx/Info.plist.master
Executable file
32
resources/osx/Info.plist.master
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>org.openlp</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>%(openlp_version)s</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>%(openlp_version)s</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>%(openlp_appname)s</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>openlp-logo-with-text.icns</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>MacOS/openlp</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>%(openlp_appname)s</string>
|
||||||
|
<key>CFBundleGetInfoString</string>
|
||||||
|
<string>%(openlp_appname)s %(openlp_version)s</string>
|
||||||
|
<key>LSHasLocalizedDisplayName</string>
|
||||||
|
<false/>
|
||||||
|
<key>NSAppleScriptEnabled</key>
|
||||||
|
<false/>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>LSBackgroundOnly</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
28
resources/osx/Makefile
Normal file
28
resources/osx/Makefile
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
all:
|
||||||
|
python build.py -c openlp.cfg
|
||||||
|
|
||||||
|
view:
|
||||||
|
python build.py -c openlp.cfg --package-view --compress-view
|
||||||
|
|
||||||
|
package:
|
||||||
|
|
||||||
|
python build.py -c openlp.cfg --package --package-view
|
||||||
|
|
||||||
|
bundle:
|
||||||
|
|
||||||
|
python build.py -c openlp.cfg --compress --compress-view
|
||||||
|
|
||||||
|
clean:
|
||||||
|
# remove old configuration files
|
||||||
|
rm -f openlp.spec
|
||||||
|
rm -f Info.plist
|
||||||
|
rm -f .version
|
||||||
|
|
||||||
|
# remove old build artifacts
|
||||||
|
rm -rf build
|
||||||
|
rm -rf dist
|
||||||
|
rm -rf Macopenlp.app
|
||||||
|
rm -rf OpenLP.app
|
||||||
|
rm -f warnopenlp.txt
|
||||||
|
rm -f *dmg
|
||||||
|
|
74
resources/osx/applescript-adjustview-10-5.master
Executable file
74
resources/osx/applescript-adjustview-10-5.master
Executable file
@ -0,0 +1,74 @@
|
|||||||
|
on saveImageWithItselfAsIcon(icon_image_file)
|
||||||
|
-- save icon_image_file with itself as icon
|
||||||
|
set icon_image_file_string to icon_image_file as string
|
||||||
|
tell application "Image Events"
|
||||||
|
launch
|
||||||
|
set icon_image to open file icon_image_file_string
|
||||||
|
save icon_image with icon
|
||||||
|
close icon_image
|
||||||
|
end tell
|
||||||
|
end saveImageWithItselfAsIcon
|
||||||
|
|
||||||
|
on copyIconOfTo(aFileOrFolderWithIcon, aFileOrFolder)
|
||||||
|
tell application "Finder" to set f to aFileOrFolderWithIcon as alias
|
||||||
|
-- grab the file's icon
|
||||||
|
my CopyOrPaste(f, "c")
|
||||||
|
-- now the icon is in the clipboard
|
||||||
|
tell application "Finder" to set c to aFileOrFolder as alias
|
||||||
|
my CopyOrPaste(result, "v")
|
||||||
|
end copyIconOfTo
|
||||||
|
|
||||||
|
on CopyOrPaste(i, cv)
|
||||||
|
tell application "Finder"
|
||||||
|
activate
|
||||||
|
open information window of i
|
||||||
|
end tell
|
||||||
|
tell application "System Events" to tell process "Finder" to tell window 1
|
||||||
|
keystroke tab -- select icon button
|
||||||
|
keystroke (cv & "w") using command down (* (copy or paste) + close window *)
|
||||||
|
end tell -- window 1 then process Finder then System Events
|
||||||
|
end CopyOrPaste
|
||||||
|
|
||||||
|
on run
|
||||||
|
set icon_image_file to POSIX file "%s" as alias
|
||||||
|
set dmg_file to POSIX file "/Volumes/%s" as alias
|
||||||
|
|
||||||
|
my saveImageWithItselfAsIcon(icon_image_file)
|
||||||
|
-- wait for virus scanner
|
||||||
|
delay 2
|
||||||
|
my copyIconOfTo(icon_image_file, dmg_file)
|
||||||
|
|
||||||
|
tell application "Finder"
|
||||||
|
tell disk "%s"
|
||||||
|
open
|
||||||
|
set current view of container window to icon view
|
||||||
|
set toolbar visible of container window to false
|
||||||
|
set statusbar visible of container window to false
|
||||||
|
set the bounds of container window to {400, 100, 1100, 500}
|
||||||
|
set theViewOptions to the icon view options of container window
|
||||||
|
set arrangement of theViewOptions to not arranged
|
||||||
|
set icon size of theViewOptions to 128
|
||||||
|
set background picture of theViewOptions to file ".installer-background.png"
|
||||||
|
if not exists file "Applications" then
|
||||||
|
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
|
||||||
|
end if
|
||||||
|
delay 5
|
||||||
|
set position of item "%s" of container window to {160, 200}
|
||||||
|
set position of item ".Trashes" of container window to {100, 500}
|
||||||
|
set position of item ".installer-background.png" of container window to {200, 500}
|
||||||
|
set position of item ".DS_Store" of container window to {400, 500}
|
||||||
|
set position of item "Applications" of container window to {550, 200}
|
||||||
|
set position of item ".VolumeIcon.icns" of container window to {500, 500}
|
||||||
|
set position of item ".fseventsd" of container window to {300, 500}
|
||||||
|
if exists POSIX file ".SymAVx86QSFile" then
|
||||||
|
set position of item ".SymAVx86QSFile" of container window to {600, 500}
|
||||||
|
end if
|
||||||
|
open
|
||||||
|
close
|
||||||
|
update without registering applications
|
||||||
|
-- wait until the virus scan completes
|
||||||
|
delay 5
|
||||||
|
-- eject
|
||||||
|
end tell
|
||||||
|
end tell
|
||||||
|
end run
|
73
resources/osx/applescript-adjustview-10-6.master
Executable file
73
resources/osx/applescript-adjustview-10-6.master
Executable file
@ -0,0 +1,73 @@
|
|||||||
|
on saveImageWithItselfAsIcon(icon_image_file)
|
||||||
|
-- save icon_image_file with itself as icon
|
||||||
|
set icon_image_file_string to icon_image_file as string
|
||||||
|
tell application "Image Events"
|
||||||
|
launch
|
||||||
|
set icon_image to open file icon_image_file_string
|
||||||
|
save icon_image with icon
|
||||||
|
close icon_image
|
||||||
|
end tell
|
||||||
|
end saveImageWithItselfAsIcon
|
||||||
|
|
||||||
|
on copyIconOfTo(aFileOrFolderWithIcon, aFileOrFolder)
|
||||||
|
tell application "Finder" to set f to aFileOrFolderWithIcon as alias
|
||||||
|
-- grab the file's icon
|
||||||
|
my CopyOrPaste(f, "c")
|
||||||
|
-- now the icon is in the clipboard
|
||||||
|
tell application "Finder" to set c to aFileOrFolder as alias
|
||||||
|
my CopyOrPaste(result, "v")
|
||||||
|
end copyIconOfTo
|
||||||
|
|
||||||
|
on CopyOrPaste(i, cv)
|
||||||
|
tell application "Finder"
|
||||||
|
activate
|
||||||
|
set infoWindow to open information window of i
|
||||||
|
set infoWindowName to name of infoWindow
|
||||||
|
end tell
|
||||||
|
tell application "System Events" to tell process "Finder" to tell window infoWindowName
|
||||||
|
keystroke tab -- select icon button
|
||||||
|
keystroke (cv & "w") using command down (* (copy or paste) + close window *)
|
||||||
|
end tell -- window 1 then process Finder then System Events
|
||||||
|
end CopyOrPaste
|
||||||
|
|
||||||
|
on run
|
||||||
|
set icon_image_file to POSIX file "%s" as alias
|
||||||
|
set dmg_file to POSIX file "/Volumes/%s" as alias
|
||||||
|
|
||||||
|
my saveImageWithItselfAsIcon(icon_image_file)
|
||||||
|
-- wait for virus scanner
|
||||||
|
delay 2
|
||||||
|
my copyIconOfTo(icon_image_file, dmg_file)
|
||||||
|
|
||||||
|
tell application "Finder"
|
||||||
|
tell disk "%s"
|
||||||
|
open
|
||||||
|
set current view of container window to icon view
|
||||||
|
set toolbar visible of container window to false
|
||||||
|
set statusbar visible of container window to false
|
||||||
|
set the bounds of container window to {400, 100, 1100, 500}
|
||||||
|
set theViewOptions to the icon view options of container window
|
||||||
|
set arrangement of theViewOptions to not arranged
|
||||||
|
set icon size of theViewOptions to 128
|
||||||
|
set background picture of theViewOptions to file ".installer-background.png"
|
||||||
|
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
|
||||||
|
delay 5
|
||||||
|
set position of item "%s" of container window to {160, 200}
|
||||||
|
set position of item ".Trashes" of container window to {100, 500}
|
||||||
|
set position of item ".installer-background.png" of container window to {200, 500}
|
||||||
|
set position of item ".DS_Store" of container window to {400, 500}
|
||||||
|
set position of item "Applications" of container window to {550, 200}
|
||||||
|
set position of item ".VolumeIcon.icns" of container window to {500, 500}
|
||||||
|
set position of item ".fseventsd" of container window to {300, 500}
|
||||||
|
if exists POSIX file ".SymAVx86QSFile" then
|
||||||
|
set position of item ".SymAVx86QSFile" of container window to {600, 500}
|
||||||
|
end if
|
||||||
|
open
|
||||||
|
close
|
||||||
|
update without registering applications
|
||||||
|
-- wait until the virus scan completes
|
||||||
|
delay 5
|
||||||
|
-- eject
|
||||||
|
end tell
|
||||||
|
end tell
|
||||||
|
end run
|
40
resources/osx/applescript-seticon-10-5.master
Executable file
40
resources/osx/applescript-seticon-10-5.master
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
on saveImageWithItselfAsIcon(icon_image_file)
|
||||||
|
-- save icon_image_file with itself as icon
|
||||||
|
set icon_image_file_string to icon_image_file as string
|
||||||
|
tell application "Image Events"
|
||||||
|
launch
|
||||||
|
set icon_image to open file icon_image_file_string
|
||||||
|
save icon_image with icon
|
||||||
|
close icon_image
|
||||||
|
end tell
|
||||||
|
end saveImageWithItselfAsIcon
|
||||||
|
|
||||||
|
on copyIconOfTo(aFileOrFolderWithIcon, aFileOrFolder)
|
||||||
|
tell application "Finder" to set f to aFileOrFolderWithIcon as alias
|
||||||
|
-- grab the file's icon
|
||||||
|
my CopyOrPaste(f, "c")
|
||||||
|
-- now the icon is in the clipboard
|
||||||
|
tell application "Finder" to set c to aFileOrFolder as alias
|
||||||
|
my CopyOrPaste(result, "v")
|
||||||
|
end copyIconOfTo
|
||||||
|
|
||||||
|
on CopyOrPaste(i, cv)
|
||||||
|
tell application "Finder"
|
||||||
|
activate
|
||||||
|
open information window of i
|
||||||
|
end tell
|
||||||
|
tell application "System Events" to tell process "Finder" to tell window 1
|
||||||
|
keystroke tab -- select icon button
|
||||||
|
keystroke (cv & "w") using command down (* (copy or paste) + close window *)
|
||||||
|
end tell -- window 1 then process Finder then System Events
|
||||||
|
end CopyOrPaste
|
||||||
|
|
||||||
|
on run
|
||||||
|
set icon_image_file to POSIX file "%s" as alias
|
||||||
|
set dmg_file to POSIX file "%s" as alias
|
||||||
|
|
||||||
|
my saveImageWithItselfAsIcon(icon_image_file)
|
||||||
|
-- wait for virus scanner
|
||||||
|
delay 2
|
||||||
|
my copyIconOfTo(icon_image_file, dmg_file)
|
||||||
|
end run
|
41
resources/osx/applescript-seticon-10-6.master
Executable file
41
resources/osx/applescript-seticon-10-6.master
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
on saveImageWithItselfAsIcon(icon_image_file)
|
||||||
|
-- save icon_image_file with itself as icon
|
||||||
|
set icon_image_file_string to icon_image_file as string
|
||||||
|
tell application "Image Events"
|
||||||
|
launch
|
||||||
|
set icon_image to open file icon_image_file_string
|
||||||
|
save icon_image with icon
|
||||||
|
close icon_image
|
||||||
|
end tell
|
||||||
|
end saveImageWithItselfAsIcon
|
||||||
|
|
||||||
|
on copyIconOfTo(aFileOrFolderWithIcon, aFileOrFolder)
|
||||||
|
tell application "Finder" to set f to aFileOrFolderWithIcon as alias
|
||||||
|
-- grab the file's icon
|
||||||
|
my CopyOrPaste(f, "c")
|
||||||
|
-- now the icon is in the clipboard
|
||||||
|
tell application "Finder" to set c to aFileOrFolder as alias
|
||||||
|
my CopyOrPaste(result, "v")
|
||||||
|
end copyIconOfTo
|
||||||
|
|
||||||
|
on CopyOrPaste(i, cv)
|
||||||
|
tell application "Finder"
|
||||||
|
activate
|
||||||
|
set infoWindow to open information window of i
|
||||||
|
set infoWindowName to name of infoWindow
|
||||||
|
end tell
|
||||||
|
tell application "System Events" to tell process "Finder" to tell window infoWindowName
|
||||||
|
keystroke tab -- select icon button
|
||||||
|
keystroke (cv & "w") using command down (* (copy or paste) + close window *)
|
||||||
|
end tell -- window 1 then process Finder then System Events
|
||||||
|
end CopyOrPaste
|
||||||
|
|
||||||
|
on run
|
||||||
|
set icon_image_file to POSIX file "%s" as alias
|
||||||
|
set dmg_file to POSIX file "%s" as alias
|
||||||
|
|
||||||
|
my saveImageWithItselfAsIcon(icon_image_file)
|
||||||
|
-- wait for virus scanner
|
||||||
|
delay 2
|
||||||
|
my copyIconOfTo(icon_image_file, dmg_file)
|
||||||
|
end run
|
261
resources/osx/build.py
Normal file
261
resources/osx/build.py
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import ConfigParser
|
||||||
|
import logging
|
||||||
|
import optparse
|
||||||
|
import sys
|
||||||
|
import platform
|
||||||
|
import re
|
||||||
|
import subprocess as subp
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
# set default actions
|
||||||
|
doBuild = True
|
||||||
|
doCompressView = True
|
||||||
|
doPackageView = True
|
||||||
|
doCreateDmg = True
|
||||||
|
doCompressDmg = True
|
||||||
|
doDeployQt = True
|
||||||
|
|
||||||
|
# set the script name
|
||||||
|
script_name = "build"
|
||||||
|
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
parser.add_option('-c', '--config', dest = 'config', help = 'config file', metavar = 'CONFIG')
|
||||||
|
parser.add_option('-v', '--package-view', dest = 'package_view', help = 'triggers view adjustment scripts for package', metavar = 'PACKAGEVIEWONLY', action='store_true', default=False)
|
||||||
|
parser.add_option('-y', '--compress-view', dest = 'compress_view', help = 'triggers view adjustment scripts for dmg', metavar = 'COMPRESSVIEWONLY', action='store_true', default=False)
|
||||||
|
parser.add_option('-p', '--package', dest = 'package', help = 'package application folder to dmg', metavar = 'PACKAGE', action='store_true', default=False)
|
||||||
|
parser.add_option('-z', '--compress', dest = 'compress', help = 'compresses the existing dmg', metavar = 'COMPRESS', action='store_true', default=False)
|
||||||
|
parser.add_option('-b', '--basedir', dest = 'basedir', help = 'volume basedir like /Volumes/OpenLP', metavar = 'BASEDIR', default='/Volumes/OpenLP')
|
||||||
|
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
# if an option is set, false all
|
||||||
|
if (options.package_view is True or options.compress_view is True or options.package is True or options.compress is True):
|
||||||
|
doBuild = False
|
||||||
|
doDeployQt = False
|
||||||
|
doPackageView = options.package_view
|
||||||
|
doCompressView = options.compress_view
|
||||||
|
doCreateDmg = options.package
|
||||||
|
doCompressDmg = options.compress
|
||||||
|
|
||||||
|
if not options.config:
|
||||||
|
parser.error('option --config|-c is required')
|
||||||
|
|
||||||
|
logHandler = logging.StreamHandler()
|
||||||
|
logHandler.setFormatter(logging.Formatter('%(asctime)s %(levelname)-8s %(message)s',
|
||||||
|
'%a, %d %b %Y %H:%M:%S'))
|
||||||
|
logging.getLogger().addHandler(logHandler)
|
||||||
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
config = ConfigParser.RawConfigParser()
|
||||||
|
config.readfp(open(options.config, 'r'))
|
||||||
|
|
||||||
|
if not config.has_section('openlp'):
|
||||||
|
logging.error('[%s] config file "%s" lacks an [openlp] section',
|
||||||
|
script_name, options.config)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if not sys.platform == "darwin":
|
||||||
|
logging.error('[%s] this script only works on Macintosh OS X systems, not on %s',
|
||||||
|
script_name, sys.platform)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
version = platform.mac_ver()[0]
|
||||||
|
# we only need the differenciation between leopard and snow leopard
|
||||||
|
if version.startswith("10.6"):
|
||||||
|
SNOWLEOPARD = True
|
||||||
|
logging.info('[%s] using snow leopard scripts (version = %s)', script_name, version)
|
||||||
|
adjustview_scriptname = "applescript-adjustview-10-6.master"
|
||||||
|
seticon_scriptname = "applescript-seticon-10-6.master"
|
||||||
|
else:
|
||||||
|
SNOWLEOPARD = False
|
||||||
|
logging.info('[%s] using leopard scripts (version = %s)', script_name, version)
|
||||||
|
adjustview_scriptname = "applescript-adjustview-10-5.master"
|
||||||
|
seticon_scriptname = "applescript-seticon-10-5.master"
|
||||||
|
|
||||||
|
if not os.path.isfile(adjustview_scriptname) or not os.path.isfile(seticon_scriptname):
|
||||||
|
logging.error('[%s] could not find apple scripts for given mac version %s', script_name, version)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
settings = dict()
|
||||||
|
for k in config.options('openlp'):
|
||||||
|
settings[k] = config.get('openlp', k)
|
||||||
|
|
||||||
|
# prepare the configuration files
|
||||||
|
os.system('python expander.py --config %(config_file)s --template openlp.spec.master --expandto %(target_directory)s/openlp.spec' \
|
||||||
|
% { 'config_file' : options.config, 'target_directory' : os.getcwd() })
|
||||||
|
os.system('python expander.py --config %(config_file)s --template Info.plist.master --expandto %(target_directory)s/Info.plist' \
|
||||||
|
% { 'config_file' : options.config, 'target_directory' : os.getcwd() })
|
||||||
|
os.system('python expander.py --config %(config_file)s --template version.master --expandto %(target_directory)s/.version' \
|
||||||
|
% { 'config_file' : options.config, 'target_directory' : os.getcwd() })
|
||||||
|
|
||||||
|
# prepare variables
|
||||||
|
app_name = settings['openlp_appname'].lower()
|
||||||
|
app_dir = os.getcwd() + '/' + settings['openlp_appname'] + '.app'
|
||||||
|
|
||||||
|
# if the view option is set, skip the building steps
|
||||||
|
if (doBuild is True):
|
||||||
|
logging.info('[%s] now building the app with pyinstaller at "%s"...', script_name, settings['pyinstaller_basedir'])
|
||||||
|
result = os.system('python %s/pyinstaller.py openlp.spec' \
|
||||||
|
% settings['pyinstaller_basedir'])
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] The pyinstaller build reported an error, cannot continue!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
logging.info('[%s] copying the qt_menu files...', script_name)
|
||||||
|
# see http://www.pyinstaller.org/ticket/157
|
||||||
|
result = os.system('cp -R %(qt_menu_directory)s %(application_directory)s/Contents/Resources' \
|
||||||
|
% { 'qt_menu_directory' : settings['qt_menu_basedir'],
|
||||||
|
'application_directory' : app_dir })
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not copy the qt_menu files, cannot continue!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
dist_folder = os.getcwd() + '/dist/' + app_name
|
||||||
|
# logging.info('[%s] copying the additional app files (from %s)...', script_name, dist_folder)
|
||||||
|
# result = os.system('cp -R %(dist_directory)s/* %(application_directory)s/Contents/MacOS' \
|
||||||
|
# % { 'dist_directory' : dist_folder,
|
||||||
|
# 'application_directory' : app_dir })
|
||||||
|
# if (result != 0):
|
||||||
|
# logging.error('[%s] could not copy additional files, cannot continue!', script_name)
|
||||||
|
# sys.exit(1)
|
||||||
|
|
||||||
|
logging.info('[%s] copying the new plugins...', script_name)
|
||||||
|
result = os.system('cp -R %(openlp_directory)s/openlp/plugins %(application_directory)s/Contents/MacOS' \
|
||||||
|
% { 'openlp_directory' : settings['openlp_basedir'],
|
||||||
|
'application_directory' : app_dir })
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not copy plugins, dmg creation failed!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
logging.info('[%s] copying the icons to the resource directory...', script_name)
|
||||||
|
result = os.system('cp %(icon_file)s %(application_directory)s/Contents/Resources' \
|
||||||
|
% { 'icon_file' : settings['openlp_icon_file'],
|
||||||
|
'application_directory' : app_dir })
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not copy the icon, dmg creation failed!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
logging.info('[%s] copying the version file...', script_name)
|
||||||
|
result = os.system('CpMac %s/.version %s/Contents/MacOS' % (os.getcwd(), app_dir))
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not copy the version file, dmg creation failed!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
logging.info('[%s] copying the new Info.plist...', script_name)
|
||||||
|
result = os.system('cp %(target_directory)s/Info.plist %(application_directory)s/Contents' \
|
||||||
|
% { 'target_directory' : os.getcwd(),
|
||||||
|
'application_directory' : app_dir })
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not copy the info file, dmg creation failed!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if (doDeployQt is True):
|
||||||
|
logging.info('[%s] running mac deploy qt on %s.app...', script_name, settings['openlp_appname']);
|
||||||
|
|
||||||
|
result = os.system('macdeployqt %s.app' % settings['openlp_appname']);
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not create dmg file!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if (doCreateDmg is True):
|
||||||
|
logging.info('[%s] creating the dmg...', script_name)
|
||||||
|
dmg_file = os.getcwd() + '/' + settings['openlp_dmgname'] + '.dmg'
|
||||||
|
result = os.system('hdiutil create %(dmg_file)s~ -ov -megabytes %(vol_size)s -fs HFS+ -volname %(vol_name)s' \
|
||||||
|
% { 'dmg_file' : dmg_file,
|
||||||
|
'vol_size' : '250',
|
||||||
|
'vol_name' : settings['openlp_appname'] })
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not create dmg file!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
logging.info('[%s] mounting the dmg file...', script_name)
|
||||||
|
output = subp.Popen(["hdiutil", "attach", dmg_file + "~.dmg"], stdout=subp.PIPE).communicate()[0]
|
||||||
|
logging.debug(output)
|
||||||
|
|
||||||
|
p = re.compile('Apple_HFS\s+(.+?)\s*$')
|
||||||
|
result = p.search(output, re.M)
|
||||||
|
volume_basedir = ''
|
||||||
|
if result:
|
||||||
|
volume_basedir = result.group(1)
|
||||||
|
else:
|
||||||
|
logging.error('could not mount dmg file, cannot continue!')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
logging.info('[%s] copying the app (from %s) to the dmg (at %s)...', script_name, app_dir, volume_basedir)
|
||||||
|
result = os.system('CpMac -r %s %s' \
|
||||||
|
% ( app_dir, volume_basedir ))
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not copy application, dmg creation failed!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
logging.info('[%s] copying the background image...', script_name)
|
||||||
|
# os.mkdir(volume_basedir + '/.background')
|
||||||
|
result = os.system('CpMac %s %s' % (settings['installer_backgroundimage_file'], volume_basedir + '/.installer-background.png'))
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not copy the background image, dmg creation failed!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# setting base dir
|
||||||
|
volume_basedir = options.basedir
|
||||||
|
dmg_file = os.getcwd() + '/' + settings['openlp_dmgname'] + '.dmg'
|
||||||
|
|
||||||
|
if (doPackageView is True):
|
||||||
|
logging.info('[%s] making adjustments to the view...', script_name)
|
||||||
|
try:
|
||||||
|
f = open(adjustview_scriptname)
|
||||||
|
p = subp.Popen(["osascript"], stdin=subp.PIPE)
|
||||||
|
p.communicate(f.read() % ((os.getcwd() + '/' + settings['openlp_dmg_icon_file']), settings['openlp_appname'], settings['openlp_appname'], settings['openlp_appname']))
|
||||||
|
f.close()
|
||||||
|
result = p.returncode
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not adjust the view, dmg creation failed!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
except IOError, e:
|
||||||
|
logging.error('[%s] could not adjust the view (%s), dmg creation failed!', script_name, e)
|
||||||
|
sys.exit(1)
|
||||||
|
except OSError, e:
|
||||||
|
logging.error('[%s] could not adjust the view (%s), dmg creation failed!', script_name, e)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if (doCreateDmg is True):
|
||||||
|
logging.info('[%s] unmounting the dmg...', script_name)
|
||||||
|
result = os.system('hdiutil detach %s' % volume_basedir)
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not unmount the dmg file, dmg creation failed!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if (doCompressDmg is True):
|
||||||
|
logging.info('[%s] compress the dmg file...', script_name)
|
||||||
|
result = os.system('hdiutil convert %s~.dmg -format UDZO -imagekey zlib-level=9 -o %s' \
|
||||||
|
% (dmg_file, dmg_file))
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not compress the dmg file, dmg creation failed!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if (doCompressView is True):
|
||||||
|
logging.info('[%s] setting icon of the dmg file...', script_name)
|
||||||
|
try:
|
||||||
|
f = open(seticon_scriptname)
|
||||||
|
p = subp.Popen(["osascript"], stdin=subp.PIPE)
|
||||||
|
p.communicate(f.read() % ((os.getcwd() + '/' + settings['openlp_dmg_icon_file']), dmg_file))
|
||||||
|
f.close()
|
||||||
|
result = p.returncode
|
||||||
|
if (result != 0):
|
||||||
|
logging.error('[%s] could not set the icon to the dmg file, dmg creation failed!', script_name)
|
||||||
|
sys.exit(1)
|
||||||
|
except IOError, e:
|
||||||
|
logging.error('[%s] could not adjust the view (%s), dmg creation failed!', script_name, e)
|
||||||
|
sys.exit(1)
|
||||||
|
except OSError, e:
|
||||||
|
logging.error('[%s] could not set the icon to the dmg file(%s), dmg creation failed!', script_name, e)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if (doCompressDmg is True):
|
||||||
|
logging.info('[%s] finished creating dmg file, resulting file is "%s"', script_name, dmg_file)
|
||||||
|
|
195
resources/osx/expander.py
Executable file
195
resources/osx/expander.py
Executable file
@ -0,0 +1,195 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
# TODOs:
|
||||||
|
# - defaults for non-supplied expansions:
|
||||||
|
# template contains
|
||||||
|
|
||||||
|
import ConfigParser
|
||||||
|
import logging
|
||||||
|
import optparse
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# variable expansion:
|
||||||
|
# - %(dog)s --- normal python expansion
|
||||||
|
# - %(dog%)s --- no python expansion, leave as is (stripping the trailing %)
|
||||||
|
# - %(dog:cat) --- if there is an expansion for dog, dog will be used; otherwise if cat exists cat will be used
|
||||||
|
# - %(dog=cat) --- if there is an expansion for dog, dog will be used; otherwise "cat" will be used
|
||||||
|
# reConf = re.compile(r'(?<!%)%\((?P<key>[^\(]+?)\)s')
|
||||||
|
reConf = re.compile(r'(?P<verbatim>%?)%\((?P<key>[^+=:&\)]+?)(?:(?P<kind>[+=:&])(?P<default>[^\)]+))?\)(?P<type>s|d)')
|
||||||
|
|
||||||
|
def expandVariable(match, expansions, errors):
|
||||||
|
key = match.group('key')
|
||||||
|
kind = match.group('kind')
|
||||||
|
default = match.group('default')
|
||||||
|
typ = match.group('type')
|
||||||
|
verbatim = match.group('verbatim')
|
||||||
|
|
||||||
|
if verbatim:
|
||||||
|
return match.group(0)[1:]
|
||||||
|
|
||||||
|
# literal default
|
||||||
|
if kind == '=':
|
||||||
|
if key in expansions:
|
||||||
|
return expansions[key]
|
||||||
|
return default
|
||||||
|
|
||||||
|
# variable default
|
||||||
|
if kind == ':' and default in expansions:
|
||||||
|
return expansions[default]
|
||||||
|
|
||||||
|
if kind == '+' and default in expansions:
|
||||||
|
if key in expansions:
|
||||||
|
key = expansions[key]
|
||||||
|
if typ == 's':
|
||||||
|
return '%s%s' % (key, expansions[default])
|
||||||
|
if typ == 'd':
|
||||||
|
try:
|
||||||
|
return str(int(key) + int(expansions[default]))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if kind == '&' and default in expansions:
|
||||||
|
if typ == 's':
|
||||||
|
return '%s%s' % (key, expansions[default])
|
||||||
|
if typ == 'd':
|
||||||
|
try:
|
||||||
|
return str(int(key) + int(expansions[default]))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if key in expansions:
|
||||||
|
return expansions[key]
|
||||||
|
|
||||||
|
if not match.group(0) in errors:
|
||||||
|
errors.append(match.group(0))
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
options = None
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
# get config file
|
||||||
|
parser = optparse.OptionParser()
|
||||||
|
parser.add_option('-c', '--config', dest = 'config', help = 'config file', metavar = 'CONFIG')
|
||||||
|
parser.add_option('-t', '--template', dest = 'template', help = 'template file', metavar = 'TEMPLATE')
|
||||||
|
parser.add_option('-x', '--expandto', dest = 'expanded', help = 'expanded file', metavar = 'EXPANDED')
|
||||||
|
parser.add_option('-e', '--echo', dest = 'echo', help = 'echo variable', metavar = 'ECHOVAR')
|
||||||
|
|
||||||
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
if not options.config:
|
||||||
|
parser.error('option --config|-c is required')
|
||||||
|
if not os.path.exists(options.config):
|
||||||
|
parser.error('config file "%s" does not exist' % options.config)
|
||||||
|
if not options.echo:
|
||||||
|
if not options.template:
|
||||||
|
parser.error('option --template|-t is required')
|
||||||
|
if not os.path.exists(options.template):
|
||||||
|
parser.error('template file "%s" does not exist' % options.template)
|
||||||
|
if not options.expanded:
|
||||||
|
parser.error('option --expandto|-e is required')
|
||||||
|
|
||||||
|
logHandler = logging.StreamHandler()
|
||||||
|
logHandler.setFormatter(logging.Formatter('%(asctime)s %(levelname)-8s %(message)s',
|
||||||
|
'%a, %d %b %Y %H:%M:%S'))
|
||||||
|
logging.getLogger().addHandler(logHandler)
|
||||||
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
|
||||||
|
config = ConfigParser.RawConfigParser()
|
||||||
|
config.readfp(open(options.config, 'r'))
|
||||||
|
|
||||||
|
if not config.has_section('openlp'):
|
||||||
|
logging.error('[expander] %s: config file "%s" lacks an [openlp] section',
|
||||||
|
options.template, options.config)
|
||||||
|
|
||||||
|
expansions = dict()
|
||||||
|
for k in config.options('openlp'):
|
||||||
|
expansions[k] = config.get('openlp', k)
|
||||||
|
|
||||||
|
# commandline overrides?
|
||||||
|
for override in args:
|
||||||
|
if not '=' in override:
|
||||||
|
continue
|
||||||
|
|
||||||
|
(k, v) = override.split('=', 2)
|
||||||
|
expansions[k] = v
|
||||||
|
|
||||||
|
if options.echo:
|
||||||
|
if options.echo in expansions:
|
||||||
|
print expansions[options.echo]
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
# closure to capture expansions and errors variable
|
||||||
|
errors = []
|
||||||
|
expanded = []
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
# try to expand the template
|
||||||
|
line = 0
|
||||||
|
faulty = False
|
||||||
|
|
||||||
|
template = open(options.template, 'r')
|
||||||
|
raw = template.readlines()
|
||||||
|
template.close()
|
||||||
|
|
||||||
|
def _expand(m):
|
||||||
|
return expandVariable(m, expansions = expansions, errors = errors)
|
||||||
|
|
||||||
|
for l in raw:
|
||||||
|
line += 1
|
||||||
|
exp = reConf.sub(_expand, l)
|
||||||
|
if errors:
|
||||||
|
for key in errors:
|
||||||
|
logging.error('[expander] %s: line %d: could not expand key "%s"', options.template, line, key)
|
||||||
|
faulty = True
|
||||||
|
errors = []
|
||||||
|
else:
|
||||||
|
expanded.append(exp)
|
||||||
|
|
||||||
|
if faulty:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# successfully expanded template, now backup potentially existing target file
|
||||||
|
targetFile = options.expanded % expansions
|
||||||
|
if os.path.exists(targetFile):
|
||||||
|
if os.path.exists('%s~' % targetFile):
|
||||||
|
os.unlink('%s~' % targetFile)
|
||||||
|
os.rename(options.expanded, '%s~' % targetFile)
|
||||||
|
logging.info('[expander] %s: backed up existing target file "%s" to "%s"',
|
||||||
|
options.template, targetFile, '%s~' % options.expanded)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: make sure that target directory exists
|
||||||
|
targetDir = os.path.dirname(targetFile)
|
||||||
|
if not os.path.exists(targetDir):
|
||||||
|
os.makedirs(targetDir)
|
||||||
|
|
||||||
|
# write target file
|
||||||
|
try:
|
||||||
|
target = open(targetFile, 'w')
|
||||||
|
for exp in expanded:
|
||||||
|
target.write(exp)
|
||||||
|
target.close()
|
||||||
|
except Exception, e:
|
||||||
|
logging.error('[expander] %s: could not expand to "%s"', options.template, options.expaned, e)
|
||||||
|
|
||||||
|
|
||||||
|
# copy over file access mode from template
|
||||||
|
mode = os.stat(options.template)
|
||||||
|
os.chmod(options.expanded, mode.st_mode)
|
||||||
|
|
||||||
|
logging.info('[expander] expanded "%s" to "%s"',
|
||||||
|
options.template, options.expanded)
|
||||||
|
|
||||||
|
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
BIN
resources/osx/installation-background.png
Executable file
BIN
resources/osx/installation-background.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
resources/osx/openlp-logo-420x420-background.png
Executable file
BIN
resources/osx/openlp-logo-420x420-background.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 76 KiB |
BIN
resources/osx/openlp-logo-420x420.png
Normal file
BIN
resources/osx/openlp-logo-420x420.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 97 KiB |
BIN
resources/osx/openlp-logo-with-text.icns
Executable file
BIN
resources/osx/openlp-logo-with-text.icns
Executable file
Binary file not shown.
BIN
resources/osx/openlp-splash-screen.png
Executable file
BIN
resources/osx/openlp-splash-screen.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
11
resources/osx/openlp.cfg
Executable file
11
resources/osx/openlp.cfg
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
[openlp]
|
||||||
|
openlp_appname = OpenLP
|
||||||
|
openlp_dmgname = OpenLP-1.9.4-bzrXXXX
|
||||||
|
openlp_version = XXXX
|
||||||
|
openlp_full_version = 1.9.4-latest
|
||||||
|
openlp_basedir = /Users/openlp/trunk
|
||||||
|
openlp_icon_file = openlp-logo-with-text.icns
|
||||||
|
openlp_dmg_icon_file = openlp-logo-420x420.png
|
||||||
|
installer_backgroundimage_file = installation-background.png
|
||||||
|
pyinstaller_basedir = /Users/openlp/pyinstaller/trunk
|
||||||
|
qt_menu_basedir = /Library/Frameworks/QtGui.framework/Versions/4/Resources/qt_menu.nib
|
24
resources/osx/openlp.spec.master
Executable file
24
resources/osx/openlp.spec.master
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
# -*- mode: python -*-
|
||||||
|
a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), '%(openlp_basedir)s/openlp.pyw'],
|
||||||
|
pathex=['%(pyinstaller_basedir)s'], hookspath=['%(openlp_basedir)s/resources/pyinstaller'])
|
||||||
|
pyz = PYZ(a.pure)
|
||||||
|
exe = EXE(pyz,
|
||||||
|
a.scripts,
|
||||||
|
exclude_binaries=1,
|
||||||
|
name=os.path.join('build/pyi.darwin/openlp', 'openlp'),
|
||||||
|
debug=False,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
console=1 )
|
||||||
|
coll = COLLECT( exe,
|
||||||
|
a.binaries,
|
||||||
|
a.zipfiles,
|
||||||
|
a.datas,
|
||||||
|
strip=False,
|
||||||
|
upx=True,
|
||||||
|
name=os.path.join('dist', 'openlp'))
|
||||||
|
import sys
|
||||||
|
if sys.platform.startswith("darwin"):
|
||||||
|
app = BUNDLE(coll,
|
||||||
|
name='%(openlp_appname)s.app',
|
||||||
|
version='%(openlp_version)s')
|
1
resources/osx/version.master
Executable file
1
resources/osx/version.master
Executable file
@ -0,0 +1 @@
|
|||||||
|
%(openlp_full_version)s
|
Loading…
Reference in New Issue
Block a user