diff --git a/builders/builder.py b/builders/builder.py index 8e1ec42..e36101b 100644 --- a/builders/builder.py +++ b/builders/builder.py @@ -161,7 +161,7 @@ class Builder(object): help='Do NOT update the language translation files') parser.add_argument('--debug', action='store_true', default=False, help='Create a debug build') parser.add_argument('--tag-override', metavar='.dev+', default=None, - help='Override tag and revision, should be in format .dev+') + help='Override tag and revision, should be in format .dev+') # noqa self.add_extra_args(parser) self.args = parser.parse_args() @@ -218,7 +218,7 @@ class Builder(object): else: self.version = None self.work_path = self.branch_path - self.openlp_script = os.path.abspath(os.path.join(self.work_path, 'run_openlp.py')) + self.openlp_script = os.path.abspath(os.path.join(self.work_path, 'openlp', '__main__.py')) self.source_path = os.path.join(self.work_path, 'openlp') self.manual_path = os.path.join(self.documentation_path, 'manual') self.manual_build_path = os.path.join(self.manual_path, 'build') @@ -507,6 +507,7 @@ class Builder(object): self._print('') self._print('WARNING: Documentation trunk not found') self._print(' Help file will not be included in build') + self._print(' Manual path: %s', self.manual_path) self._print('') self.copy_extra_files() if not self.args.skip_translations: diff --git a/builders/windows-builder.py b/builders/windows-builder.py index c564b88..2a437b5 100644 --- a/builders/windows-builder.py +++ b/builders/windows-builder.py @@ -102,8 +102,9 @@ from distutils import dir_util from hashlib import md5 from shutil import copy, copytree, move, rmtree -from lxml.etree import fromstring, parse, tostring +from lxml.etree import ElementTree from lxml.builder import E, ElementMaker +from lxml.objectify import fromstring from builder import Builder @@ -128,63 +129,81 @@ class WindowsBuilder(Builder): else: return None - def _get_fragments_from_files(self, start_dir): + def _get_dirs_and_files(self, install_dir, start_dir): """ Walk down a directory recursively and build up the XML for WiX """ + self._openlp_id = None start_base, start_path = os.path.split(start_dir) - element = E.DirectoryRef(Id='INSTALLDIR') + element = install_dir directories = {start_path: {'__dir__': element}} components = [] + component_ids = [] FxE = ElementMaker(namespace='http://schemas.microsoft.com/wix/FirewallExtension', nsmap={'fw': 'http://schemas.microsoft.com/wix/FirewallExtension'}) for root, _, files in os.walk(start_dir): parent = os.sep.join(root.replace(os.path.join(start_base, ''), '').split(os.sep)[:-1]) - if root == start_dir: - path = '' - else: - path = root.replace(os.path.join(start_dir, ''), '') base = os.path.basename(root) if root != start_dir: - dir_id = 'dir_{parent}_{base}'.format(parent=parent.replace(os.sep, '_'), base=base) - element = E.Directory(Id=dir_id, Name=base) + dir_id = 'd_{}'.format(md5(os.path.join(parent, base).encode('utf8')).hexdigest()) + new_element = E.Directory(Id=dir_id, Name=base) + element.append(new_element) + element = new_element new_dir = {'__dir__': element} parent_dir = self._walk_dirs(directories, parent) parent_dir[base] = new_dir parent_dir['__dir__'].append(element) for fname in files: - source = os.path.join(path, fname) if path else fname - source_id = md5(source.encode('utf8')).hexdigest() - file_id = 'file_{source_id}'.format(source_id=source_id) - component_id = 'cmp_{source_id}'.format(source_id=source_id) + source = os.path.join(root, fname) + source_id = 'f_{}'.format(md5(source.encode('utf8')).hexdigest()) + component_ids.append(source_id) if self.arch == 'x64': - file_ = E.File(Id=file_id, KeyPath='yes', Source=source, ProcessorArchitecture='x64') - component = E.Component(file_, Id=component_id, Guid='*', Win64='yes') + file_ = E.File(Id=source_id, Name=fname, Source=source, ProcessorArchitecture='x64') + component = E.Component(file_, Id=source_id, Guid='*', DiskId='1', Win64='yes') else: - file_ = E.File(Id=file_id, KeyPath='yes', Source=source) - component = E.Component(file_, Id=component_id, Guid='*') + file_ = E.File(Id=source_id, Name=fname, Source=source) + component = E.Component(file_, Id=source_id, Guid='*', DiskId='1') if source.endswith('OpenLP.exe'): - description = 'Firewall exception for OpenLP\'s remote interface (UDP)' - program = '[#file_e368869eb54b01e2288a3359b1cf51f8]' - component.append(FxE.FirewallException(Id='OpenLP_TCP', Name='OpenLP', - Description=description, IgnoreFailure='yes', - Program=program, Protocol='tcp', Scope='any')) - component.append(FxE.FirewallException(Id='OpenLP_UDP', Name='OpenLP', - Description=description, IgnoreFailure='yes', - Program=program, Protocol='udp', Scope='any')) - # Add the file association XML - config_dir = os.path.dirname(self.config_path) - with open(os.path.join(config_dir, 'file-associations.xml')) as assoc_file: - file_assoc = parse(assoc_file) - component.append(file_assoc.getroot()) + self._openlp_id = source_id + file_.set('KeyPath', 'yes') + fw_program = '[#{}]'.format(source_id) + component.append(FxE.FirewallException(Id='OpenLP_TCP', Name='$(var.ProductName)', + IgnoreFailure='yes', Program=fw_program, + Protocol='tcp', Scope='any')) + component.append(FxE.FirewallException(Id='OpenLP_UDP', Name='$(var.ProductName)', + IgnoreFailure='yes', Program=fw_program, + Protocol='udp', Scope='any')) + component.append(E.Shortcut(Id='ApplicationStartMenuShortcut', Name='$(var.ProductName)', + Description='$(var.Description)', Directory='ProgramMenuDir', + Icon='OpenLP.ico', Advertise='yes', WorkingDirectory='INSTALLDIR')) + component.append(E.Shortcut(Id='DebugStartMenuShortcut', Name='$(var.ProductName) (Debug)', + Description='Run $(var.ProductName) with debug logging enabled', + Directory='ProgramMenuDir', Arguments='--log-level debug', + Icon='OpenLP.ico', Advertise='yes', WorkingDirectory='INSTALLDIR')) + component.append(E.ProgId( + E.Extension( + E.Verb(Id="Open", Command="Open", Argument=" "%1""), + E.MIME(Advertise="yes", ContentType="application/-x-openlp-service", Default="yes"), + Id="osz" + ), + E.Extension( + E.Verb(Id="Open", Command="Open", Argument=" "%1""), + E.MIME(Advertise="yes", ContentType="application/-x-openlp-service-lite", Default="yes"), + Id="oszl" + ), + Id="OpenLP.Service", + Description="OpenLP Service File", + Icon="service_file.ico", + Advertise="yes" + )) + elif source.endswith('OpenLP.chm'): + component.append(E.Shortcut(Id='HelpStartMenuShortcut', Name='$(var.ProductName) Help', + Description='Help file for $(var.ProductName)', + Target='[#{}]'.format(source_id), WorkingDirectory='INSTALLDIR')) element.append(component) components.append(component) - - files_fragment = E.Fragment(directories[start_path]['__dir__']) - comps_fragment = E.Fragment(E.ComponentGroup(*[E.ComponentRef(Id=c.attrib['Id']) for c in components], - Id='Files')) - return files_fragment, comps_fragment + return component_ids def _create_wix_file(self): """ @@ -195,27 +214,40 @@ class WindowsBuilder(Builder): self._print_verbose('Reading base WiX file') with open(os.path.join(config_dir, 'OpenLP-base.wxs'), 'rt') as base_file: xml = base_file.read() - progfilefolder = 'ProgramFiles64Folder' if self.arch == 'x64' else 'ProgramFilesFolder' # convert the version string to format x.x.x if needed if '.dev' in self.version: windows_version = self.version.replace('.dev', '.') windows_version = windows_version.rsplit('+', 1)[0] else: windows_version = self.version - xml = xml % dict(dialog=os.path.join(config_dir, 'WizardMain.bmp'), - banner=os.path.join(config_dir, 'WizardBanner.bmp'), - platform=self.arch, - progfilefolder=progfilefolder, - version=windows_version) - tree = fromstring(xml.encode('utf8')) + xml = xml % { + 'dialog': os.path.join(config_dir, 'WizardMain.bmp'), + 'banner': os.path.join(config_dir, 'WizardBanner.bmp'), + 'license': os.path.join(config_dir, 'LICENSE.rtf'), + 'platform': self.arch, + 'progfilefolder': 'ProgramFiles64Folder' if self.arch == 'x64' else 'ProgramFilesFolder', + 'systemfolder': 'System64Folder' if self.arch == 'x64' else 'SystemFolder', + 'version': windows_version + } + root = fromstring(xml.encode('utf8')) + # Find the INSTALLDIR directory component and populate it with our files and folders + install_dir = root.xpath('//wix:Directory[@Id="INSTALLDIR"]', + namespaces={'wix': 'http://schemas.microsoft.com/wix/2006/wi'})[0] self._print_verbose('Creating XML fragments from files and directories') - fragments = self._get_fragments_from_files(self.dist_path) - self._print_verbose('Inserting XML fragments into base WiX file') - for fragment in fragments: - tree.append(fragment) + component_ids = self._get_dirs_and_files(install_dir, self.dist_path) + # Write the property for the "Run OpenLP" checkbox + product = root.xpath('//wix:Product', + namespaces={'wix': 'http://schemas.microsoft.com/wix/2006/wi'})[0] + product.append(E.Property(Id='WixShellExecTarget', Value='[#{}]'.format(self._openlp_id))) + # Set the component ids for the feature + feature = root.xpath('//wix:Feature', + namespaces={'wix': 'http://schemas.microsoft.com/wix/2006/wi'})[0] + for component_id in component_ids: + feature.append(E.ComponentRef(Id=component_id)) self._print_verbose('Writing new WiX file') + tree = ElementTree(root) with open(os.path.join(config_dir, 'OpenLP.wxs'), 'wb') as f: - f.write(tostring(tree, encoding='utf-8', xml_declaration=True, pretty_print=True)) + tree.write(f, encoding='utf-8', xml_declaration=True, pretty_print=True) def _run_wix_tools(self): """ diff --git a/pyinstaller-hooks/hook-openlp.py b/pyinstaller-hooks/hook-openlp.py index 659d2bc..a932da1 100644 --- a/pyinstaller-hooks/hook-openlp.py +++ b/pyinstaller-hooks/hook-openlp.py @@ -29,5 +29,6 @@ hiddenimports = [ 'openlp.plugins.custom.customplugin', 'openlp.plugins.songusage.songusageplugin', 'openlp.plugins.remotes.remoteplugin', - 'openlp.plugins.alerts.alertsplugin' + 'openlp.plugins.alerts.alertsplugin', + 'openlp.plugins.planningcenter.planningcenterplugin' ] diff --git a/windows/OpenLP-base.wxs b/windows/OpenLP-base.wxs index 38328d5..7c43709 100644 --- a/windows/OpenLP-base.wxs +++ b/windows/OpenLP-base.wxs @@ -10,16 +10,14 @@ + UpgradeCode="$(var.UpgradeCode)" Language="1033" Version="$(var.ProductVersion)"> + Manufacturer="$(var.Manufacturer)" InstallerVersion="400" Compressed="yes" Platform="$(var.Platform)"/> Privileged - + - @@ -63,31 +61,13 @@ - + - - - @@ -96,7 +76,7 @@ Target="http://forums.openlp.org/"/> @@ -104,12 +84,8 @@ - - - - - diff --git a/windows/file-associations.xml b/windows/file-associations.xml deleted file mode 100644 index b25764e..0000000 --- a/windows/file-associations.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - -