← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~springermac/openlp/packaging-py3 into lp:openlp/packaging

 

Jonathan Springer has proposed merging lp:~springermac/openlp/packaging-py3 into lp:openlp/packaging.

Requested reviews:
  OpenLP Core (openlp-core)

For more details, see:
https://code.launchpad.net/~springermac/openlp/packaging-py3/+merge/218504

Ran 2to3 and changed line lengths to 120 characters.
Also fixed a few python3 issues and add code to include the default theme's json file.
-- 
https://code.launchpad.net/~springermac/openlp/packaging-py3/+merge/218504
Your team OpenLP Core is requested to review the proposed merge of lp:~springermac/openlp/packaging-py3 into lp:openlp/packaging.
=== modified file 'osx/macosx-builder.py'
--- osx/macosx-builder.py	2013-02-03 14:56:42 +0000
+++ osx/macosx-builder.py	2014-05-06 20:08:08 +0000
@@ -118,7 +118,7 @@
 import sys
 from shutil import copy, rmtree
 from subprocess import Popen, PIPE
-from ConfigParser import SafeConfigParser as ConfigParser
+from configparser import ConfigParser
 from argparse import ArgumentParser
 
 
@@ -128,7 +128,7 @@
     """
     for path in os.environ["PATH"].split(os.pathsep):
         if os.access(os.path.join(path, command), os.X_OK):
-            print "%s/%s" % (path, command)
+            print("%s/%s" % (path, command))
             return "%s/%s" % (path, command)
 
 
@@ -137,6 +137,7 @@
     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()
@@ -150,7 +151,7 @@
         """
         if len(args) > 0:
             text = text % tuple(args)
-        print text
+        print(text)
 
     def _print_verbose(self, text, *args):
         """
@@ -173,7 +174,7 @@
             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,16 +185,15 @@
                 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'],
-                u'Detecting mount points failed.')
-        pl = plistlib.readPlistFromString(output)
+        output = self._run_command([self.hdiutil, 'info', '-plist'], 'Detecting mount points failed.')
+        pl = plistlib.readPlistFromBytes(output)
         for image in pl['images']:
             for se in image['system-entities']:
                 if se.get('mount-point'):
@@ -207,33 +207,25 @@
         """
         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):
