Change to 120 charcter limit

This commit is contained in:
Jonathan Springer 2014-05-06 12:04:21 -04:00
parent 4bd0610ad8
commit b66db894fd
2 changed files with 165 additions and 274 deletions

View File

@ -137,6 +137,7 @@ class MacosxBuilder(object):
The :class:`MacosxBuilder` class encapsulates everything that is needed
to build a Mac OS X .dmg file.
"""
def __init__(self):
self.setup_args()
self.setup_system_paths()
@ -173,7 +174,7 @@ class MacosxBuilder(object):
self._print(error)
raise Exception(err_msg)
return output
def _get_directory_size(self, directory):
"""
Return directory size - size of everything in the dir.
@ -184,15 +185,14 @@ class MacosxBuilder(object):
filename = os.path.join(path, file)
dir_size += os.path.getsize(filename)
return dir_size
def _get_mountpoints(self):
"""
Return list of mounted disks on Mac.
"""
# Get the output in plist format.
paths = []
output = self._run_command([self.hdiutil, 'info', '-plist'],
'Detecting mount points failed.')
output = self._run_command([self.hdiutil, 'info', '-plist'], 'Detecting mount points failed.')
pl = plistlib.readPlistFromString(output)
for image in pl['images']:
for se in image['system-entities']:
@ -207,33 +207,25 @@ class MacosxBuilder(object):
"""
parser = ArgumentParser()
parser.add_argument('-b', '--branch', metavar='BRANCH', dest='branch',
help='Specify the path to the branch you wish to build.')
parser.add_argument('--devel', dest='devel',
action='store_true', default=False,
help='Development build does not have set icons for .dmg file '
'and .dmg filename contains bzr revision number.')
parser.add_argument('-d', '--documentation', metavar='DOCS',
dest='docs',
help='Specify the path to the documentation branch.')
help='Specify the path to the branch you wish to build.')
parser.add_argument('--devel', dest='devel', action='store_true', default=False,
help='Development build does not have set icons for .dmg file '
'and .dmg filename contains bzr revision number.')
parser.add_argument('-d', '--documentation', metavar='DOCS', dest='docs',
help='Specify the path to the documentation branch.')
parser.add_argument('-c', '--config', metavar='CONFIG', dest='config',
help='Specify the path to the configuration file.',
default=os.path.abspath(os.path.join('.', 'config.ini.default')))
parser.add_argument('-u', '--skip-update', dest='skip_update',
action='store_true', default=False,
help='Do NOT update the branch before building.')
parser.add_argument('-t', '--skip-translations',
dest='skip_translations', action='store_true', default=False,
help='Do NOT update the language translation files.')
parser.add_argument('--transifex',
dest='update_translations', action='store_true', default=False,
help='Update the language translation from Transifex.')
parser.add_argument('--transifex-user',
dest='transifex_user', help='Transifex username.')
parser.add_argument('--transifex-pass',
dest='transifex_pass', help='Transifex password.')
parser.add_argument('-v', '--verbose', dest='verbose',
action='store_true', default=False,
help='Print out additional information.')
help='Specify the path to the configuration file.',
default=os.path.abspath(os.path.join('.', 'config.ini.default')))
parser.add_argument('-u', '--skip-update', dest='skip_update', action='store_true', default=False,
help='Do NOT update the branch before building.')
parser.add_argument('-t', '--skip-translations', dest='skip_translations', action='store_true', default=False,
help='Do NOT update the language translation files.')
parser.add_argument('--transifex', dest='update_translations', action='store_true', default=False,
help='Update the language translation from Transifex.')
parser.add_argument('--transifex-user', dest='transifex_user', help='Transifex username.')
parser.add_argument('--transifex-pass', dest='transifex_pass', help='Transifex password.')
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', default=False,
help='Print out additional information.')
self.args = parser.parse_args()
def read_config(self):
@ -242,9 +234,7 @@ class MacosxBuilder(object):
"""
self.config = ConfigParser(defaults={
'here': self.script_path,
'projects': os.path.abspath(os.path.join(self.script_path,
'..', '..')),
})
'projects': os.path.abspath(os.path.join(self.script_path, '..', '..')), })
self.config.read(os.path.abspath(self.args.config))
def setup_system_paths(self):
@ -259,13 +249,12 @@ class MacosxBuilder(object):
Set up the paths to the executables we use.
"""
self.sphinx = _which(self.config.get('executables', 'sphinx'))
self.pyinstaller = os.path.abspath(
self.config.get('executables', 'pyinstaller'))
self.pyinstaller = os.path.abspath(self.config.get('executables', 'pyinstaller'))
self.lrelease = _which(self.config.get('executables', 'lrelease'))
self.diskutil = _which(self.config.get('executables', 'diskutil'))
self.hdiutil = _which(self.config.get('executables', 'hdiutil'))
self.osascript = _which(self.config.get('executables', 'osascript'))
def setup_paths(self):
"""
Set up a variety of paths that we use throughout the build process.
@ -279,32 +268,25 @@ class MacosxBuilder(object):
else:
self.docs_path = self.config.get('paths', 'documentation')
self.openlp_script = os.path.abspath(
os.path.join(self.branch_path, 'openlp.py'))
self.hooks_path = os.path.abspath(os.path.join(
self.branch_path, self.config.get('paths', 'hooks')))
self.mac_icon = os.path.abspath(
self.config.get('paths', 'macicon'))
self.bundle_info = os.path.abspath(
self.config.get('paths', 'bundleinfo'))
self.dmg_background_img = os.path.abspath(
self.config.get('paths', 'dmg_background'))
self.i18n_utils = os.path.join(self.branch_path, 'scripts',
'translation_utils.py')
self.openlp_script = os.path.abspath(os.path.join(self.branch_path, 'openlp.py'))
self.hooks_path = os.path.abspath(os.path.join(self.branch_path, self.config.get('paths', 'hooks')))
self.mac_icon = os.path.abspath(self.config.get('paths', 'macicon'))
self.bundle_info = os.path.abspath(self.config.get('paths', 'bundleinfo'))
self.dmg_background_img = os.path.abspath(self.config.get('paths', 'dmg_background'))
self.i18n_utils = os.path.join(self.branch_path, 'scripts', 'translation_utils.py')
self.source_path = os.path.join(self.branch_path, 'openlp')
self.manual_path = os.path.join(self.docs_path, 'manual')
self.manual_build_path = os.path.join(self.manual_path, 'build')
self.i18n_path = os.path.join(self.branch_path, 'resources', 'i18n')
self.build_path = os.path.join(self.branch_path, 'build')
self.dist_app_path = os.path.join(self.branch_path, 'dist', 'OpenLP.app')
self.dist_path = os.path.join(self.branch_path, 'dist', 'OpenLP.app',
'Contents', 'MacOS')
self.dist_path = os.path.join(self.branch_path, 'dist', 'OpenLP.app', 'Contents', 'MacOS')
# Path to Qt translation files.
from PyQt4.QtCore import QCoreApplication
qt_plug_dir = str(list(QCoreApplication.libraryPaths())[0])
self.qt_translat_path = os.path.join(os.path.dirname(qt_plug_dir),
'translations')
self.qt_translat_path = os.path.join(os.path.dirname(qt_plug_dir), 'translations')
def update_code(self):
"""
@ -333,19 +315,19 @@ class MacosxBuilder(object):
self._print('Running PyInstaller...')
os.chdir(self.branch_path)
pyinstaller = Popen((self.python,
self.pyinstaller,
'--noconfirm',
'--windowed',
'--noupx',
'--additional-hooks-dir', self.hooks_path,
'--runtime-hook', os.path.join(self.hooks_path, 'rthook_openlp_pyqt4.py'),
'--log-level=ERROR',
'-o', self.branch_path,
#u'-i', self.mac_icon,
'-p', self.branch_path,
'-n', 'OpenLP',
self.openlp_script),
stdout=PIPE)
self.pyinstaller,
'--noconfirm',
'--windowed',
'--noupx',
'--additional-hooks-dir', self.hooks_path,
'--runtime-hook', os.path.join(self.hooks_path, 'rthook_openlp_pyqt4.py'),
'--log-level=ERROR',
'-o', self.branch_path,
#u'-i', self.mac_icon,
'-p', self.branch_path,
'-n', 'OpenLP',
self.openlp_script),
stdout=PIPE)
output = pyinstaller.communicate()[0]
code = pyinstaller.wait()
if code != 0:
@ -397,12 +379,11 @@ class MacosxBuilder(object):
for root, dirs, files in os.walk(source):
for filename in files:
if not filename.endswith('.pyc'):
dest_path = os.path.join(dest, root[len(source)+1:])
dest_path = os.path.join(dest, root[len(source) + 1:])
if not os.path.exists(dest_path):
os.makedirs(dest_path)
self._print_verbose('... %s', filename)
copy(os.path.join(root, filename),
os.path.join(dest_path, filename))
copy(os.path.join(root, filename), os.path.join(dest_path, filename))
def copy_media_player(self):
"""
@ -414,27 +395,24 @@ class MacosxBuilder(object):
for root, dirs, files in os.walk(source):
for filename in files:
if not filename.endswith('.pyc'):
dest_path = os.path.join(dest, root[len(source)+1:])
dest_path = os.path.join(dest, root[len(source) + 1:])
if not os.path.exists(dest_path):
os.makedirs(dest_path)
self._print_verbose('... %s', filename)
copy(os.path.join(root, filename),
os.path.join(dest_path, filename))
copy(os.path.join(root, filename), os.path.join(dest_path, filename))
def copy_mac_bundle_files(self):
"""
Copy Info.plist and OpenLP.icns to app bundle.
"""
copy(self.mac_icon, os.path.join(self.dist_app_path,
'Contents', 'Resources', os.path.basename(self.mac_icon)))
copy(self.mac_icon, os.path.join(self.dist_app_path, 'Contents', 'Resources', os.path.basename(self.mac_icon)))
# Add OpenLP version to Info.plist and put it to app bundle.
fr = open(self.bundle_info, 'r')
fw = open(os.path.join(self.dist_app_path,
'Contents', os.path.basename(self.bundle_info)), 'w')
fw = open(os.path.join(self.dist_app_path, 'Contents', os.path.basename(self.bundle_info)), 'w')
text = fr.read()
text = text % {'openlp_version': self.version_string}
fw.write(text)
fr.close()
fw.close()
@ -444,8 +422,7 @@ class MacosxBuilder(object):
"""
self._print('Copying extra files for Mac OS X...')
self._print_verbose('... LICENSE.txt')
copy(os.path.join(self.script_path, 'LICENSE.txt'),
os.path.join(self.dist_path, 'LICENSE.txt'))
copy(os.path.join(self.script_path, 'LICENSE.txt'), os.path.join(self.dist_path, 'LICENSE.txt'))
def update_translations(self):
"""
@ -467,8 +444,7 @@ class MacosxBuilder(object):
else:
password = self.config.get('transifex', 'password')
os.chdir(os.path.split(self.i18n_utils)[0])
translation_utils = Popen([self.python, self.i18n_utils, '-qdpu',
'-U', username, '-P', password])
translation_utils = Popen([self.python, self.i18n_utils, '-qdpu', '-U', username, '-P', password])
code = translation_utils.wait()
if code != 0:
raise Exception('Error running translation_utils.py')
@ -485,36 +461,29 @@ class MacosxBuilder(object):
if file.endswith('.ts'):
self._print_verbose('... %s', file)
source_path = os.path.join(self.i18n_path, file)
dest_path = os.path.join(self.dist_path, 'i18n',
file.replace('.ts', '.qm'))
lconvert = Popen((self.lrelease, '-compress', '-silent',
source_path, '-qm', dest_path))
dest_path = os.path.join(self.dist_path, 'i18n', file.replace('.ts', '.qm'))
lconvert = Popen((self.lrelease, '-compress', '-silent', source_path, '-qm', dest_path))
code = lconvert.wait()
if code != 0:
raise Exception('Error running lconvert on %s' % \
source_path)
raise Exception('Error running lconvert on %s' % source_path)
self._print('Copying qm files...')
source = self.qt_translat_path
files = os.listdir(source)
for filename in files:
if filename.startswith('qt_') and filename.endswith('.qm') and \
len(filename) == 8:
if filename.startswith('qt_') and filename.endswith('.qm') and len(filename) == 8:
self._print_verbose('... %s', filename)
copy(os.path.join(source, filename),
os.path.join(self.dist_path, 'i18n', filename))
copy(os.path.join(source, filename), os.path.join(self.dist_path, 'i18n', filename))
def run_sphinx(self):
"""
Run Sphinx to build an HTML Help project.
"""
self._print('Deleting previous manual build... %s',
self.manual_build_path)
self._print('Deleting previous manual build... %s', self.manual_build_path)
if os.path.exists(self.manual_build_path):
rmtree(self.manual_build_path)
self._print('Running Sphinx...')
os.chdir(self.manual_path)
sphinx = Popen((self.sphinx, '-b', 'htmlhelp', '-d',
'build/doctrees', 'source', 'build/htmlhelp'), stdout=PIPE)
sphinx = Popen((self.sphinx, '-b', 'htmlhelp', '-d', 'build/doctrees', 'source', 'build/htmlhelp'), stdout=PIPE)
output, error = sphinx.communicate()
code = sphinx.wait()
if code != 0:
@ -542,18 +511,13 @@ class MacosxBuilder(object):
size = size / (1024 * 1024) # Convert to megabytes.
size += 10 # Additional space in .dmg for other files.
self._print('... dmg disk size: %s' % size)
self._run_command([self.hdiutil, 'create', dmg_file,
'-ov', '-megabytes', str(size),
'-fs', 'HFS+', '-volname', 'OpenLP'],
'Could not create dmg file.'
)
self._run_command([self.hdiutil, 'create', dmg_file, '-ov', '-megabytes', str(size), '-fs', 'HFS+', '-volname',
'OpenLP'], 'Could not create dmg file.')
# Mount empty dmg file.
old_mounts = self._get_mountpoints()
self._print('... mounting the dmg file: %s' % dmg_file)
self._run_command([self.hdiutil, 'attach', dmg_file],
'Could not mount dmg file, cannot continue.'
)
self._run_command([self.hdiutil, 'attach', dmg_file], 'Could not mount dmg file, cannot continue.')
new_mounts = self._get_mountpoints()
# Get the mount point from difference between paths
# after mounting and before mounting the dmg file.
@ -562,24 +526,18 @@ class MacosxBuilder(object):
# Copy OpenLP.app and other files to .dmg
# TODO more reliable way to determine dmg_volume_path
self._print('... Copying the app to the dmg: ' + dmg_volume_path)
self._run_command(['cp', '-r', self.dist_app_path,
dmg_volume_path],
'Could not copy app bundle, dmg creation failed.'
)
self._run_command(['cp', '-r', self.dist_app_path, dmg_volume_path],
'Could not copy app bundle, dmg creation failed.')
# Set icon for dmg file.
# http://endrift.com/blog/2010/06/14/dmg-files-volume-icons-cli/
self._print('... Setting the dmg icon.')
dmg_icon = os.path.join(dmg_volume_path, '.VolumeIcon.icns')
self._run_command(['cp', self.mac_icon, dmg_icon],
'Could not copy the dmg icon file, dmg creation failed.'
)
self._run_command(['cp', self.mac_icon, dmg_icon], 'Could not copy the dmg icon file, dmg creation failed.')
# Set proper dmg icon attributes.
self._run_command(['SetFile', '-c', 'icnC', dmg_icon],
'Could not set dmg icon attributes.')
self._run_command(['SetFile', '-c', 'icnC', dmg_icon], 'Could not set dmg icon attributes.')
# Ensures dmg icon will be used while mounted.
self._run_command(['SetFile', '-a', 'C', dmg_volume_path],
'Could not set dmg icon attributes.')
self._run_command(['SetFile', '-a', 'C', dmg_volume_path], 'Could not set dmg icon attributes.')
# Create symlink in dmg pointing to the /Applications directory on OS X.
self._print('... Creating symlink to /Applications.')
@ -591,11 +549,9 @@ class MacosxBuilder(object):
self._print('... Setting the background image.')
os.mkdir(os.path.join(dmg_volume_path, '.background'))
self._run_command(['cp', self.dmg_background_img,
os.path.join(dmg_volume_path,
'.background/installer-background.png')],
'Could not copy the background image, dmg creation failed.'
)
self._run_command(['cp', self.dmg_background_img, os.path.join(dmg_volume_path,
'.background/installer-background.png')],
'Could not copy the background image, dmg creation failed.')
self.adjust_dmg_view(os.path.basename(dmg_volume_path))
@ -613,44 +569,36 @@ class MacosxBuilder(object):
self._print('... failed to kill process using %s' % dmg_volume_path)
# Unmount dmg file.
self._run_command([self.hdiutil, 'detach', dmg_volume_path],
'Could not unmount the dmg file, dmg creation failed.'
)
'Could not unmount the dmg file, dmg creation failed.')
# Compress dmg file.
self._print('... compressing the dmg file')
compressed_dmg = os.path.join(self.branch_path, 'dist',
os.path.basename(dmg_file)) # Put dmg to 'dist' dir.
compressed_dmg = os.path.join(self.branch_path, 'dist', os.path.basename(dmg_file)) # Put dmg to 'dist' dir.
# Remove dmg if it exists.
if os.path.exists(compressed_dmg):
os.remove(compressed_dmg)
self._run_command([self.hdiutil,
'convert', dmg_file, '-format', 'UDZO',
'-imagekey', 'zlib-level=9', '-o', compressed_dmg],
'Could not compress the dmg file, dmg creation failed.'
)
self._run_command([self.hdiutil, 'convert', dmg_file, '-format', 'UDZO', '-imagekey', 'zlib-level=9', '-o',
compressed_dmg], 'Could not compress the dmg file, dmg creation failed.')
# Jenkins integration.
# Continuous integration server needs to know the filename of dmg.
# Write java property file. For uploading dmg to openlp.
if self.args.devel:
fpath = os.path.join(self.branch_path, 'openlp.properties')
self._print('... writing property file for jenkins: %s' %
fpath)
self._print('... writing property file for jenkins: %s' % fpath)
f = open(fpath, 'w')
f.write('OPENLP_DMGNAME=' + os.path.basename(dmg_file) + '\n')
f.close()
# Dmg done.
self._print('Finished creating dmg file, resulting file: %s' %
compressed_dmg)
self._print('Finished creating dmg file, resulting file: %s' % compressed_dmg)
self.dmg_file = compressed_dmg
def adjust_dmg_view(self, dmg_volume_name):
try:
# TODO: Use only one applescript file. Remove one for osx 10.5.
f = open(os.path.join(self.script_path,
'applescript-adjust-dmg-view.master'))
f = open(os.path.join(self.script_path, 'applescript-adjust-dmg-view.master'))
p = Popen([self.osascript], stdin=PIPE)
p.communicate(f.read() % (dmg_volume_name, 'OpenLP'))
f.close()
@ -664,10 +612,8 @@ class MacosxBuilder(object):
"""
The main function to run the Mac OS X builder.
"""
self._print_verbose('OpenLP main script: ......%s',
self.openlp_script)
self._print_verbose('Script path: .............%s',
os.path.split(os.path.abspath(__file__))[0])
self._print_verbose('OpenLP main script: ......%s', self.openlp_script)
self._print_verbose('Script path: .............%s', os.path.split(os.path.abspath(__file__))[0])
self._print_verbose('Branch path: .............%s', self.branch_path)
self._print_verbose('Source path: .............%s', self.source_path)
self._print_verbose('"dist.app" path: .........%s', self.dist_app_path)

