diff --git a/openlp.pyw b/openlp.pyw index 85ba81fba..d3da1c835 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -273,6 +273,8 @@ def main(): qInitResources() # Now create and actually run the application. app = OpenLP(qt_args) + if sys.platform == 'darwin': + QtGui.QApplication.addLibraryPath(QtGui.QApplication.applicationDirPath() + "/qt4_plugins") #i18n Set Language language = LanguageManager.get_language() appTranslator = LanguageManager.get_translator(language) diff --git a/resources/osx/Info.plist.master b/resources/osx/Info.plist.master new file mode 100755 index 000000000..e97e1faf5 --- /dev/null +++ b/resources/osx/Info.plist.master @@ -0,0 +1,32 @@ + + + + +CFBundleIdentifier +org.openlp +CFBundleShortVersionString +%(openlp_version)s +CFBundleVersion +%(openlp_version)s +CFBundleInfoDictionaryVersion +6.0 +CFBundleDisplayName +%(openlp_appname)s +CFBundleIconFile +openlp-logo-with-text.icns +CFBundleExecutable +MacOS/openlp +CFBundleName +%(openlp_appname)s +CFBundleGetInfoString +%(openlp_appname)s %(openlp_version)s +LSHasLocalizedDisplayName + +NSAppleScriptEnabled + +CFBundlePackageType +APPL +LSBackgroundOnly + + + diff --git a/resources/osx/Makefile b/resources/osx/Makefile new file mode 100644 index 000000000..422749da5 --- /dev/null +++ b/resources/osx/Makefile @@ -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 + diff --git a/resources/osx/applescript-adjustview-10-5.master b/resources/osx/applescript-adjustview-10-5.master new file mode 100755 index 000000000..abc0e5a8d --- /dev/null +++ b/resources/osx/applescript-adjustview-10-5.master @@ -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 diff --git a/resources/osx/applescript-adjustview-10-6.master b/resources/osx/applescript-adjustview-10-6.master new file mode 100755 index 000000000..2b5a0c000 --- /dev/null +++ b/resources/osx/applescript-adjustview-10-6.master @@ -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 diff --git a/resources/osx/applescript-seticon-10-5.master b/resources/osx/applescript-seticon-10-5.master new file mode 100755 index 000000000..738c4b883 --- /dev/null +++ b/resources/osx/applescript-seticon-10-5.master @@ -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 diff --git a/resources/osx/applescript-seticon-10-6.master b/resources/osx/applescript-seticon-10-6.master new file mode 100755 index 000000000..849f02344 --- /dev/null +++ b/resources/osx/applescript-seticon-10-6.master @@ -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 diff --git a/resources/osx/build.py b/resources/osx/build.py new file mode 100644 index 000000000..e0e338d46 --- /dev/null +++ b/resources/osx/build.py @@ -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) + diff --git a/resources/osx/expander.py b/resources/osx/expander.py new file mode 100755 index 000000000..fee4138b5 --- /dev/null +++ b/resources/osx/expander.py @@ -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'(?[^\(]+?)\)s') +reConf = re.compile(r'(?P%?)%\((?P[^+=:&\)]+?)(?:(?P[+=:&])(?P[^\)]+))?\)(?Ps|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 + diff --git a/resources/osx/installation-background.png b/resources/osx/installation-background.png new file mode 100755 index 000000000..8a41d3b68 Binary files /dev/null and b/resources/osx/installation-background.png differ diff --git a/resources/osx/openlp-logo-420x420-background.png b/resources/osx/openlp-logo-420x420-background.png new file mode 100755 index 000000000..1008621d6 Binary files /dev/null and b/resources/osx/openlp-logo-420x420-background.png differ diff --git a/resources/osx/openlp-logo-420x420.png b/resources/osx/openlp-logo-420x420.png new file mode 100644 index 000000000..85457d8fb Binary files /dev/null and b/resources/osx/openlp-logo-420x420.png differ diff --git a/resources/osx/openlp-logo-with-text.icns b/resources/osx/openlp-logo-with-text.icns new file mode 100755 index 000000000..6066b111e Binary files /dev/null and b/resources/osx/openlp-logo-with-text.icns differ diff --git a/resources/osx/openlp-splash-screen.png b/resources/osx/openlp-splash-screen.png new file mode 100755 index 000000000..618e47c6e Binary files /dev/null and b/resources/osx/openlp-splash-screen.png differ diff --git a/resources/osx/openlp.cfg b/resources/osx/openlp.cfg new file mode 100755 index 000000000..1f04861b5 --- /dev/null +++ b/resources/osx/openlp.cfg @@ -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 diff --git a/resources/osx/openlp.spec.master b/resources/osx/openlp.spec.master new file mode 100755 index 000000000..94aec2a60 --- /dev/null +++ b/resources/osx/openlp.spec.master @@ -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') diff --git a/resources/osx/version.master b/resources/osx/version.master new file mode 100755 index 000000000..d517a51bc --- /dev/null +++ b/resources/osx/version.master @@ -0,0 +1 @@ +%(openlp_full_version)s