@@ -241,10 +233,8 @@
         Read the configuration from the configuration file.
         """
         self.config = ConfigParser(defaults={
-            u'here': self.script_path,
-            u'projects': os.path.abspath(os.path.join(self.script_path,
-                '..', '..')),
-        })
+            'here': 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):
@@ -258,14 +248,13 @@
         """
         Set up the paths to the executables we use.
         """
-        self.sphinx = _which(self.config.get(u'executables', u'sphinx'))
-        self.pyinstaller = os.path.abspath(
-            self.config.get(u'executables', u'pyinstaller'))
-        self.lrelease = _which(self.config.get(u'executables', u'lrelease'))
-        self.diskutil = _which(self.config.get(u'executables', u'diskutil'))
-        self.hdiutil = _which(self.config.get(u'executables', u'hdiutil'))
-        self.osascript = _which(self.config.get(u'executables', u'osascript'))
-        
+        self.sphinx = _which(self.config.get('executables', 'sphinx'))
+        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.
@@ -273,168 +262,172 @@
         if self.args.branch:
             self.branch_path = os.path.abspath(self.args.branch)
         else:
-            self.branch_path = self.config.get(u'paths', u'branch')
+            self.branch_path = self.config.get('paths', 'branch')
         if self.args.docs:
             self.docs_path = os.path.abspath(self.args.docs)
         else:
-            self.docs_path = self.config.get(u'paths', u'documentation')
+            self.docs_path = self.config.get('paths', 'documentation')
 
-        self.openlp_script = os.path.abspath(
-            os.path.join(self.branch_path, u'openlp.py'))
-        self.hooks_path = os.path.abspath(os.path.join(
-            self.branch_path, self.config.get(u'paths', u'hooks')))
-        self.mac_icon = os.path.abspath(
-            self.config.get(u'paths', u'macicon'))
-        self.bundle_info = os.path.abspath(
-            self.config.get(u'paths', u'bundleinfo'))
-        self.dmg_background_img = os.path.abspath(
-            self.config.get(u'paths', u'dmg_background'))
-        self.i18n_utils = os.path.join(self.branch_path, u'scripts',
-            u'translation_utils.py')
-        self.source_path = os.path.join(self.branch_path, u'openlp')
-        self.manual_path = os.path.join(self.docs_path, u'manual')
-        self.manual_build_path = os.path.join(self.manual_path, u'build')
-        self.i18n_path = os.path.join(self.branch_path, u'resources', u'i18n')
-        self.build_path = os.path.join(self.branch_path, u'build')
-        self.dist_app_path = os.path.join(self.branch_path, u'dist', u'OpenLP.app')
-        self.dist_path = os.path.join(self.branch_path, u'dist', u'OpenLP.app',
-                'Contents', 'MacOS')
+        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')
 
         # 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):
         """
         Update the code in the branch.
         """
         os.chdir(self.branch_path)
-        self._print(u'Reverting any changes to the code...')
-        bzr = Popen((u'bzr', u'revert'), stdout=PIPE)
-        output = bzr.communicate()[0]
-        code = bzr.wait()
-        if code != 0:
-            self._print(output)
-            raise Exception(u'Error reverting the code')
-        self._print(u'Updating the code...')
-        bzr = Popen((u'bzr', u'update'), stdout=PIPE)
-        output = bzr.communicate()[0]
-        code = bzr.wait()
-        if code != 0:
-            self._print(output)
-            raise Exception(u'Error updating the code')
+        self._print('Reverting any changes to the code...')
+        bzr = Popen(('bzr', 'revert'), stdout=PIPE)
+        output = bzr.communicate()[0]
+        code = bzr.wait()
+        if code != 0:
+            self._print(output)
+            raise Exception('Error reverting the code')
+        self._print('Updating the code...')
+        bzr = Popen(('bzr', 'update'), stdout=PIPE)
+        output = bzr.communicate()[0]
+        code = bzr.wait()
+        if code != 0:
+            self._print(output)
+            raise Exception('Error updating the code')
 
     def run_pyinstaller(self):
         """
         Run PyInstaller on the branch to build an executable.
         """
-        self._print(u'Running PyInstaller...')
+        self._print('Running PyInstaller...')
         os.chdir(self.branch_path)
         pyinstaller = Popen((self.python,
-            self.pyinstaller,
-            u'--noconfirm',
-            u'--windowed',
-            u'--noupx',
-            u'--additional-hooks-dir', self.hooks_path,
-            u'--runtime-hook', os.path.join(self.hooks_path, 'rthook_openlp_pyqt4.py'),
-            u'--log-level=ERROR',
-            u'-o', self.branch_path,
-            #u'-i', self.mac_icon,
-            u'-p', self.branch_path,
-            u'-n', u'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',
+                             # '--distpath', self.branch_path,
+                             # '-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:
             self._print(output)
-            raise Exception(u'Error running PyInstaller')
+            raise Exception('Error running PyInstaller')
 
     def write_version_file(self):
         """
         Write the version number to a file for reading once installed.
         """
-        self._print(u'Writing version file...')
+        self._print('Writing version file...')
         os.chdir(self.branch_path)
-        bzr = Popen((u'bzr', u'tags', u'--sort', u'time'), stdout=PIPE)
+        bzr = Popen(('bzr', 'tags'), stdout=PIPE)
         output = bzr.communicate()[0]
         code = bzr.wait()
         if code != 0:
-            raise Exception(u'Error running bzr tags')
+            raise Exception('Error running bzr tags')
         lines = output.splitlines()
         if len(lines) == 0:
-            tag = u'0.0.0'
-            revision = u'0'
+            tag = '0.0.0'
+            revision = '0'
         else:
-            tag, revision = lines[-1].split()
-        bzr = Popen((u'bzr', u'log', u'--line', u'-r', u'-1'), stdout=PIPE)
+            tag, revision = lines[-1].decode('utf-8').split()
+        bzr = Popen(('bzr', 'log', '--line', '-r', '-1'), stdout=PIPE)
         output, error = bzr.communicate()
         code = bzr.wait()
         if code != 0:
-            raise Exception(u'Error running bzr log')
-        output_ascii = unicode(output, errors=u'ignore')
-        latest = output_ascii.split(u':')[0]
-        self.version_string = u'%s-bzr%s' % (tag, latest)
+            raise Exception('Error running bzr log')
+        latest = output.decode('utf-8').split(':')[0]
+        self.version_string = '%s-bzr%s' % (tag, latest)
         self.version_tag = tag
-        version_file = open(os.path.join(self.dist_path, u'.version'), u'w')
+        version_file = open(os.path.join(self.dist_path, '.version'), 'w')
         # Release version does not contain revision in .dmg name.
         if self.args.devel:
-            version_file.write(self.version_string)
+            version_file.write(str(self.version_string))
         else:
-            version_file.write(self.version_tag)
+            version_file.write(str(self.version_tag))
         version_file.close()
 
+    def copy_default_theme(self):
+        """
+        Copy the default theme to the correct directory for OpenLP.
+        """
+        self._print('Copying default theme...')
+        source = os.path.join(self.source_path, 'core', 'lib', 'json')
+        dest = os.path.join(self.dist_path, 'core', 'lib', 'json')
+        for root, dirs, files in os.walk(source):
+            for filename in files:
+                if filename.endswith('.json'):
+                    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))
+
     def copy_plugins(self):
         """
         Copy all the plugins to the correct directory so that OpenLP sees that
         it has plugins.
         """
-        self._print(u'Copying plugins...')
-        source = os.path.join(self.source_path, u'plugins')
-        dest = os.path.join(self.dist_path, u'plugins')
+        self._print('Copying plugins...')
+        source = os.path.join(self.source_path, 'plugins')
+        dest = os.path.join(self.dist_path, 'plugins')
         for root, dirs, files in os.walk(source):
             for filename in files:
-                if not filename.endswith(u'.pyc'):
-                    dest_path = os.path.join(dest, root[len(source)+1:])
+                if not filename.endswith('.pyc'):
+                    dest_path = os.path.join(dest, root[len(source) + 1:])
                     if not os.path.exists(dest_path):
                         os.makedirs(dest_path)
-                    self._print_verbose(u'... %s', filename)
-                    copy(os.path.join(root, filename),
-                        os.path.join(dest_path, filename))
+                    self._print_verbose('... %s', filename)
+                    copy(os.path.join(root, filename), os.path.join(dest_path, filename))
 
     def copy_media_player(self):
         """
         Copy the media players to the correct directory for OpenLP.
         """
-        self._print(u'Copying media player...')
-        source = os.path.join(self.source_path, u'core', u'ui', u'media')
-        dest = os.path.join(self.dist_path, u'core', u'ui', u'media')
+        self._print('Copying media player...')
+        source = os.path.join(self.source_path, 'core', 'ui', 'media')
+        dest = os.path.join(self.dist_path, 'core', 'ui', 'media')
         for root, dirs, files in os.walk(source):
             for filename in files:
-                if not filename.endswith(u'.pyc'):
-                    dest_path = os.path.join(dest, root[len(source)+1:])
+                if not filename.endswith('.pyc'):
+                    dest_path = os.path.join(dest, root[len(source) + 1:])
                     if not os.path.exists(dest_path):
                         os.makedirs(dest_path)
-                    self._print_verbose(u'... %s', filename)
-                    copy(os.path.join(root, filename),
-                        os.path.join(dest_path, filename))
+                    self._print_verbose('... %s', 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, u'r')
-        fw = open(os.path.join(self.dist_app_path, 
-            'Contents', os.path.basename(self.bundle_info)), 'w')
+        fr = open(self.bundle_info, 'r')
+        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()
 
@@ -442,118 +435,104 @@
         """
         Copy all the OSX-specific files.
         """
-        self._print(u'Copying extra files for Mac OS X...')
-        self._print_verbose(u'... LICENSE.txt')
-        copy(os.path.join(self.script_path, u'LICENSE.txt'),
-            os.path.join(self.dist_path, u'LICENSE.txt'))
+        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'))
 
     def update_translations(self):
         """
         Update the translations.
         """
-        self._print(u'Updating translations...')
+        self._print('Updating translations...')
         if not self.config.has_section('transifex'):
-            raise Exception(u'No section named "transifex" found.')
+            raise Exception('No section named "transifex" found.')
         if not self.config.has_option('transifex', 'username'):
-            raise Exception(u'No option named "username" found.')
+            raise Exception('No option named "username" found.')
         if not self.config.has_option('transifex', 'password'):
-            raise Exception(u'No option named "password" found.')
+            raise Exception('No option named "password" found.')
         if self.args.transifex_user:
             username = self.args.transifex_user
         else:
-            username = self.config.get(u'transifex', u'username')
+            username = self.config.get('transifex', 'username')
         if self.args.transifex_pass:
             password = self.args.transifex_pass
         else:
-            password = self.config.get(u'transifex', u'password')
+            password = self.config.get('transifex', 'password')
         os.chdir(os.path.split(self.i18n_utils)[0])
-        translation_utils = Popen([self.python, self.i18n_utils, u'-qdpu',
-            u'-U', username, u'-P', password])
+        translation_utils = Popen([self.python, self.i18n_utils, '-qdpu', '-U', username, '-P', password])
         code = translation_utils.wait()
         if code != 0:
-            raise Exception(u'Error running translation_utils.py')
+            raise Exception('Error running translation_utils.py')
 
     def compile_translations(self):
         """
         Compile the translations for Qt.
         """
-        self._print(u'Compiling translations...')
+        self._print('Compiling translations...')
         files = os.listdir(self.i18n_path)
-        if not os.path.exists(os.path.join(self.dist_path, u'i18n')):
-            os.makedirs(os.path.join(self.dist_path, u'i18n'))
+        if not os.path.exists(os.path.join(self.dist_path, 'i18n')):
+            os.makedirs(os.path.join(self.dist_path, 'i18n'))
         for file in files:
-            if file.endswith(u'.ts'):
-                self._print_verbose(u'... %s', file)
+            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, u'i18n',
-                    file.replace(u'.ts', u'.qm'))
-                lconvert = Popen((self.lrelease, u'-compress', u'-silent',
-                    source_path, u'-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(u'Error running lconvert on %s' % \
-                        source_path)
-        self._print(u'Copying qm files...')
+                    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(u'qt_') and filename.endswith(u'.qm') and \
-                len(filename) == 8:
-                self._print_verbose(u'... %s', filename)
-                copy(os.path.join(source, filename),
-                    os.path.join(self.dist_path, u'i18n', filename))
+            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))
 
     def run_sphinx(self):
         """
         Run Sphinx to build an HTML Help project.
         """
-        self._print(u'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(u'Running Sphinx...')
+        self._print('Running Sphinx...')
         os.chdir(self.manual_path)
-        sphinx = Popen((self.sphinx, u'-b', u'htmlhelp', u'-d',
-            u'build/doctrees', u'source', u'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:
             self._print(output)
-            raise Exception(u'Error running Sphinx')
+            raise Exception('Error running Sphinx')
 
     def create_dmg_file(self):
         """
         Create .dmg file.
         """
-        self._print(u'Creating dmg file...')
+        self._print('Creating dmg file...')
 
         # Release version does not contain revision in .dmg name.
         if self.args.devel:
-            dmg_name = 'OpenLP-' + self.version_string + '.dmg'
+            dmg_name = 'OpenLP-' + str(self.version_string) + '.dmg'
         else:
-            dmg_name = 'OpenLP-' + self.version_tag + '.dmg'
+            dmg_name = 'OpenLP-' + str(self.version_tag) + '.dmg'
 
         dmg_file = os.path.join(self.branch_path, 'build', dmg_name)
         # Remove dmg if it exists.
         if os.path.exists(dmg_file):
             os.remove(dmg_file)
-        # Create empty dmg file. 
+        # Create empty dmg file.
         size = self._get_directory_size(self.dist_app_path)  # in bytes.
         size = size / (1024 * 1024)  # Convert to megabytes.
         size += 10  # Additional space in .dmg for other files.
-        self._print(u'... dmg disk size: %s' % size)
-        self._run_command([self.hdiutil, 'create', dmg_file, 
-            '-ov', '-megabytes', str(size), 
-            '-fs', 'HFS+', '-volname', 'OpenLP'],
-            u'Could not create dmg file.'
-        )
+        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.')
 
         # Mount empty dmg file.
         old_mounts = self._get_mountpoints()
-        self._print(u'... mounting the dmg file: %s' % dmg_file)
-        self._run_command([self.hdiutil, 'attach', dmg_file],
-            u'Could not mount dmg file, cannot continue.'
-        )
+        self._print('... mounting the dmg file: %s' % dmg_file)
+        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.
@@ -561,25 +540,19 @@
 
         # Copy OpenLP.app and other files to .dmg
         # TODO more reliable way to determine dmg_volume_path
-        self._print(u'... Copying the app to the dmg: ' + dmg_volume_path)
-        self._run_command(['cp', '-r', self.dist_app_path,
-            dmg_volume_path],
-            u'Could not copy app bundle, dmg creation failed.'
-        )
+        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.')
 
         # 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],
-            u'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,15 +564,13 @@
             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')],
-                u'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))
 
-        ## Unmount dmg file.
+        # Unmount dmg file.
         self._print('... unmounting the dmg.')
         # Sometimes it could happen that OSX Finder is blocking umount.
         # We need to find this process and kill it.
@@ -609,50 +580,42 @@
                 blocking_proc_pid = int(output.split()[0])
                 os.kill(int(blocking_proc_pid), signal.SIGKILL)
         except Exception as e:
-            print str(e)
+            print(str(e))
             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],
-            u'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. 
+        # 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'))
+            p.communicate(bytes(f.read() % (dmg_volume_name, 'OpenLP'), 'utf-8'))
             f.close()
             result = p.returncode
             if (result != 0):
@@ -664,33 +627,32 @@
         """
         The main function to run the Mac OS X builder.
         """
-        self._print_verbose(u'OpenLP main script: ......%s',
-            self.openlp_script)
-        self._print_verbose(u'Script path: .............%s',
-            os.path.split(os.path.abspath(__file__))[0])
-        self._print_verbose(u'Branch path: .............%s', self.branch_path)
-        self._print_verbose(u'Source path: .............%s', self.source_path)
-        self._print_verbose(u'"dist.app" path: .........%s', self.dist_app_path)
-        self._print_verbose(u'"dist" path: .............%s', self.dist_path)
-        self._print_verbose(u'"hooks" path: ............%s', self.hooks_path)
-        self._print_verbose(u'PyInstaller: .............%s', self.pyinstaller)
-        self._print_verbose(u'Documentation branch path:%s', self.docs_path)
-        self._print_verbose(u'')
+        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)
+        self._print_verbose('"dist" path: .............%s', self.dist_path)
+        self._print_verbose('"hooks" path: ............%s', self.hooks_path)
+        self._print_verbose('PyInstaller: .............%s', self.pyinstaller)
+        self._print_verbose('Documentation branch path:%s', self.docs_path)
+        self._print_verbose('')
         if not self.args.skip_update:
             self.update_code()
         self.run_pyinstaller()
         self.write_version_file()
         self.copy_mac_bundle_files()
+        self.copy_default_theme()
         self.copy_plugins()
         self.copy_media_player()
         # TODO creating help on Mac
         if os.path.exists(self.manual_path):
             self.run_sphinx()
         else:
-            self._print(u'')
-            self._print(u'WARNING: Documentation trunk not found. Mac OS X')
-            self._print(u'         Help file will not be included in build')
-            self._print(u'')
+            self._print('')
+            self._print('WARNING: Documentation trunk not found. Mac OS X')
+            self._print('         Help file will not be included in build')
+            self._print('')
         self.copy_macosx_files()
         if not self.args.skip_translations:
             if self.args.update_translations:
@@ -698,9 +660,9 @@
             self.compile_translations()
         self.create_dmg_file()
 
-        self._print(u'Done.')
+        self._print('Done.')
         raise SystemExit()
 
 
-if __name__ == u'__main__':
+if __name__ == '__main__':
     MacosxBuilder().main()

=== modified file 'pyinstaller-hooks/rthook_openlp_pyqt4.py'
--- pyinstaller-hooks/rthook_openlp_pyqt4.py	2013-01-01 01:04:23 +0000
+++ pyinstaller-hooks/rthook_openlp_pyqt4.py	2014-05-06 20:08:08 +0000
@@ -41,10 +41,10 @@
 
 import sip
 
-sip.setapi(u'QDate', 2)
-sip.setapi(u'QDateTime', 2)
-sip.setapi(u'QString', 2)
-sip.setapi(u'QTextStream', 2)
-sip.setapi(u'QTime', 2)
-sip.setapi(u'QUrl', 2)
-sip.setapi(u'QVariant', 2)
+sip.setapi('QDate', 2)
+sip.setapi('QDateTime', 2)
+sip.setapi('QString', 2)
+sip.setapi('QTextStream', 2)
+sip.setapi('QTime', 2)
+sip.setapi('QUrl', 2)
+sip.setapi('QVariant', 2)

=== modified file 'windows/windows-builder.py'
--- windows/windows-builder.py	2013-02-03 14:56:42 +0000
+++ windows/windows-builder.py	2014-05-06 20:08:08 +0000
@@ -129,7 +129,7 @@
 from shutil import copy, rmtree, move
 from distutils import dir_util
 from subprocess import Popen, PIPE
-from ConfigParser import SafeConfigParser as ConfigParser
+from configparser import ConfigParser
 from argparse import ArgumentParser
 
 
@@ -138,13 +138,14 @@
     The :class:`WindowsBuilder` class encapsulates everything that is needed
     to build a Windows installer.
     """