View File

@ -138,6 +138,7 @@ class WindowsBuilder(object):
The :class:`WindowsBuilder` class encapsulates everything that is needed
to build a Windows installer.
"""
def __init__(self):
self.setup_args()
self.setup_system_paths()
@ -167,26 +168,20 @@ class WindowsBuilder(object):
"""
parser = ArgumentParser()
parser.add_argument('-b', '--branch', metavar='BRANCH', dest='branch',
help='Specify the path to the branch you wish to build.',
default=None)
parser.add_argument('-d', '--documentation', metavar='DOCS',
dest='docs', default=None,
help='Specify the path to the documentation branch.')
help='Specify the path to the branch you wish to build.', default=None)
parser.add_argument('-d', '--documentation', metavar='DOCS', dest='docs', default=None,
help='Specify the path to the documentation branch.')
parser.add_argument('-c', '--config', metavar='CONFIG', dest='config',
help='Specify the path to the configuration file.',
default=os.path.abspath(os.path.join('.', 'config.ini')))
parser.add_argument('-u', '--skip-update', dest='skip_update',
action='store_true', default=False,
help='Do NOT update the branch before building.')
parser.add_argument('-p', '--portable', metavar='PORTABLE',
dest='portable', default=None,
help='Specify the path to build the portable installation.')
parser.add_argument('-t', '--skip-translations',
dest='skip_translations', action='store_true', default=False,
help='Do NOT update the language translation files.')
parser.add_argument('-v', '--verbose', dest='verbose',
action='store_true', default=False,
help='Print out additional information.')
help='Specify the path to the configuration file.',
default=os.path.abspath(os.path.join('.', 'config.ini')))
parser.add_argument('-u', '--skip-update', dest='skip_update', action='store_true', default=False,
help='Do NOT update the branch before building.')
parser.add_argument('-p', '--portable', metavar='PORTABLE', dest='portable', default=None,
help='Specify the path to build the portable installation.')
parser.add_argument('-t', '--skip-translations', dest='skip_translations', action='store_true', default=False,
help='Do NOT update the language translation files.')
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', default=False,
help='Print out additional information.')
self.args = parser.parse_args()
def read_config(self):
@ -208,40 +203,29 @@ class WindowsBuilder(object):
self.script_path = os.path.split(os.path.abspath(__file__))[0]
self.python = sys.executable
self.python_root = os.path.split(self.python)[0]
self.site_packages = os.path.join(self.python_root,
'Lib', 'site-packages')
self.site_packages = os.path.join(self.python_root, 'Lib', 'site-packages')
self.program_files = os.getenv('PROGRAMFILES')
def setup_executables(self):
"""
Set up the paths to the executables we use.
"""
self.innosetup = os.path.abspath(
self.config.get('executables', 'innosetup'))
self.sphinx = os.path.abspath(
self.config.get('executables', 'sphinx'))
self.pyinstaller = os.path.abspath(
self.config.get('executables', 'pyinstaller'))
self.vcbuild = os.path.abspath(
self.config.get('executables', 'vcbuild'))
self.hhc = os.path.abspath(
self.config.get('executables', 'htmlhelp'))
self.psvince = os.path.abspath(
self.config.get('executables', 'psvince'))
self.portableinstaller = os.path.abspath(
self.config.get('executables', 'portableinstaller'))
self.portablelauncher = os.path.abspath(
self.config.get('executables', 'portablelauncher'))
self.innosetup = os.path.abspath(self.config.get('executables', 'innosetup'))
self.sphinx = os.path.abspath(self.config.get('executables', 'sphinx'))
self.pyinstaller = os.path.abspath(self.config.get('executables', 'pyinstaller'))
self.vcbuild = os.path.abspath(self.config.get('executables', 'vcbuild'))
self.hhc = os.path.abspath(self.config.get('executables', 'htmlhelp'))
self.psvince = os.path.abspath(self.config.get('executables', 'psvince'))
self.portableinstaller = os.path.abspath(self.config.get('executables', 'portableinstaller'))
self.portablelauncher = os.path.abspath(self.config.get('executables', 'portablelauncher'))
if os.path.exists(os.path.join(self.site_packages, 'PyQt4', 'bin')):
# Older versions of the PyQt4 Windows installer put their binaries
# in the "bin" directory
self.lrelease = os.path.join(self.site_packages, 'PyQt4',
'bin', 'lrelease.exe')
self.lrelease = os.path.join(self.site_packages, 'PyQt4', 'bin', 'lrelease.exe')
else:
# Newer versions of the PyQt4 Windows installer put their binaries
# in the base directory of the installation
self.lrelease = os.path.join(self.site_packages, 'PyQt4',
'lrelease.exe')
self.lrelease = os.path.join(self.site_packages, 'PyQt4', 'lrelease.exe')
def setup_paths(self):
"""
@ -274,19 +258,16 @@ class WindowsBuilder(object):
self.hooks_path = os.path.abspath(self.config.get('paths', 'hooks'))
self.win32_icon = os.path.abspath(
self.config.get('paths', 'win32icon'))
self.i18n_utils = os.path.join(self.branch_path, 'scripts',
'translation_utils.py')
self.i18n_utils = os.path.join(self.branch_path, 'scripts', 'translation_utils.py')
self.source_path = os.path.join(self.branch_path, 'openlp')
self.manual_path = os.path.join(self.docs_path, 'manual')
self.manual_build_path = os.path.join(self.manual_path, 'build')
self.helpfile_path = os.path.join(self.manual_build_path, 'htmlhelp')
self.i18n_path = os.path.join(self.branch_path, 'resources', 'i18n')
self.winres_path = os.path.join(self.branch_path, 'resources',
'windows')
self.winres_path = os.path.join(self.branch_path, 'resources', 'windows')
self.build_path = os.path.join(self.branch_path, 'build')
self.dist_path = os.path.join(self.branch_path, 'dist', 'OpenLP')
self.pptviewlib_path = os.path.join(self.source_path, 'plugins',
'presentations', 'lib', 'pptviewlib')
self.pptviewlib_path = os.path.join(self.source_path, 'plugins', 'presentations', 'lib', 'pptviewlib')
def update_code(self):
"""
@ -315,18 +296,18 @@ class WindowsBuilder(object):
self._print('Running PyInstaller...')
os.chdir(self.branch_path)
pyinstaller = Popen((self.python, self.pyinstaller,
'--noconfirm',
'--windowed',
'--noupx',
'--additional-hooks-dir', self.hooks_path,
'--runtime-hook', os.path.join(self.hooks_path, 'rthook_openlp_pyqt4.py'),
'--log-level=ERROR',
'-o', self.branch_path,
'-i', self.win32_icon,
'-p', self.branch_path,
'-n', 'OpenLP',
self.openlp_script),
stdout=PIPE)
'--noconfirm',
'--windowed',
'--noupx',
'--additional-hooks-dir', self.hooks_path,
'--runtime-hook', os.path.join(self.hooks_path, 'rthook_openlp_pyqt4.py'),
'--log-level=ERROR',
'-o', self.branch_path,
'-i', self.win32_icon,
'-p', self.branch_path,
'-n', 'OpenLP',
self.openlp_script),
stdout=PIPE)
output = pyinstaller.communicate()[0]
code = pyinstaller.wait()
if code != 0:
@ -357,11 +338,9 @@ class WindowsBuilder(object):
raise Exception('Error running bzr log')
output_ascii = str(output, errors='ignore')
latest = output_ascii.split(':')[0]
version_string = latest == revision and tag or \
'%s-bzr%s' % (tag, latest)
version_string = latest == revision and tag or '%s-bzr%s' % (tag, latest)
# Save decimal version in case we need to do a portable build.
self.version = latest == revision and tag or\
'%s.%s' % (tag, latest)
self.version = latest == revision and tag or '%s.%s' % (tag, latest)
version_file = open(os.path.join(self.dist_path, '.version'), 'w')
version_file.write(version_string)
version_file.close()
@ -377,12 +356,11 @@ class WindowsBuilder(object):
for root, dirs, files in os.walk(source):
for filename in files:
if not filename.endswith('.pyc'):
dest_path = os.path.join(dest, root[len(source)+1:])
dest_path = os.path.join(dest, root[len(source) + 1:])
if not os.path.exists(dest_path):
os.makedirs(dest_path)
self._print_verbose('... %s', filename)
copy(os.path.join(root, filename),
os.path.join(dest_path, filename))
copy(os.path.join(root, filename), os.path.join(dest_path, filename))
def copy_media_player(self):
"""
@ -394,12 +372,11 @@ class WindowsBuilder(object):
for root, dirs, files in os.walk(source):
for filename in files:
if not filename.endswith('.pyc'):
dest_path = os.path.join(dest, root[len(source)+1:])
dest_path = os.path.join(dest, root[len(source) + 1:])
if not os.path.exists(dest_path):
os.makedirs(dest_path)
self._print_verbose('... %s', filename)
copy(os.path.join(root, filename),
os.path.join(dest_path, filename))
copy(os.path.join(root, filename), os.path.join(dest_path, filename))
def copy_windows_files(self):
"""
@ -407,17 +384,14 @@ class WindowsBuilder(object):
"""
self._print('Copying extra files for Windows...')
self._print_verbose('... OpenLP.ico')
copy(os.path.join(self.script_path, 'OpenLP.ico'),
os.path.join(self.dist_path, 'OpenLP.ico'))
copy(os.path.join(self.script_path, 'OpenLP.ico'), os.path.join(self.dist_path, 'OpenLP.ico'))
self._print_verbose('... LICENSE.txt')
copy(os.path.join(self.script_path, 'LICENSE.txt'),
os.path.join(self.dist_path, 'LICENSE.txt'))
copy(os.path.join(self.script_path, 'LICENSE.txt'), os.path.join(self.dist_path, 'LICENSE.txt'))
self._print_verbose('... psvince.dll')
copy(self.psvince, os.path.join(self.dist_path, 'psvince.dll'))
if os.path.isfile(os.path.join(self.helpfile_path, 'OpenLP.chm')):
self._print_verbose('... OpenLP.chm')
copy(os.path.join(self.helpfile_path, 'OpenLP.chm'),
os.path.join(self.dist_path, 'OpenLP.chm'))
copy(os.path.join(self.helpfile_path, 'OpenLP.chm'), os.path.join(self.dist_path, 'OpenLP.chm'))
else:
self._print('... WARNING: Windows help file not found')
@ -435,8 +409,7 @@ class WindowsBuilder(object):
username = self.config.get('transifex', 'username')
password = self.config.get('transifex', 'password')
os.chdir(os.path.split(self.i18n_utils)[0])
translation_utils = Popen([self.python, self.i18n_utils, '-qdpu',
'-U', username, '-P', password])
translation_utils = Popen([self.python, self.i18n_utils, '-qdpu', '-U', username, '-P', password])
code = translation_utils.wait()
if code != 0:
raise Exception('Error running translation_utils.py')
@ -453,36 +426,29 @@ class WindowsBuilder(object):
if file.endswith('.ts'):
self._print_verbose('... %s', file)
source_path = os.path.join(self.i18n_path, file)
dest_path = os.path.join(self.dist_path, 'i18n',
file.replace('.ts', '.qm'))
lconvert = Popen((self.lrelease, '-compress', '-silent',
source_path, '-qm', dest_path))
dest_path = os.path.join(self.dist_path, 'i18n', file.replace('.ts', '.qm'))
lconvert = Popen((self.lrelease, '-compress', '-silent', source_path, '-qm', dest_path))
code = lconvert.wait()
if code != 0:
raise Exception('Error running lconvert on %s' % \
source_path)
raise Exception('Error running lconvert on %s' % source_path)
self._print('Copying qm files...')
source = os.path.join(self.site_packages, 'PyQt4', 'translations')
files = os.listdir(source)
for filename in files:
if filename.startswith('qt_') and filename.endswith('.qm') and \
len(filename) == 8:
if filename.startswith('qt_') and filename.endswith('.qm') and len(filename) == 8:
self._print_verbose('... %s', filename)
copy(os.path.join(source, filename),
os.path.join(self.dist_path, 'i18n', filename))
copy(os.path.join(source, filename), os.path.join(self.dist_path, 'i18n', filename))
def run_sphinx(self):
"""
Run Sphinx to build an HTML Help project.
"""
self._print('Deleting previous help manual build... %s',
self.manual_build_path)
self._print('Deleting previous help manual build... %s', self.manual_build_path)
if os.path.exists(self.manual_build_path):
rmtree(self.manual_build_path)
self._print('Running Sphinx...')
os.chdir(self.manual_path)
sphinx = Popen((self.sphinx, '-b', 'htmlhelp', '-d',
'build/doctrees', 'source', 'build/htmlhelp'), stdout=PIPE)
sphinx = Popen((self.sphinx, '-b', 'htmlhelp', '-d', 'build/doctrees', 'source', 'build/htmlhelp'), stdout=PIPE)
output, error = sphinx.communicate()
code = sphinx.wait()
if code != 0:
@ -508,12 +474,10 @@ class WindowsBuilder(object):
Create an InnoSetup file pointing to the branch being built.
"""
self._print('Creating Inno Setup file...')
input = open(os.path.join(self.script_path,
'OpenLP-2.0.iss.default'), 'r').read()
input = open(os.path.join(self.script_path, 'OpenLP-2.0.iss.default'), 'r').read()
output = input.replace('%(branch)s', self.branch_path)
output = output.replace('%(display_version)s', self.version)
outfile = open(os.path.join(self.script_path,
'OpenLP-2.0.iss'), 'w')
outfile = open(os.path.join(self.script_path, 'OpenLP-2.0.iss'), 'w')
outfile.write(output)
outfile.close()
@ -523,12 +487,10 @@ class WindowsBuilder(object):
missing subdirs
"""
self._print(' Checking PortableApps directory structure...')
launcher_path = os.path.join(self.portable_path, 'App',
'Appinfo', 'Launcher')
launcher_path = os.path.join(self.portable_path, 'App', 'Appinfo', 'Launcher')
if not os.path.exists(launcher_path):
os.makedirs(launcher_path)
settings_path = os.path.join(self.portable_path, 'Data',
'Settings')
settings_path = os.path.join(self.portable_path, 'Data', 'Settings')
if not os.path.exists(settings_path):
os.makedirs(settings_path)
@ -537,13 +499,11 @@ class WindowsBuilder(object):
Create a Portabbleapps appinfo.ini file.
"""
self._print(' Creating PortableApps appinfo file ...')
portable_version = self.version + '.0' * (3-self.version.count('.'))
input = open(os.path.join(self.script_path,
'appinfo.ini.default'), 'r').read()
portable_version = self.version + '.0' * (3 - self.version.count('.'))
input = open(os.path.join(self.script_path, 'appinfo.ini.default'), 'r').read()
output = input.replace('%(display_version)s', self.version)
output = output.replace('%(package_version)s', portable_version)
outfile = open(os.path.join(self.portable_path, 'App',
'Appinfo', 'appinfo.ini'), 'w')
outfile = open(os.path.join(self.portable_path, 'App', 'Appinfo', 'appinfo.ini'), 'w')
outfile.write(output)
outfile.close()
@ -553,8 +513,7 @@ class WindowsBuilder(object):
"""
self._print('Running Inno Setup...')
os.chdir(self.script_path)
innosetup = Popen((self.innosetup,
os.path.join(self.script_path, 'OpenLP-2.0.iss'), '/q'))
innosetup = Popen((self.innosetup, os.path.join(self.script_path, 'OpenLP-2.0.iss'), '/q'))
code = innosetup.wait()
if code != 0:
raise Exception('Error running Inno Setup')
@ -574,8 +533,7 @@ class WindowsBuilder(object):
self._print(' Creating PortableApps build directory')
# Copy the contents of the OpenLPPortable directory to the portable
# build directory.
dir_util.copy_tree(os.path.join(self.script_path, 'OpenLPPortable'),
self.portable_path)
dir_util.copy_tree(os.path.join(self.script_path, 'OpenLPPortable'), self.portable_path)
self.check_portableapp_directory()
self.create_portableapps_appinfo_file()
# Copy distribution files to portableapp build directory.
@ -584,27 +542,22 @@ class WindowsBuilder(object):
dir_util.copy_tree(self.dist_path, portable_app_path)
# Copy help files to portableapp build directory.
self._print(' Copying help files')
dir_util.copy_tree(self.helpfile_path,
os.path.join(portable_app_path, 'help'))
dir_util.copy_tree(self.helpfile_path, os.path.join(portable_app_path, 'help'))
# Build the launcher.
self._print(' Building PortableApps Launcher')
portableapps = Popen((self.portablelauncher, self.portable_path),
stdout=PIPE)
portableapps = Popen((self.portablelauncher, self.portable_path), stdout=PIPE)
code = portableapps.wait()
if code != 0:
raise Exception('Error creating PortableAppa Launcher')
# Build the portable installer.
self._print(' Building PortableApps Installer')
portableapps = Popen((self.portableinstaller, self.portable_path),
stdout=PIPE)
portableapps = Popen((self.portableinstaller, self.portable_path), stdout=PIPE)
code = portableapps.wait()
if code != 0:
raise Exception('Error running PortableApps Installer')
portable_app = os.path.abspath(os.path.join(self.portable_path, '..',
'OpenLPPortable_%s.paf.exe' % self.version))
portable_app = os.path.abspath(os.path.join(self.portable_path, '..', 'OpenLPPortable_%s.paf.exe' % self.version))
if os.path.exists(portable_app):
move(portable_app, os.path.abspath(
os.path.join(self.dist_path, '..')))
move(portable_app, os.path.abspath(os.path.join(self.dist_path, '..')))
self._print(' PortableApp build complete')
else:
raise Exception('PortableApp failed to build')
@ -614,41 +567,32 @@ class WindowsBuilder(object):
Build the PowerPoint Viewer DLL using Visual Studio.
"""
self._print('Building PPTVIEWLIB.DLL...')
vcbuild = Popen((self.vcbuild, '/rebuild',
os.path.join(self.pptviewlib_path, 'pptviewlib.vcproj'),
'Release|Win32'))
vcbuild = Popen((self.vcbuild, '/rebuild', os.path.join(self.pptviewlib_path, 'pptviewlib.vcproj'),
'Release|Win32'))
code = vcbuild.wait()
if code != 0:
raise Exception('Error building pptviewlib.dll')
copy(os.path.join(self.pptviewlib_path, 'Release',
'pptviewlib.dll'), self.pptviewlib_path)
copy(os.path.join(self.pptviewlib_path, 'Release', 'pptviewlib.dll'), self.pptviewlib_path)
def main(self):
"""
The main function to run the Windows builder.
"""
self._print_verbose('OpenLP main script: ......%s',
self.openlp_script)
self._print_verbose('Script path: .............%s',
os.path.split(os.path.abspath(__file__))[0])
self._print_verbose('OpenLP main script: ......%s', self.openlp_script)
self._print_verbose('Script path: .............%s', os.path.split(os.path.abspath(__file__))[0])
self._print_verbose('Branch path: .............%s', self.branch_path)
self._print_verbose('Source path: .............%s', self.source_path)
self._print_verbose('Dist path: ...............%s', self.dist_path)
self._print_verbose('Portable path: ...........%s',
self.portable_path)
self._print_verbose('Portable path: ...........%s', self.portable_path)
self._print_verbose('PyInstaller: .............%s', self.pyinstaller)
self._print_verbose('Documentation branch path:%s', self.docs_path)
self._print_verbose('Help file build path: ....%s',
self.helpfile_path)
self._print_verbose('Help file build path: ....%s', self.helpfile_path)
self._print_verbose('Inno Setup path: .........%s', self.innosetup)
self._print_verbose('PortableApp Launcher......%s',
self.portablelauncher)
self._print_verbose('PortableApp Installer.....%s',
self.portableinstaller)
self._print_verbose('PortableApp Launcher......%s', self.portablelauncher)
self._print_verbose('PortableApp Installer.....%s', self.portableinstaller)
self._print_verbose('Windows resources: .......%s', self.winres_path)
self._print_verbose('VCBuild path: ............%s', self.vcbuild)
self._print_verbose('PPTVIEWLIB path: .........%s',
self.pptviewlib_path)
self._print_verbose('PPTVIEWLIB path: .........%s', self.pptviewlib_path)
self._print_verbose('')
if not self.args.skip_update:
self.update_code()
@ -675,5 +619,6 @@ class WindowsBuilder(object):
self.run_portableapp_builder()
self._print('Done.')
if __name__ == '__main__':
WindowsBuilder().main()