+
     def __init__(self):
         self.setup_args()
         self.setup_system_paths()
         self.read_config()
         self.setup_executables()
         self.setup_paths()
-        self.version = u''
+        self.version = ''
 
     def _print(self, text, *args):
         """
@@ -152,7 +153,7 @@
         """
         if len(args) > 0:
             text = text % tuple(args)
-        print text
+        print(text)
 
     def _print_verbose(self, text, *args):
         """
@@ -167,26 +168,20 @@
         """
         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):
@@ -194,10 +189,10 @@
         Read the configuration from the configuration file.
         """
         self.config = ConfigParser(defaults={
-            u'pyroot': self.python_root,
-            u'progfiles': self.program_files,
-            u'sitepackages': self.site_packages,
-            u'here': self.script_path
+            'pyroot': self.python_root,
+            'progfiles': self.program_files,
+            'sitepackages': self.site_packages,
+            'here': self.script_path
         })
         self.config.read(os.path.abspath(self.args.config))
 
@@ -208,40 +203,29 @@
         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,
-            u'Lib', u'site-packages')
-        self.program_files = os.getenv(u'PROGRAMFILES')
+        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(u'executables', u'innosetup'))
-        self.sphinx = os.path.abspath(
-            self.config.get(u'executables', u'sphinx'))
-        self.pyinstaller = os.path.abspath(
-            self.config.get(u'executables', u'pyinstaller'))
-        self.vcbuild = os.path.abspath(
-            self.config.get(u'executables', u'vcbuild'))
-        self.hhc = os.path.abspath(
-            self.config.get(u'executables', u'htmlhelp'))
-        self.psvince = os.path.abspath(
-            self.config.get(u'executables', u'psvince'))
-        self.portableinstaller = os.path.abspath(
-            self.config.get(u'executables', u'portableinstaller'))
-        self.portablelauncher = os.path.abspath(
-            self.config.get(u'executables', u'portablelauncher'))
-        if os.path.exists(os.path.join(self.site_packages, u'PyQt4', u'bin')):
+        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, u'PyQt4',
-                u'bin', u'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, u'PyQt4',
-                u'lrelease.exe')
+            self.lrelease = os.path.join(self.site_packages, 'PyQt4', 'lrelease.exe')
 
     def setup_paths(self):
         """
@@ -250,270 +234,263 @@
         if self.args.branch:
             branch_path = self.args.branch
         else:
-            branch_path = self.config.get(u'paths', u'branch')
+            branch_path = self.config.get('paths', 'branch')
         self.branch_path = os.path.abspath(branch_path)
         if self.args.docs:
             docs_path = self.args.docs
         else:
-            docs_path = self.config.get(u'paths', u'documentation')
+            docs_path = self.config.get('paths', 'documentation')
         self.docs_path = os.path.abspath(docs_path)
         if self.args.portable:
             portable_path = self.args.portable
         else:
             try:
-                portable_path = self.config.get(u'paths', u'portable')
+                portable_path = self.config.get('paths', 'portable')
             except:
-                portable_path = u''
+                portable_path = ''
         if portable_path:
             self.portable_path = os.path.abspath(portable_path)
             self.args.portable = self.portable_path
         else:
-            self.portable_path = u''
-        self.openlp_script = os.path.abspath(
-            os.path.join(branch_path, u'openlp.py'))
-        self.hooks_path = os.path.abspath(self.config.get(u'paths', u'hooks'))
-        self.win32_icon = os.path.abspath(
-            self.config.get(u'paths', u'win32icon'))
-        self.i18n_utils = os.path.join(self.branch_path, u'scripts',
-            u'translation_utils.py')
-        self.source_path = os.path.join(self.branch_path, u'openlp')
-        self.manual_path = os.path.join(self.docs_path, u'manual')
-        self.manual_build_path = os.path.join(self.manual_path, u'build')
-        self.helpfile_path = os.path.join(self.manual_build_path, u'htmlhelp')
-        self.i18n_path = os.path.join(self.branch_path, u'resources', u'i18n')
-        self.winres_path = os.path.join(self.branch_path, u'resources',
-            u'windows')
-        self.build_path = os.path.join(self.branch_path, u'build')
-        self.dist_path = os.path.join(self.branch_path, u'dist', u'OpenLP')
-        self.pptviewlib_path = os.path.join(self.source_path, u'plugins',
-            u'presentations', u'lib', u'pptviewlib')
+            self.portable_path = ''
+        self.openlp_script = os.path.abspath(os.path.join(branch_path, 'openlp.py'))
+        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.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.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')
 
     def update_code(self):
         """
         Update the code in the branch.
         """
         os.chdir(self.branch_path)
-        self._print(u'Reverting any changes to the code...')
-        bzr = Popen((u'bzr', u'revert'), stdout=PIPE)
-        output = bzr.communicate()[0]
-        code = bzr.wait()
-        if code != 0:
-            self._print(output)
-            raise Exception(u'Error reverting the code')
-        self._print(u'Updating the code...')
-        bzr = Popen((u'bzr', u'update'), stdout=PIPE)
-        output = bzr.communicate()[0]
-        code = bzr.wait()
-        if code != 0:
-            self._print(output)
-            raise Exception(u'Error updating the code')
+        self._print('Reverting any changes to the code...')
+        bzr = Popen(('bzr', 'revert'), stdout=PIPE)
+        output = bzr.communicate()[0]
+        code = bzr.wait()
+        if code != 0:
+            self._print(output)
+            raise Exception('Error reverting the code')
+        self._print('Updating the code...')
+        bzr = Popen(('bzr', 'update'), stdout=PIPE)
+        output = bzr.communicate()[0]
+        code = bzr.wait()
+        if code != 0:
+            self._print(output)
+            raise Exception('Error updating the code')
 
     def run_pyinstaller(self):
         """
         Run PyInstaller on the branch to build an executable.
         """
-        self._print(u'Running PyInstaller...')
+        self._print('Running PyInstaller...')
         os.chdir(self.branch_path)
         pyinstaller = Popen((self.python, self.pyinstaller,
-            u'--noconfirm',
-            u'--windowed',
-            u'--noupx',
-            u'--additional-hooks-dir', self.hooks_path,
-            u'--runtime-hook', os.path.join(self.hooks_path, 'rthook_openlp_pyqt4.py'),
-            u'--log-level=ERROR',
-            u'-o', self.branch_path,
-            u'-i', self.win32_icon,
-            u'-p', self.branch_path,
-            u'-n', u'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',
+                             '--distpath', 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:
             self._print(output)
-            raise Exception(u'Error running PyInstaller')
+            raise Exception('Error running PyInstaller')
 
     def write_version_file(self):
         """
         Write the version number to a file for reading once installed.
         """
-        self._print(u'Writing version file...')
+        self._print('Writing version file...')
         os.chdir(self.branch_path)
-        bzr = Popen((u'bzr', u'tags', u'--sort', u'time'), stdout=PIPE)
+        bzr = Popen(('bzr', 'tags'), stdout=PIPE)
         output = bzr.communicate()[0]
         code = bzr.wait()
         if code != 0:
-            raise Exception(u'Error running bzr tags')
+            raise Exception('Error running bzr tags')
         lines = output.splitlines()
         if len(lines) == 0:
-            tag = u'0.0.0'
-            revision = u'0'
+            tag = '0.0.0'
+            revision = '0'
         else:
-            tag, revision = lines[-1].split()
-        bzr = Popen((u'bzr', u'log', u'--line', u'-r', u'-1'), stdout=PIPE)
+            tag, revision = lines[-1].decode('utf-8').split()
+        bzr = Popen(('bzr', 'log', '--line', '-r', '-1'), stdout=PIPE)
         output, error = bzr.communicate()
         code = bzr.wait()
         if code != 0:
-            raise Exception(u'Error running bzr log')
-        output_ascii = unicode(output, errors=u'ignore')
-        latest = output_ascii.split(u':')[0]
-        version_string = latest == revision and tag or \
-            u'%s-bzr%s' % (tag, latest)
+            raise Exception('Error running bzr log')
+        latest = output.decode('utf-8').split(':')[0]
+        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\
-            u'%s.%s' % (tag, latest)
-        version_file = open(os.path.join(self.dist_path, u'.version'), u'w')
-        version_file.write(version_string)
+        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(str(version_string))
         version_file.close()
 
+    def copy_default_theme(self):
+        """
+        Copy the default theme to the correct directory for OpenLP.
+        """
+        self._print('Copying default theme...')
+        source = os.path.join(self.source_path, 'core', 'lib', 'json')
+        dest = os.path.join(self.dist_path, 'core', 'lib', 'json')
+        for root, dirs, files in os.walk(source):
+            for filename in files:
+                if filename.endswith('.json'):
+                    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))
+
     def copy_plugins(self):
         """
         Copy all the plugins to the correct directory so that OpenLP sees that
         it has plugins.
         """
-        self._print(u'Copying plugins...')
-        source = os.path.join(self.source_path, u'plugins')
-        dest = os.path.join(self.dist_path, u'plugins')
+        self._print('Copying plugins...')
+        source = os.path.join(self.source_path, 'plugins')
+        dest = os.path.join(self.dist_path, 'plugins')
         for root, dirs, files in os.walk(source):
             for filename in files:
-                if not filename.endswith(u'.pyc'):
-                    dest_path = os.path.join(dest, root[len(source)+1:])
+                if not filename.endswith('.pyc'):
+                    dest_path = os.path.join(dest, root[len(source) + 1:])
                     if not os.path.exists(dest_path):
                         os.makedirs(dest_path)
-                    self._print_verbose(u'... %s', filename)
-                    copy(os.path.join(root, filename),
-                        os.path.join(dest_path, filename))
+                    self._print_verbose('... %s', filename)
+                    copy(os.path.join(root, filename), os.path.join(dest_path, filename))
 
     def copy_media_player(self):
         """
         Copy the media players to the correct directory for OpenLP.
         """
-        self._print(u'Copying media player...')
-        source = os.path.join(self.source_path, u'core', u'ui', u'media')
-        dest = os.path.join(self.dist_path, u'core', u'ui', u'media')
+        self._print('Copying media player...')
+        source = os.path.join(self.source_path, 'core', 'ui', 'media')
+        dest = os.path.join(self.dist_path, 'core', 'ui', 'media')
         for root, dirs, files in os.walk(source):
             for filename in files:
-                if not filename.endswith(u'.pyc'):
-                    dest_path = os.path.join(dest, root[len(source)+1:])
+                if not filename.endswith('.pyc'):
+                    dest_path = os.path.join(dest, root[len(source) + 1:])
                     if not os.path.exists(dest_path):
                         os.makedirs(dest_path)
-                    self._print_verbose(u'... %s', filename)
-                    copy(os.path.join(root, filename),
-                        os.path.join(dest_path, filename))
+                    self._print_verbose('... %s', filename)
+                    copy(os.path.join(root, filename), os.path.join(dest_path, filename))
 
     def copy_windows_files(self):
         """
         Copy all the Windows-specific files.
         """
-        self._print(u'Copying extra files for Windows...')
-        self._print_verbose(u'... OpenLP.ico')
-        copy(os.path.join(self.script_path, u'OpenLP.ico'),
-            os.path.join(self.dist_path, u'OpenLP.ico'))
-        self._print_verbose(u'... LICENSE.txt')
-        copy(os.path.join(self.script_path, u'LICENSE.txt'),
-            os.path.join(self.dist_path, u'LICENSE.txt'))
-        self._print_verbose(u'... psvince.dll')
-        copy(self.psvince, os.path.join(self.dist_path, u'psvince.dll'))
-        if os.path.isfile(os.path.join(self.helpfile_path, u'OpenLP.chm')):
-            self._print_verbose(u'... OpenLP.chm')
-            copy(os.path.join(self.helpfile_path, u'OpenLP.chm'),
-                os.path.join(self.dist_path, u'OpenLP.chm'))
+        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'))
+        self._print_verbose('... 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'))
         else:
-            self._print(u'... WARNING: Windows help file not found')
+            self._print('... WARNING: Windows help file not found')
 
     def update_translations(self):
         """
         Update the translations.
         """
-        self._print(u'Updating translations...')
+        self._print('Updating translations...')
         if not self.config.has_section('transifex'):
-            raise Exception(u'No section named "transifex" found.')
+            raise Exception('No section named "transifex" found.')
         if not self.config.has_option('transifex', 'username'):
-            raise Exception(u'No option named "username" found.')
+            raise Exception('No option named "username" found.')
         if not self.config.has_option('transifex', 'password'):
-            raise Exception(u'No option named "password" found.')
-        username = self.config.get(u'transifex', u'username')
-        password = self.config.get(u'transifex', u'password')
+            raise Exception('No option named "password" found.')
+        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, u'-qdpu',
-            u'-U', username, u'-P', password])
+        translation_utils = Popen([self.python, self.i18n_utils, '-qdpu', '-U', username, '-P', password])
         code = translation_utils.wait()
         if code != 0:
-            raise Exception(u'Error running translation_utils.py')
+            raise Exception('Error running translation_utils.py')
 
     def compile_translations(self):
         """
         Compile the translations for Qt.
         """
-        self._print(u'Compiling translations...')
+        self._print('Compiling translations...')
         files = os.listdir(self.i18n_path)
-        if not os.path.exists(os.path.join(self.dist_path, u'i18n')):
-            os.makedirs(os.path.join(self.dist_path, u'i18n'))
+        if not os.path.exists(os.path.join(self.dist_path, 'i18n')):
+            os.makedirs(os.path.join(self.dist_path, 'i18n'))
         for file in files:
-            if file.endswith(u'.ts'):
-                self._print_verbose(u'... %s', file)
+            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, u'i18n',
-                    file.replace(u'.ts', u'.qm'))
-                lconvert = Popen((self.lrelease, u'-compress', u'-silent',
-                    source_path, u'-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(u'Error running lconvert on %s' % \
-                        source_path)
-        self._print(u'Copying qm files...')
-        source = os.path.join(self.site_packages, u'PyQt4', u'translations')
+                    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(u'qt_') and filename.endswith(u'.qm') and \
-                len(filename) == 8:
-                self._print_verbose(u'... %s', filename)
-                copy(os.path.join(source, filename),
-                    os.path.join(self.dist_path, u'i18n', filename))
+            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))
 
     def run_sphinx(self):
         """
         Run Sphinx to build an HTML Help project.
         """
-        self._print(u'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(u'Running Sphinx...')
+        self._print('Running Sphinx...')
         os.chdir(self.manual_path)
-        sphinx = Popen((self.sphinx, u'-b', u'htmlhelp', u'-d',
-            u'build/doctrees', u'source', u'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:
             self._print(output)
-            raise Exception(u'Error running Sphinx')
+            raise Exception('Error running Sphinx')
 
     def run_htmlhelp(self):
         """
         Run HTML Help Workshop to convert the Sphinx output into a manual.
         """
-        self._print(u'Running HTML Help Workshop...')
-        os.chdir(os.path.join(self.manual_build_path, u'htmlhelp'))
-        hhc = Popen((self.hhc, u'OpenLP.chm'), stdout=PIPE)
+        self._print('Running HTML Help Workshop...')
+        os.chdir(os.path.join(self.manual_build_path, 'htmlhelp'))
+        hhc = Popen((self.hhc, 'OpenLP.chm'), stdout=PIPE)
         output, error = hhc.communicate()
         code = hhc.wait()
         if code != 1:
-            self._print(u'Exit code:', code)
+            self._print('Exit code:', code)
             self._print(output)
-            raise Exception(u'Error running HTML Help Workshop')
+            raise Exception('Error running HTML Help Workshop')
 
     def create_innosetup_file(self):
         """
         Create an InnoSetup file pointing to the branch being built.
         """
-        self._print(u'Creating Inno Setup file...')
-        input = open(os.path.join(self.script_path,
-            u'OpenLP-2.0.iss.default'), u'r').read()
-        output = input.replace(u'%(branch)s', self.branch_path)
-        output = output.replace(u'%(display_version)s', self.version)
-        outfile = open(os.path.join(self.script_path,
-            u'OpenLP-2.0.iss'), u'w')
+        self._print('Creating Inno Setup file...')
+        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.write(output)
         outfile.close()
 
@@ -522,13 +499,11 @@
         Checks the PortableApp directory structure amd creates
         missing subdirs
         """
-        self._print(u'  Checking PortableApps directory structure...')
-        launcher_path = os.path.join(self.portable_path, u'App',
-            u'Appinfo', u'Launcher')
+        self._print('  Checking PortableApps directory structure...')
+        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, u'Data',
-            u'Settings')
+        settings_path = os.path.join(self.portable_path, 'Data', 'Settings')
         if not os.path.exists(settings_path):
             os.makedirs(settings_path)
 
@@ -536,14 +511,12 @@
         """
         Create a Portabbleapps appinfo.ini file.
         """
-        self._print(u'  Creating PortableApps appinfo file ...')
-        portable_version = self.version + '.0' * (3-self.version.count('.'))
-        input = open(os.path.join(self.script_path,
-            u'appinfo.ini.default'), u'r').read()
-        output = input.replace(u'%(display_version)s', self.version)
-        output = output.replace(u'%(package_version)s', portable_version)
-        outfile = open(os.path.join(self.portable_path, u'App',
-            u'Appinfo', u'appinfo.ini'), u'w')
+        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()
+        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.write(output)
         outfile.close()
 
@@ -551,13 +524,12 @@
         """
         Run InnoSetup to create an installer.
         """
-        self._print(u'Running Inno Setup...')
+        self._print('Running Inno Setup...')
         os.chdir(self.script_path)
-        innosetup = Popen((self.innosetup,
-            os.path.join(self.script_path, u'OpenLP-2.0.iss'), u'/q'))
+        innosetup = Popen((self.innosetup, os.path.join(self.script_path, 'OpenLP-2.0.iss'), '/q'))
         code = innosetup.wait()
         if code != 0:
-            raise Exception(u'Error running Inno Setup')
+            raise Exception('Error running Inno Setup')
 
     def run_portableapp_builder(self):
         """
@@ -566,105 +538,92 @@
         2  Builds the PortableApps Launcher
         3  Builds the PortableApps Install
         """
-        self._print(u'Running PortableApps Builder...')
-        self._print(u'  Clearing old files')
+        self._print('Running PortableApps Builder...')
+        self._print('  Clearing old files')
         # Remove previous contents of portableapp build directory.
         if os.path.exists(self.portable_path):
             rmtree(self.portable_path)
-        self._print(u'  Creating PortableApps build directory')
+        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, u'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.
-        self._print(u'  Copying distribution files')
-        portable_app_path = os.path.join(self.portable_path, u'App', u'OpenLP')
+        self._print('  Copying distribution files')
+        portable_app_path = os.path.join(self.portable_path, 'App', 'OpenLP')
         dir_util.copy_tree(self.dist_path, portable_app_path)
         # Copy help files to portableapp build directory.
-        self._print(u'  Copying help files')
-        dir_util.copy_tree(self.helpfile_path,
-            os.path.join(portable_app_path, u'help'))
+        self._print('  Copying help files')
+        dir_util.copy_tree(self.helpfile_path, os.path.join(portable_app_path, 'help'))
         # Build the launcher.
-        self._print(u'  Building PortableApps Launcher')
-        portableapps = Popen((self.portablelauncher, self.portable_path),
-            stdout=PIPE)
+        self._print('  Building PortableApps Launcher')
+        portableapps = Popen((self.portablelauncher, self.portable_path), stdout=PIPE)
         code = portableapps.wait()
         if code != 0:
-            raise Exception(u'Error creating PortableAppa Launcher')
+            raise Exception('Error creating PortableAppa Launcher')
         # Build the portable installer.
-        self._print(u'  Building PortableApps Installer')
-        portableapps = Popen((self.portableinstaller, self.portable_path),
-            stdout=PIPE)
+        self._print('  Building PortableApps Installer')
+        portableapps = Popen((self.portableinstaller, self.portable_path), stdout=PIPE)
         code = portableapps.wait()
         if code != 0:
-            raise Exception(u'Error running PortableApps Installer')
-        portable_app = os.path.abspath(os.path.join(self.portable_path, u'..',
-            u'OpenLPPortable_%s.paf.exe' % self.version))
+            raise Exception('Error running PortableApps Installer')
+        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, u'..')))
-            self._print(u'  PortableApp build complete')
+            move(portable_app, os.path.abspath(os.path.join(self.dist_path, '..')))
+            self._print('  PortableApp build complete')
         else:
-            raise Exception(u'PortableApp failed to build')
+            raise Exception('PortableApp failed to build')
 
     def build_pptviewlib(self):
         """
         Build the PowerPoint Viewer DLL using Visual Studio.
         """
-        self._print(u'Building PPTVIEWLIB.DLL...')
-        vcbuild = Popen((self.vcbuild, u'/rebuild',
-            os.path.join(self.pptviewlib_path, u'pptviewlib.vcproj'),
-            u'Release|Win32'))
+        self._print('Building PPTVIEWLIB.DLL...')
+        vcbuild = Popen((self.vcbuild, '/rebuild', os.path.join(self.pptviewlib_path, 'pptviewlib.vcproj'),
+                         'Release|Win32'))
         code = vcbuild.wait()
         if code != 0:
-            raise Exception(u'Error building pptviewlib.dll')
-        copy(os.path.join(self.pptviewlib_path, u'Release',
-            u'pptviewlib.dll'), self.pptviewlib_path)
+            raise Exception('Error building pptviewlib.dll')
+        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(u'OpenLP main script: ......%s',
-            self.openlp_script)
-        self._print_verbose(u'Script path: .............%s',
-            os.path.split(os.path.abspath(__file__))[0])
-        self._print_verbose(u'Branch path: .............%s', self.branch_path)
-        self._print_verbose(u'Source path: .............%s', self.source_path)
-        self._print_verbose(u'Dist path: ...............%s', self.dist_path)
-        self._print_verbose(u'Portable path: ...........%s',
-            self.portable_path)
-        self._print_verbose(u'PyInstaller: .............%s', self.pyinstaller)
-        self._print_verbose(u'Documentation branch path:%s', self.docs_path)
-        self._print_verbose(u'Help file build path: ....%s',
-            self.helpfile_path)
-        self._print_verbose(u'Inno Setup path: .........%s', self.innosetup)
-        self._print_verbose(u'PortableApp Launcher......%s',
-            self.portablelauncher)
-        self._print_verbose(u'PortableApp Installer.....%s',
-            self.portableinstaller)
-        self._print_verbose(u'Windows resources: .......%s', self.winres_path)
-        self._print_verbose(u'VCBuild path: ............%s', self.vcbuild)
-        self._print_verbose(u'PPTVIEWLIB path: .........%s',
-            self.pptviewlib_path)
-        self._print_verbose(u'')
+        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('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('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('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('')
         if not self.args.skip_update:
             self.update_code()
         self.build_pptviewlib()
         self.run_pyinstaller()
         self.write_version_file()
+        self.copy_default_theme()
         self.copy_plugins()
         self.copy_media_player()
         if os.path.exists(self.manual_path):
             self.run_sphinx()
             self.run_htmlhelp()
         else:
-            self._print(u'')
-            self._print(u'WARNING: Documentation trunk not found. Windows')
-            self._print(u'         Help file will not be included in build')
-            self._print(u'')
+            self._print('')
+            self._print('WARNING: Documentation trunk not found. Windows')
+            self._print('         Help file will not be included in build')
+            self._print('')
         self.copy_windows_files()
         if not self.args.skip_translations:
             self.update_translations()
@@ -673,7 +632,8 @@
         self.run_innosetup()
         if self.args.portable:
             self.run_portableapp_builder()
-        self._print(u'Done.')
-
-if __name__ == u'__main__':
+        self._print('Done.')
+
+
+if __name__ == '__main__':
     WindowsBuilder().main()


Follow ups