From 2aa53f640b112e11df4b0eac40818ab69570c21d Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Wed, 23 Jan 2019 20:00:41 -0500 Subject: [PATCH 01/30] It starts on macos, need to work on the desktop entries --- examples/test_local.py | 13 +++++++++++++ iquail/helper/misc.py | 1 + iquail/installer/installer.py | 4 +++- iquail/installer/installer_osx.py | 32 +++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 iquail/installer/installer_osx.py diff --git a/examples/test_local.py b/examples/test_local.py index c712504..24e35e2 100755 --- a/examples/test_local.py +++ b/examples/test_local.py @@ -25,6 +25,19 @@ iquail.builder.CmdIntegrity(solution_path) ) ) +if iquail.helper.OS_OSX: + solution_path = ['Allum1'] + iquail.run( + iquail.SolutionLocal(['Allum1']), + iquail.Installer( + name='Allum1', + publisher='alies', + icon='icon.jpeg', + binary='allum1', + console=True, + ), + iquail.builder.Builder(iquail.builder.CmdIntegrity(solution_path)) + ) if iquail.helper.OS_WINDOWS: solution_path = ['OpenHardwareMonitor'] iquail.run( diff --git a/iquail/helper/misc.py b/iquail/helper/misc.py index 367aef0..60837d2 100644 --- a/iquail/helper/misc.py +++ b/iquail/helper/misc.py @@ -11,6 +11,7 @@ OS_LINUX = platform.system() == 'Linux' OS_WINDOWS = platform.system() == 'Windows' +OS_OSX = platform.system() == 'Darwin' def cache_result(func): diff --git a/iquail/installer/installer.py b/iquail/installer/installer.py index 69f0877..00775b3 100644 --- a/iquail/installer/installer.py +++ b/iquail/installer/installer.py @@ -8,4 +8,6 @@ from .installer_windows import InstallerWindows Installer = InstallerWindows else: - raise NotImplementedError + from .installer_osx import InstallerOsx + Installer = InstallerOsx + diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py new file mode 100644 index 0000000..9fb588e --- /dev/null +++ b/iquail/installer/installer_osx.py @@ -0,0 +1,32 @@ +from .installer_base import InstallerBase +import os +import pathlib + +class InstallerOsx(InstallerBase): + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + """ We need to put a syslink into /usr/local/bin or into a local folder inside the user's home directory""" + def _register(self): + self.__add_to_path(self.binary, self._binary_name) + + def _unregister(self): + self.__remove_from_path(self.binary) + + def _registered(self): + if not os.path.exists(self.build_symlink_path(self.binary)): + return False + + def __add_to_path(self, binary, name): + os.symlink(binary, self.build_symlink_path(name)) + + def __remove_from_path(self, name): + os.remove(self.build_install_path(name)) + + def build_symlink_path(self, name): + if self.install_systemwide: + final_folder = '/usr/bin' + else: + final_folder = os.path.join(str(pathlib.Path.home()), '.local/bin') + return os.path.join(final_folder, name) From 87682be654066a28d340551c1911e7ff2eeebdcf Mon Sep 17 00:00:00 2001 From: Lucas TRONCY Date: Tue, 29 Jan 2019 11:40:28 -0800 Subject: [PATCH 02/30] added app bundle --- examples/MacCalc/maccalc | 2 ++ examples/test_osx.py | 20 +++++++++++++ iquail/controller/__init__.py | 5 +++- iquail/helper/__init__.py | 1 + iquail/helper/osx/__init__.py | 2 ++ iquail/helper/osx/bundle_template.py | 34 ++++++++++++++++++++++ iquail/helper/osx/plist_template.py | 42 ++++++++++++++++++++++++++++ iquail/installer/installer_osx.py | 9 ++++-- 8 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 examples/MacCalc/maccalc create mode 100644 examples/test_osx.py create mode 100644 iquail/helper/osx/__init__.py create mode 100644 iquail/helper/osx/bundle_template.py create mode 100644 iquail/helper/osx/plist_template.py diff --git a/examples/MacCalc/maccalc b/examples/MacCalc/maccalc new file mode 100644 index 0000000..ffd64d8 --- /dev/null +++ b/examples/MacCalc/maccalc @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +open -a calculator && cat \ No newline at end of file diff --git a/examples/test_osx.py b/examples/test_osx.py new file mode 100644 index 0000000..d00ff7f --- /dev/null +++ b/examples/test_osx.py @@ -0,0 +1,20 @@ +#!/usr/bin/python3 + +import os +import os.path +import iquail +import platform + +if iquail.helper.OS_OSX: + solution_path = ['MacCalc'] + iquail.run( + iquail.SolutionLocal(['MacCalc']), + iquail.Installer( + name='MacCalc', + publisher='test', + icon='icon.jpeg', + binary='maccalc', + console=True, + ), + iquail.builder.Builder(iquail.builder.CmdIntegrity(solution_path)) + ) diff --git a/iquail/controller/__init__.py b/iquail/controller/__init__.py index 22e2015..a2470b7 100644 --- a/iquail/controller/__init__.py +++ b/iquail/controller/__init__.py @@ -1,3 +1,6 @@ from .controller_base import ControllerBase -from .controller_tkinter import ControllerTkinter +try: + from .controller_tkinter import ControllerTkinter +except: + print("No display found or tkinter missing, console mode enabled !") from .controller_console import ControllerConsole diff --git a/iquail/helper/__init__.py b/iquail/helper/__init__.py index 9638f13..c6ac604 100644 --- a/iquail/helper/__init__.py +++ b/iquail/helper/__init__.py @@ -2,3 +2,4 @@ from .file_ignore import FileIgnore, accept_path from .integrity_verifier import IntegrityVerifier, checksum_file from .configuration import Configuration, ConfVar +from .osx import BundleTemplate, PlistTemplate diff --git a/iquail/helper/osx/__init__.py b/iquail/helper/osx/__init__.py new file mode 100644 index 0000000..772c159 --- /dev/null +++ b/iquail/helper/osx/__init__.py @@ -0,0 +1,2 @@ +from .bundle_template import BundleTemplate +from .plist_template import PlistTemplate \ No newline at end of file diff --git a/iquail/helper/osx/bundle_template.py b/iquail/helper/osx/bundle_template.py new file mode 100644 index 0000000..1443c56 --- /dev/null +++ b/iquail/helper/osx/bundle_template.py @@ -0,0 +1,34 @@ +import os + +""" + +iquail.app/ + Contents/ + Info.plist + MacOS/ + iquail + Resources/ + iquail.icns + +""" + +class BundleTemplate(): + + def __init__(self, CFBundleName): + self.bundleName = CFBundleName + self.baseDir = "/Applications/" + self.fullPath = self.baseDir + self.bundleName + ".app" + self.names = [self.fullPath, self.fullPath + "/Contents", self.fullPath + "/Contents/MacOS"] + + def make(self): + for path in self.names: + print("Creating folder: " + path) + os.mkdir(path) + # mkdir /Applications/Bundle.app + # mkdir /Applications/Bundle.app/Contents + # mkdir /Applications/Bundle.app/Contents/MacOS + # mkdir /Applications/Bundle.app/Contents/Resources + + # touch mkdir /Applications/Bundle.app/Contents/Info.plist + # OR MV # touch mkdir /Applications/Bundle.app/Resources/XXX.icns + # OR MV # touch mkdir /Applications/Bundle.app/MacOS/XXX -> BINARY diff --git a/iquail/helper/osx/plist_template.py b/iquail/helper/osx/plist_template.py new file mode 100644 index 0000000..aed1cb0 --- /dev/null +++ b/iquail/helper/osx/plist_template.py @@ -0,0 +1,42 @@ +import os + +class PlistTemplate(): + def __init__(self, CFBundleName, plistDict): + print("init template") + self.file = open("/Applications/" + CFBundleName + ".app/Contents/Info.plist", "a+") + self.plistDict = dict( + CFBundleGetInfoString=CFBundleName, + CFBundleExecutable=CFBundleName, + CFBundleIdentifier=CFBundleName, + CFBundleName=CFBundleName + ) + self.plistDict.update(plistDict) + + def make(self): + self._createHeader() + for key, value in self.plistDict.items(): + self._writeProperty(key, value, "string") + self._createFooter() + + def getInfoPlist(self): + return self.plistDict + + def _createHeader(self): + self.plistHeader = """ + + + + + """ + self.file.write(self.plistHeader) + + def _createFooter(self): + self.plistFooter = """ + + + """ + self.file.write(self.plistFooter) + + def _writeProperty(self, key, value, typeValue): + self.file.write(" " + key + "\n") + self.file.write(" <" + typeValue + ">" + value + "\n") \ No newline at end of file diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index 9fb588e..aa99a31 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -1,6 +1,7 @@ from .installer_base import InstallerBase import os import pathlib +from ..helper import BundleTemplate, PlistTemplate class InstallerOsx(InstallerBase): @@ -9,6 +10,10 @@ def __init__(self, *args, **kwargs): """ We need to put a syslink into /usr/local/bin or into a local folder inside the user's home directory""" def _register(self): + bundle = BundleTemplate(self._name) + bundle.make() + plist = PlistTemplate(self._binary_name, {}) + plist.make() self.__add_to_path(self.binary, self._binary_name) def _unregister(self): @@ -26,7 +31,7 @@ def __remove_from_path(self, name): def build_symlink_path(self, name): if self.install_systemwide: - final_folder = '/usr/bin' + final_folder = '/Applications' else: - final_folder = os.path.join(str(pathlib.Path.home()), '.local/bin') + final_folder = os.path.join(str(pathlib.Path.home()), '/Applications/' + self._name + '.app/Contents/MacOS/') return os.path.join(final_folder, name) From d6ebc8cec1d402be716490308d3a3a82f0e40bc9 Mon Sep 17 00:00:00 2001 From: Lucas TRONCY Date: Mon, 25 Mar 2019 16:37:21 -0700 Subject: [PATCH 03/30] The solution is now launched via iQuail on OSX --- examples/MacCalc/.integrity.json | 1 + iquail/helper/osx/bundle_template.py | 24 ++---------------------- iquail/helper/osx/plist_template.py | 4 ++-- iquail/installer/installer_osx.py | 25 ++++++++++++++++++++++--- 4 files changed, 27 insertions(+), 27 deletions(-) create mode 100644 examples/MacCalc/.integrity.json diff --git a/examples/MacCalc/.integrity.json b/examples/MacCalc/.integrity.json new file mode 100644 index 0000000..d24bf3b --- /dev/null +++ b/examples/MacCalc/.integrity.json @@ -0,0 +1 @@ +{"maccalc": "bdee4331072ce68954b7aa6d090165bc638474bf9515114a72d5baf86fa415af"} \ No newline at end of file diff --git a/iquail/helper/osx/bundle_template.py b/iquail/helper/osx/bundle_template.py index 1443c56..8650a2a 100644 --- a/iquail/helper/osx/bundle_template.py +++ b/iquail/helper/osx/bundle_template.py @@ -1,34 +1,14 @@ import os -""" - -iquail.app/ - Contents/ - Info.plist - MacOS/ - iquail - Resources/ - iquail.icns - -""" - class BundleTemplate(): def __init__(self, CFBundleName): self.bundleName = CFBundleName + #TODO refactor name self.baseDir = "/Applications/" self.fullPath = self.baseDir + self.bundleName + ".app" self.names = [self.fullPath, self.fullPath + "/Contents", self.fullPath + "/Contents/MacOS"] def make(self): for path in self.names: - print("Creating folder: " + path) - os.mkdir(path) - # mkdir /Applications/Bundle.app - # mkdir /Applications/Bundle.app/Contents - # mkdir /Applications/Bundle.app/Contents/MacOS - # mkdir /Applications/Bundle.app/Contents/Resources - - # touch mkdir /Applications/Bundle.app/Contents/Info.plist - # OR MV # touch mkdir /Applications/Bundle.app/Resources/XXX.icns - # OR MV # touch mkdir /Applications/Bundle.app/MacOS/XXX -> BINARY + os.mkdir(path) \ No newline at end of file diff --git a/iquail/helper/osx/plist_template.py b/iquail/helper/osx/plist_template.py index aed1cb0..3eae32d 100644 --- a/iquail/helper/osx/plist_template.py +++ b/iquail/helper/osx/plist_template.py @@ -1,12 +1,12 @@ import os +#TODO : add full PATH to spotlight env to access python3 class PlistTemplate(): def __init__(self, CFBundleName, plistDict): - print("init template") self.file = open("/Applications/" + CFBundleName + ".app/Contents/Info.plist", "a+") self.plistDict = dict( CFBundleGetInfoString=CFBundleName, - CFBundleExecutable=CFBundleName, + CFBundleExecutable='launcher', CFBundleIdentifier=CFBundleName, CFBundleName=CFBundleName ) diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index aa99a31..d58a35f 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -1,5 +1,7 @@ from .installer_base import InstallerBase import os +import stat +import shutil import pathlib from ..helper import BundleTemplate, PlistTemplate @@ -7,6 +9,7 @@ class InstallerOsx(InstallerBase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + self._bundle_install_path = '/Applications/' + self.name + '.app' """ We need to put a syslink into /usr/local/bin or into a local folder inside the user's home directory""" def _register(self): @@ -14,7 +17,8 @@ def _register(self): bundle.make() plist = PlistTemplate(self._binary_name, {}) plist.make() - self.__add_to_path(self.binary, self._binary_name) + self._build_launcher() + #self.__add_to_path(self.binary, self._binary_name) def _unregister(self): self.__remove_from_path(self.binary) @@ -27,11 +31,26 @@ def __add_to_path(self, binary, name): os.symlink(binary, self.build_symlink_path(name)) def __remove_from_path(self, name): - os.remove(self.build_install_path(name)) + shutil.rmtree(self._bundle_install_path) def build_symlink_path(self, name): if self.install_systemwide: - final_folder = '/Applications' + #TODO setup local installation + #final_folder = '/Applications' + final_folder = os.path.join(str(pathlib.Path.home()), '/Applications/' + self._name + '.app/Contents/MacOS/') else: final_folder = os.path.join(str(pathlib.Path.home()), '/Applications/' + self._name + '.app/Contents/MacOS/') + print('DEBUG run') + print(final_folder) + print(name) + print('END_DEEBUG run') return os.path.join(final_folder, name) + + def _build_launcher(self): + with open(self._bundle_install_path + '/Contents/MacOS/launcher', 'w') as f: + content = '/usr/local/bin/python3 ~/.iquail/' + self.uid + '/iquail_launcher.py' + shebang = '#!/bin/bash\n' + f.write(shebang) + f.write(content) + st = os.stat(self._bundle_install_path + '/Contents/MacOS/launcher') + os.chmod(self._bundle_install_path + '/Contents/MacOS/launcher', st.st_mode | stat.S_IEXEC) From d35f3db98e696531a8d359dff8b8ea3a0b6f566c Mon Sep 17 00:00:00 2001 From: peauc Date: Tue, 26 Mar 2019 00:49:18 -0400 Subject: [PATCH 04/30] OSX - Started to work on a proper xml way of writing plist files --- iquail/helper/osx/plist_creator.py | 33 ++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 iquail/helper/osx/plist_creator.py diff --git a/iquail/helper/osx/plist_creator.py b/iquail/helper/osx/plist_creator.py new file mode 100644 index 0000000..3ea178f --- /dev/null +++ b/iquail/helper/osx/plist_creator.py @@ -0,0 +1,33 @@ +import xml.etree.ElementTree as ET + +class PlistCreator: + def __init__(self, bundle_name: str, plistDict: dict): + self.__file = open("/applications/" + bundle_name + ".app/contents/info.plist", "a+") + self.__ + self.__plist_dict = { + "CFBundleGetInfoString": bundle_name, + "CFBundleExecutable": 'launcher', + "CFBundleIdentifier": bundle_name, + "CFBundleName": bundle_name + } + self.__plist_header = """ + + + + """ + self.__plist_dict.update(plistDict) + + def __del__(self): + self.__file.close() + + @property + def plist_dict(self): + return self.__plist_dict + + def write_file(self): + self.__create_header() + + def __create_header(self): + self.__file.write(self.__plist_header) + + From 1af7eb67396e3a0bc8a2bd561ba0d12cad8a9b11 Mon Sep 17 00:00:00 2001 From: Lucas TRONCY Date: Tue, 26 Mar 2019 14:39:22 -0700 Subject: [PATCH 05/30] Fixed some variables names --- iquail/helper/osx/bundle_template.py | 8 ++++---- iquail/helper/osx/plist_template.py | 16 ++++++++-------- iquail/installer/installer_osx.py | 4 ---- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/iquail/helper/osx/bundle_template.py b/iquail/helper/osx/bundle_template.py index 8650a2a..a57315b 100644 --- a/iquail/helper/osx/bundle_template.py +++ b/iquail/helper/osx/bundle_template.py @@ -3,11 +3,11 @@ class BundleTemplate(): def __init__(self, CFBundleName): - self.bundleName = CFBundleName + self.bundle_name = CFBundleName #TODO refactor name - self.baseDir = "/Applications/" - self.fullPath = self.baseDir + self.bundleName + ".app" - self.names = [self.fullPath, self.fullPath + "/Contents", self.fullPath + "/Contents/MacOS"] + self.base_dir = "/Applications/" + self.full_path = self.base_dir + self.bundle_name + ".app" + self.names = [self.full_path, self.full_path + "/Contents", self.full_path + "/Contents/MacOS"] def make(self): for path in self.names: diff --git a/iquail/helper/osx/plist_template.py b/iquail/helper/osx/plist_template.py index 3eae32d..3a03e6f 100644 --- a/iquail/helper/osx/plist_template.py +++ b/iquail/helper/osx/plist_template.py @@ -4,38 +4,38 @@ class PlistTemplate(): def __init__(self, CFBundleName, plistDict): self.file = open("/Applications/" + CFBundleName + ".app/Contents/Info.plist", "a+") - self.plistDict = dict( + self.plist_dict = dict( CFBundleGetInfoString=CFBundleName, CFBundleExecutable='launcher', CFBundleIdentifier=CFBundleName, CFBundleName=CFBundleName ) - self.plistDict.update(plistDict) + self.plist_dict.update(plistDict) def make(self): self._createHeader() - for key, value in self.plistDict.items(): + for key, value in self.plist_dict.items(): self._writeProperty(key, value, "string") self._createFooter() def getInfoPlist(self): - return self.plistDict + return self.plist_dict def _createHeader(self): - self.plistHeader = """ + self.plist_header = """ """ - self.file.write(self.plistHeader) + self.file.write(self.plist_header) def _createFooter(self): - self.plistFooter = """ + self.plist_footer = """ """ - self.file.write(self.plistFooter) + self.file.write(self.plist_footer) def _writeProperty(self, key, value, typeValue): self.file.write(" " + key + "\n") diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index d58a35f..af4d5f6 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -40,10 +40,6 @@ def build_symlink_path(self, name): final_folder = os.path.join(str(pathlib.Path.home()), '/Applications/' + self._name + '.app/Contents/MacOS/') else: final_folder = os.path.join(str(pathlib.Path.home()), '/Applications/' + self._name + '.app/Contents/MacOS/') - print('DEBUG run') - print(final_folder) - print(name) - print('END_DEEBUG run') return os.path.join(final_folder, name) def _build_launcher(self): From 67f9841a4bc6234393275b86d14be495189bb099 Mon Sep 17 00:00:00 2001 From: Lucas TRONCY Date: Tue, 26 Mar 2019 15:49:16 -0700 Subject: [PATCH 06/30] Fixed code from the feedback review --- iquail/installer/installer_osx.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index af4d5f6..53a4615 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -9,13 +9,13 @@ class InstallerOsx(InstallerBase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self._bundle_install_path = '/Applications/' + self.name + '.app' + self._bundle_install_path = os.path.join('Applications', self.name + '.app') """ We need to put a syslink into /usr/local/bin or into a local folder inside the user's home directory""" def _register(self): - bundle = BundleTemplate(self._name) + bundle = BundleTemplate(self.name) bundle.make() - plist = PlistTemplate(self._binary_name, {}) + plist = PlistTemplate(self.binary, {}) plist.make() self._build_launcher() #self.__add_to_path(self.binary, self._binary_name) @@ -37,16 +37,16 @@ def build_symlink_path(self, name): if self.install_systemwide: #TODO setup local installation #final_folder = '/Applications' - final_folder = os.path.join(str(pathlib.Path.home()), '/Applications/' + self._name + '.app/Contents/MacOS/') + final_folder = os.path.join(str(pathlib.Path.home()), 'Applications', self._name + '.app', 'Contents', 'MacOS') else: - final_folder = os.path.join(str(pathlib.Path.home()), '/Applications/' + self._name + '.app/Contents/MacOS/') + final_folder = os.path.join(str(pathlib.Path.home()), 'Applications', self._name + '.app', 'Contents', 'MacOS') return os.path.join(final_folder, name) def _build_launcher(self): - with open(self._bundle_install_path + '/Contents/MacOS/launcher', 'w') as f: + with open(os.path.join(self._bundle_install_path, 'Contents', 'MacOS', 'launcher'), 'w') as f: content = '/usr/local/bin/python3 ~/.iquail/' + self.uid + '/iquail_launcher.py' shebang = '#!/bin/bash\n' f.write(shebang) f.write(content) - st = os.stat(self._bundle_install_path + '/Contents/MacOS/launcher') - os.chmod(self._bundle_install_path + '/Contents/MacOS/launcher', st.st_mode | stat.S_IEXEC) + st = os.stat(os.path.join(self._bundle_install_path, 'Contents', 'MacOS', 'launcher')) + os.chmod(os.stat(os.path.join(self._bundle_install_path, 'Contents', 'MacOS', 'launcher')), st.st_mode | stat.S_IEXEC) From b563fd6ada60a1069e34bc0122ffc138baa3c1e6 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Tue, 26 Mar 2019 18:50:05 -0400 Subject: [PATCH 07/30] Removed a syntax error --- iquail/helper/osx/plist_creator.py | 1 - 1 file changed, 1 deletion(-) diff --git a/iquail/helper/osx/plist_creator.py b/iquail/helper/osx/plist_creator.py index 3ea178f..7ed4983 100644 --- a/iquail/helper/osx/plist_creator.py +++ b/iquail/helper/osx/plist_creator.py @@ -3,7 +3,6 @@ class PlistCreator: def __init__(self, bundle_name: str, plistDict: dict): self.__file = open("/applications/" + bundle_name + ".app/contents/info.plist", "a+") - self.__ self.__plist_dict = { "CFBundleGetInfoString": bundle_name, "CFBundleExecutable": 'launcher', From 206afa33877378925f62e36e1a7c77d3b7a4b2d9 Mon Sep 17 00:00:00 2001 From: Lucas TRONCY Date: Tue, 26 Mar 2019 18:49:41 -0700 Subject: [PATCH 08/30] Fix bundle path --- iquail/installer/installer_osx.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index 53a4615..a0e3736 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -9,13 +9,13 @@ class InstallerOsx(InstallerBase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self._bundle_install_path = os.path.join('Applications', self.name + '.app') + self._bundle_install_path = os.path.join(os.sep, 'Applications', self.name + '.app') """ We need to put a syslink into /usr/local/bin or into a local folder inside the user's home directory""" def _register(self): bundle = BundleTemplate(self.name) bundle.make() - plist = PlistTemplate(self.binary, {}) + plist = PlistTemplate(self._binary_name, {}) plist.make() self._build_launcher() #self.__add_to_path(self.binary, self._binary_name) @@ -49,4 +49,4 @@ def _build_launcher(self): f.write(shebang) f.write(content) st = os.stat(os.path.join(self._bundle_install_path, 'Contents', 'MacOS', 'launcher')) - os.chmod(os.stat(os.path.join(self._bundle_install_path, 'Contents', 'MacOS', 'launcher')), st.st_mode | stat.S_IEXEC) + os.chmod(os.path.join(self._bundle_install_path, 'Contents', 'MacOS', 'launcher'), st.st_mode | stat.S_IEXEC) From 6154eae13615f9bb21cb2e3b462a1f5b06e9d87b Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Mon, 22 Apr 2019 18:14:56 -0400 Subject: [PATCH 09/30] Adding a new feature to parse and write xml files for our OSX install. --- examples/test_osx.py | 3 -- iquail/helper/__init__.py | 2 +- iquail/helper/osx/__init__.py | 3 +- iquail/helper/osx/bundle_template.py | 16 ++++--- iquail/helper/osx/plist_creator.py | 68 ++++++++++++++++++++++++---- iquail/installer/installer_osx.py | 6 +-- 6 files changed, 74 insertions(+), 24 deletions(-) diff --git a/examples/test_osx.py b/examples/test_osx.py index d00ff7f..e3cb89e 100644 --- a/examples/test_osx.py +++ b/examples/test_osx.py @@ -1,9 +1,6 @@ #!/usr/bin/python3 -import os -import os.path import iquail -import platform if iquail.helper.OS_OSX: solution_path = ['MacCalc'] diff --git a/iquail/helper/__init__.py b/iquail/helper/__init__.py index c6ac604..d63a152 100644 --- a/iquail/helper/__init__.py +++ b/iquail/helper/__init__.py @@ -2,4 +2,4 @@ from .file_ignore import FileIgnore, accept_path from .integrity_verifier import IntegrityVerifier, checksum_file from .configuration import Configuration, ConfVar -from .osx import BundleTemplate, PlistTemplate +from .osx import BundleTemplate, PlistTemplate, PlistCreator diff --git a/iquail/helper/osx/__init__.py b/iquail/helper/osx/__init__.py index 772c159..e59be37 100644 --- a/iquail/helper/osx/__init__.py +++ b/iquail/helper/osx/__init__.py @@ -1,2 +1,3 @@ from .bundle_template import BundleTemplate -from .plist_template import PlistTemplate \ No newline at end of file +from .plist_template import PlistTemplate +from .plist_creator import PlistCreator diff --git a/iquail/helper/osx/bundle_template.py b/iquail/helper/osx/bundle_template.py index a57315b..8e3c462 100644 --- a/iquail/helper/osx/bundle_template.py +++ b/iquail/helper/osx/bundle_template.py @@ -2,13 +2,15 @@ class BundleTemplate(): - def __init__(self, CFBundleName): - self.bundle_name = CFBundleName - #TODO refactor name - self.base_dir = "/Applications/" - self.full_path = self.base_dir + self.bundle_name + ".app" - self.names = [self.full_path, self.full_path + "/Contents", self.full_path + "/Contents/MacOS"] + def __init__(self, bundle_name: str, base_dir='/Application'): + self.full_path = os.path.join(base_dir, bundle_name + ".app") + self.names = [ + self.full_path, + os.path.join(self.full_path, 'Contents'), + os.path.join(self.full_path, 'Contents/MacOS'), + os.path.join(self.full_path, 'Contents/Ressources') + ] def make(self): for path in self.names: - os.mkdir(path) \ No newline at end of file + os.mkdir(path) diff --git a/iquail/helper/osx/plist_creator.py b/iquail/helper/osx/plist_creator.py index 7ed4983..cc70816 100644 --- a/iquail/helper/osx/plist_creator.py +++ b/iquail/helper/osx/plist_creator.py @@ -1,8 +1,14 @@ +import os import xml.etree.ElementTree as ET + class PlistCreator: - def __init__(self, bundle_name: str, plistDict: dict): - self.__file = open("/applications/" + bundle_name + ".app/contents/info.plist", "a+") + def __init__(self, bundle_name: str, application_path: str, plist_dict=None): + # The argument plist_dict can't be mutable + if not plist_dict: + plist_dict = {} + self.__filename = os.path.join(application_path, bundle_name + ".app/Contents/info.plist") + self.__data = "" self.__plist_dict = { "CFBundleGetInfoString": bundle_name, "CFBundleExecutable": 'launcher', @@ -12,21 +18,65 @@ def __init__(self, bundle_name: str, plistDict: dict): self.__plist_header = """ - """ - self.__plist_dict.update(plistDict) - - def __del__(self): - self.__file.close() + self.__plist_dict.update(plist_dict) @property def plist_dict(self): return self.__plist_dict + def __make_key_with_text(self, key: str, value: str): + item = ET.Element(key) + item.text = value + return item + + def __indent_tree(self, elem, level=0): + i = "\n" + level * " " + if len(elem): + if not elem.text or not elem.text.strip(): + elem.text = i + " " + if not elem.tail or not elem.tail.strip(): + elem.tail = i + for elem in elem: + self.__indent_tree(elem, level + 1) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + else: + if level and (not elem.tail or not elem.tail.strip()): + elem.tail = i + + def __add_icon(self, root: ET.Element, icon_name: str): + root.append(self.__make_key_with_text('key', 'CFBundleIcons')) + + icon_dict = ET.SubElement(root, 'dict') + icon_dict.append(self.__make_key_with_text('key', 'CFBundlePrimaryIcon')) + + sub_dict = ET.SubElement(icon_dict, 'dict') + sub_dict.append(self.__make_key_with_text('key', 'CFBundleIconFiles')) + array = ET.SubElement(sub_dict, 'array') + string = ET.SubElement(array, 'string') + string.text = icon_name + + sub_dict.append(self.__make_key_with_text('key', 'UIPrerenderedIcon')) + ET.SubElement(sub_dict, 'false') + + def __create_header(self): + self.__data += self.__plist_header + + def __create_tree(self) -> ET.Element: + root = ET.Element('plist', {'version':'1.0'}) + # This is a test, need to use a real + #self.__add_icon(root, 'icon') + return root + def write_file(self): self.__create_header() + tree = self.__create_tree() + self.__indent_tree(tree) + tree_data = ET.tostring(tree, encoding='unicode') + with open(self.__filename, 'w+') as f: + total_data = self.__data + tree_data + f.write(total_data) - def __create_header(self): - self.__file.write(self.__plist_header) diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index a0e3736..1e29735 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -3,7 +3,7 @@ import stat import shutil import pathlib -from ..helper import BundleTemplate, PlistTemplate +from ..helper import BundleTemplate, PlistCreator class InstallerOsx(InstallerBase): @@ -15,8 +15,8 @@ def __init__(self, *args, **kwargs): def _register(self): bundle = BundleTemplate(self.name) bundle.make() - plist = PlistTemplate(self._binary_name, {}) - plist.make() + plist = PlistCreator(self.name, '/Applications', {}) + plist.write_file() self._build_launcher() #self.__add_to_path(self.binary, self._binary_name) From a19b6c86f63ff0fc9a96050e33ebf00133eea4cb Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Mon, 22 Apr 2019 18:15:10 -0400 Subject: [PATCH 10/30] Added new tests for our xml feature --- tests/base_test_osx_bundle.py | 18 ++++++++++++++++++ tests/test_bundle_osx.py | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/base_test_osx_bundle.py create mode 100644 tests/test_bundle_osx.py diff --git a/tests/base_test_osx_bundle.py b/tests/base_test_osx_bundle.py new file mode 100644 index 0000000..67497d2 --- /dev/null +++ b/tests/base_test_osx_bundle.py @@ -0,0 +1,18 @@ +import shutil + +from tests.base_test_case import BaseTestCase +from iquail.helper.osx.bundle_template import BundleTemplate +from iquail.helper.osx.plist_creator import PlistCreator + + +class BaseTestOsxBundle(BaseTestCase): + # The test folder will always be named test.app + def setUp(self): + super(BaseTestOsxBundle, self).setUp() + self._test_folder_path = self.tmp('test.app') + self.plistCreator = PlistCreator('test', self._tmpdir) + self.bt = BundleTemplate('test', self._tmpdir) + self.bt.make() + + def tearDown(self): + shutil.rmtree(self.bt.full_path, ignore_errors=True) diff --git a/tests/test_bundle_osx.py b/tests/test_bundle_osx.py new file mode 100644 index 0000000..228a6ab --- /dev/null +++ b/tests/test_bundle_osx.py @@ -0,0 +1,17 @@ +import os + +from tests.base_test_osx_bundle import BaseTestOsxBundle + + +class TestOsxBundle(BaseTestOsxBundle): + """ + In this test we make sure that the proper folder has the right name and that all the subfolders are created correctly + """ + def test_default_bundle_setup(self): + # Bundle template create a folder appended with .app + assert os.path.exists(self._test_folder_path) + assert os.path.exists(os.path.join(self._test_folder_path, 'Contents')) + + def test_plist_creation(self): + self.plistCreator.write_file() + assert os.path.exists(os.path.join(self._test_folder_path, 'Contents', 'info.plist')) From 310fe69748a3fe7f4cfa7409c7365de697f2b035 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Tue, 23 Apr 2019 00:49:05 -0400 Subject: [PATCH 11/30] Hey we have icons on osx now -> Extra s in resource folder --- iquail/helper/osx/plist_creator.py | 17 +++-------------- tests/base_test_osx_bundle.py | 1 - tests/test_bundle_osx.py | 4 +++- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/iquail/helper/osx/plist_creator.py b/iquail/helper/osx/plist_creator.py index cc70816..48dd929 100644 --- a/iquail/helper/osx/plist_creator.py +++ b/iquail/helper/osx/plist_creator.py @@ -7,7 +7,7 @@ def __init__(self, bundle_name: str, application_path: str, plist_dict=None): # The argument plist_dict can't be mutable if not plist_dict: plist_dict = {} - self.__filename = os.path.join(application_path, bundle_name + ".app/Contents/info.plist") + self.__filename = os.path.join(application_path, bundle_name + ".app/Contents/Info.plist") self.__data = "" self.__plist_dict = { "CFBundleGetInfoString": bundle_name, @@ -46,19 +46,8 @@ def __indent_tree(self, elem, level=0): elem.tail = i def __add_icon(self, root: ET.Element, icon_name: str): - root.append(self.__make_key_with_text('key', 'CFBundleIcons')) - - icon_dict = ET.SubElement(root, 'dict') - icon_dict.append(self.__make_key_with_text('key', 'CFBundlePrimaryIcon')) - - sub_dict = ET.SubElement(icon_dict, 'dict') - sub_dict.append(self.__make_key_with_text('key', 'CFBundleIconFiles')) - array = ET.SubElement(sub_dict, 'array') - string = ET.SubElement(array, 'string') - string.text = icon_name - - sub_dict.append(self.__make_key_with_text('key', 'UIPrerenderedIcon')) - ET.SubElement(sub_dict, 'false') + root.append(self.__make_key_with_text('key', 'CFBundleIconFile')) + root.append(self.__make_key_with_text('string', icon_name)) def __create_header(self): self.__data += self.__plist_header diff --git a/tests/base_test_osx_bundle.py b/tests/base_test_osx_bundle.py index 67497d2..89977a3 100644 --- a/tests/base_test_osx_bundle.py +++ b/tests/base_test_osx_bundle.py @@ -10,7 +10,6 @@ class BaseTestOsxBundle(BaseTestCase): def setUp(self): super(BaseTestOsxBundle, self).setUp() self._test_folder_path = self.tmp('test.app') - self.plistCreator = PlistCreator('test', self._tmpdir) self.bt = BundleTemplate('test', self._tmpdir) self.bt.make() diff --git a/tests/test_bundle_osx.py b/tests/test_bundle_osx.py index 228a6ab..7937418 100644 --- a/tests/test_bundle_osx.py +++ b/tests/test_bundle_osx.py @@ -1,5 +1,6 @@ import os +from iquail.helper.osx.plist_creator import PlistCreator from tests.base_test_osx_bundle import BaseTestOsxBundle @@ -13,5 +14,6 @@ def test_default_bundle_setup(self): assert os.path.exists(os.path.join(self._test_folder_path, 'Contents')) def test_plist_creation(self): - self.plistCreator.write_file() + plist_creator = PlistCreator('test', self._tmpdir) + plist_creator.write_file() assert os.path.exists(os.path.join(self._test_folder_path, 'Contents', 'info.plist')) From 77066337eef370cbe35c2025259135119b48c320 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Tue, 23 Apr 2019 00:57:37 -0400 Subject: [PATCH 12/30] Forgot to commit the file (Couldn't ammend don't know why) --- iquail/helper/osx/bundle_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iquail/helper/osx/bundle_template.py b/iquail/helper/osx/bundle_template.py index 8e3c462..e5365b6 100644 --- a/iquail/helper/osx/bundle_template.py +++ b/iquail/helper/osx/bundle_template.py @@ -8,7 +8,7 @@ def __init__(self, bundle_name: str, base_dir='/Application'): self.full_path, os.path.join(self.full_path, 'Contents'), os.path.join(self.full_path, 'Contents/MacOS'), - os.path.join(self.full_path, 'Contents/Ressources') + os.path.join(self.full_path, 'Contents/Resources') ] def make(self): From d4c9dae102416f79fc9e962e917e41b1cf83b01e Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Tue, 23 Apr 2019 13:39:43 -0400 Subject: [PATCH 13/30] fixed wrong syntax on class declaration --- iquail/helper/osx/bundle_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iquail/helper/osx/bundle_template.py b/iquail/helper/osx/bundle_template.py index e5365b6..3ddd3d1 100644 --- a/iquail/helper/osx/bundle_template.py +++ b/iquail/helper/osx/bundle_template.py @@ -1,7 +1,7 @@ import os -class BundleTemplate(): +class BundleTemplate: def __init__(self, bundle_name: str, base_dir='/Application'): self.full_path = os.path.join(base_dir, bundle_name + ".app") self.names = [ From fee413381bc1e61615d21bf8160cd4a6a32600e5 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Wed, 23 Oct 2019 15:15:16 +0200 Subject: [PATCH 14/30] Auto stash before merge of "mac_compability" and "origin/master" Added ds store to the gitignore --- .gitignore | 3 +++ iquail/installer/installer_osx.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 315ab6f..31fd78b 100644 --- a/.gitignore +++ b/.gitignore @@ -109,3 +109,6 @@ ENV/ # mypy .mypy_cache/ + +#Don't add mac's dsstore +*.DS_Store* diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index 1e29735..b8176e0 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -9,7 +9,7 @@ class InstallerOsx(InstallerBase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self._bundle_install_path = os.path.join(os.sep, 'Applications', self.name + '.app') + self._bundle_install_path = os.path.join(os.sep, 'Applications', self.name + '.app') """ We need to put a syslink into /usr/local/bin or into a local folder inside the user's home directory""" def _register(self): From 7d06807589801f552977def1395e00d972a0f91b Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Thu, 24 Oct 2019 08:09:47 +0200 Subject: [PATCH 15/30] Missing an S to the application's folder --- iquail/helper/osx/bundle_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iquail/helper/osx/bundle_template.py b/iquail/helper/osx/bundle_template.py index 3ddd3d1..f22932f 100644 --- a/iquail/helper/osx/bundle_template.py +++ b/iquail/helper/osx/bundle_template.py @@ -2,7 +2,7 @@ class BundleTemplate: - def __init__(self, bundle_name: str, base_dir='/Application'): + def __init__(self, bundle_name: str, base_dir='/Applications'): self.full_path = os.path.join(base_dir, bundle_name + ".app") self.names = [ self.full_path, From fae2ecced59b3e12edf789233496ee413edbf764 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Thu, 24 Oct 2019 08:10:51 +0200 Subject: [PATCH 16/30] Fixing some variable name and removing old comments --- iquail/controller/controller_console.py | 2 +- iquail/helper/osx/plist_creator.py | 2 -- iquail/installer/installer_osx.py | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/iquail/controller/controller_console.py b/iquail/controller/controller_console.py index cd23aff..aaa974b 100644 --- a/iquail/controller/controller_console.py +++ b/iquail/controller/controller_console.py @@ -74,7 +74,7 @@ def start_uninstall(self): self.manager.uninstall() print("[*] %s successfully removed!" % self.manager.get_name()) self.press_to_exit() - except: + except Exception as e: print( "[*] Unknown error while uninstalling %s" % self.manager.get_name()) self.press_to_exit() diff --git a/iquail/helper/osx/plist_creator.py b/iquail/helper/osx/plist_creator.py index 48dd929..f6ed0de 100644 --- a/iquail/helper/osx/plist_creator.py +++ b/iquail/helper/osx/plist_creator.py @@ -54,8 +54,6 @@ def __create_header(self): def __create_tree(self) -> ET.Element: root = ET.Element('plist', {'version':'1.0'}) - # This is a test, need to use a real - #self.__add_icon(root, 'icon') return root def write_file(self): diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index b8176e0..4dae0cd 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -18,7 +18,7 @@ def _register(self): plist = PlistCreator(self.name, '/Applications', {}) plist.write_file() self._build_launcher() - #self.__add_to_path(self.binary, self._binary_name) + #self.add_to_path(self.binary, self._binary_name) def _unregister(self): self.__remove_from_path(self.binary) @@ -26,6 +26,7 @@ def _unregister(self): def _registered(self): if not os.path.exists(self.build_symlink_path(self.binary)): return False + return True def __add_to_path(self, binary, name): os.symlink(binary, self.build_symlink_path(name)) From 0ce224c2493536fce419c69af957417a0b004697 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Thu, 24 Oct 2019 08:23:34 +0200 Subject: [PATCH 17/30] Added key/value adding in plcreator --- iquail/helper/osx/plist_creator.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/iquail/helper/osx/plist_creator.py b/iquail/helper/osx/plist_creator.py index f6ed0de..88f9967 100644 --- a/iquail/helper/osx/plist_creator.py +++ b/iquail/helper/osx/plist_creator.py @@ -59,11 +59,18 @@ def __create_tree(self) -> ET.Element: def write_file(self): self.__create_header() tree = self.__create_tree() + self.__write_dict_to_file(tree) self.__indent_tree(tree) tree_data = ET.tostring(tree, encoding='unicode') with open(self.__filename, 'w+') as f: total_data = self.__data + tree_data f.write(total_data) + def __write_dict_to_file(self, root: ET.Element): + for key, value in self.plist_dict.items(): + root.append(self.__make_key_with_text('key', key)) + root.append(self.__make_key_with_text('string', value)) + + From aea3b8268b1e38c089a24944fe31945d67a47c6f Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Thu, 24 Oct 2019 08:34:59 +0200 Subject: [PATCH 18/30] We are now creating valid .plist files --- iquail/helper/osx/plist_creator.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/iquail/helper/osx/plist_creator.py b/iquail/helper/osx/plist_creator.py index 88f9967..fa31ad1 100644 --- a/iquail/helper/osx/plist_creator.py +++ b/iquail/helper/osx/plist_creator.py @@ -67,10 +67,11 @@ def write_file(self): f.write(total_data) def __write_dict_to_file(self, root: ET.Element): + elem = ET.Element('dict') for key, value in self.plist_dict.items(): - root.append(self.__make_key_with_text('key', key)) - root.append(self.__make_key_with_text('string', value)) - + elem.append(self.__make_key_with_text('key', key)) + elem.append(self.__make_key_with_text('string', value)) + root.append(elem) From 8532d48c10fe305b78f012adb71e9811459b70d1 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Thu, 24 Oct 2019 08:56:23 +0200 Subject: [PATCH 19/30] Skipping IOS test on different platforms --- tests/base_test_osx_bundle.py | 29 ++++++++++++++++------------- tests/test_bundle_osx.py | 31 +++++++++++++++++-------------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/tests/base_test_osx_bundle.py b/tests/base_test_osx_bundle.py index 89977a3..8bd4be2 100644 --- a/tests/base_test_osx_bundle.py +++ b/tests/base_test_osx_bundle.py @@ -1,17 +1,20 @@ -import shutil +import iquail.helper -from tests.base_test_case import BaseTestCase -from iquail.helper.osx.bundle_template import BundleTemplate -from iquail.helper.osx.plist_creator import PlistCreator +if iquail.helper.OS_OSX: + import shutil + from tests.base_test_case import BaseTestCase + from iquail.helper.osx.bundle_template import BundleTemplate + from iquail.helper.osx.plist_creator import PlistCreator -class BaseTestOsxBundle(BaseTestCase): - # The test folder will always be named test.app - def setUp(self): - super(BaseTestOsxBundle, self).setUp() - self._test_folder_path = self.tmp('test.app') - self.bt = BundleTemplate('test', self._tmpdir) - self.bt.make() - def tearDown(self): - shutil.rmtree(self.bt.full_path, ignore_errors=True) + class BaseTestOsxBundle(BaseTestCase): + # The test folder will always be named test.app + def setUp(self): + super(BaseTestOsxBundle, self).setUp() + self._test_folder_path = self.tmp('test.app') + self.bt = BundleTemplate('test', self._tmpdir) + self.bt.make() + + def tearDown(self): + shutil.rmtree(self.bt.full_path, ignore_errors=True) diff --git a/tests/test_bundle_osx.py b/tests/test_bundle_osx.py index 7937418..71ec95c 100644 --- a/tests/test_bundle_osx.py +++ b/tests/test_bundle_osx.py @@ -1,19 +1,22 @@ -import os +import iquail.helper -from iquail.helper.osx.plist_creator import PlistCreator -from tests.base_test_osx_bundle import BaseTestOsxBundle +if iquail.helper.OS_OSX: + import os + from iquail.helper.osx.plist_creator import PlistCreator + from tests.base_test_osx_bundle import BaseTestOsxBundle -class TestOsxBundle(BaseTestOsxBundle): - """ + + class TestOsxBundle(BaseTestOsxBundle): + """ In this test we make sure that the proper folder has the right name and that all the subfolders are created correctly - """ - def test_default_bundle_setup(self): - # Bundle template create a folder appended with .app - assert os.path.exists(self._test_folder_path) - assert os.path.exists(os.path.join(self._test_folder_path, 'Contents')) + """ + def test_default_bundle_setup(self): + # Bundle template create a folder appended with .app + assert os.path.exists(self._test_folder_path) + assert os.path.exists(os.path.join(self._test_folder_path, 'Contents')) - def test_plist_creation(self): - plist_creator = PlistCreator('test', self._tmpdir) - plist_creator.write_file() - assert os.path.exists(os.path.join(self._test_folder_path, 'Contents', 'info.plist')) + def test_plist_creation(self): + plist_creator = PlistCreator('test', self._tmpdir) + plist_creator.write_file() + assert os.path.exists(os.path.join(self._test_folder_path, 'Contents', 'info.plist')) From aed062db098967ac825e916497d442af99569a46 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Thu, 24 Oct 2019 09:01:47 +0200 Subject: [PATCH 20/30] removed an old file. --- iquail/helper/__init__.py | 2 +- iquail/helper/osx/__init__.py | 1 - iquail/helper/osx/plist_template.py | 42 ----------------------------- 3 files changed, 1 insertion(+), 44 deletions(-) delete mode 100644 iquail/helper/osx/plist_template.py diff --git a/iquail/helper/__init__.py b/iquail/helper/__init__.py index e5017ba..e55ad97 100644 --- a/iquail/helper/__init__.py +++ b/iquail/helper/__init__.py @@ -3,4 +3,4 @@ from .integrity_verifier import IntegrityVerifier, checksum_file from .configuration import Configuration, ConfVar from .linux_polkit_file import polkit_install, polkit_check -from .osx import BundleTemplate, PlistTemplate, PlistCreator +from .osx import BundleTemplate, PlistCreator diff --git a/iquail/helper/osx/__init__.py b/iquail/helper/osx/__init__.py index e59be37..8131754 100644 --- a/iquail/helper/osx/__init__.py +++ b/iquail/helper/osx/__init__.py @@ -1,3 +1,2 @@ from .bundle_template import BundleTemplate -from .plist_template import PlistTemplate from .plist_creator import PlistCreator diff --git a/iquail/helper/osx/plist_template.py b/iquail/helper/osx/plist_template.py deleted file mode 100644 index 3a03e6f..0000000 --- a/iquail/helper/osx/plist_template.py +++ /dev/null @@ -1,42 +0,0 @@ -import os - -#TODO : add full PATH to spotlight env to access python3 -class PlistTemplate(): - def __init__(self, CFBundleName, plistDict): - self.file = open("/Applications/" + CFBundleName + ".app/Contents/Info.plist", "a+") - self.plist_dict = dict( - CFBundleGetInfoString=CFBundleName, - CFBundleExecutable='launcher', - CFBundleIdentifier=CFBundleName, - CFBundleName=CFBundleName - ) - self.plist_dict.update(plistDict) - - def make(self): - self._createHeader() - for key, value in self.plist_dict.items(): - self._writeProperty(key, value, "string") - self._createFooter() - - def getInfoPlist(self): - return self.plist_dict - - def _createHeader(self): - self.plist_header = """ - - - - - """ - self.file.write(self.plist_header) - - def _createFooter(self): - self.plist_footer = """ - - - """ - self.file.write(self.plist_footer) - - def _writeProperty(self, key, value, typeValue): - self.file.write(" " + key + "\n") - self.file.write(" <" + typeValue + ">" + value + "\n") \ No newline at end of file From 850ec114550418770a0413cef273eeb01a64eb5a Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Thu, 24 Oct 2019 09:07:59 +0200 Subject: [PATCH 21/30] Refactored the plist_creator.py file --- iquail/helper/osx/plist_creator.py | 23 ++++++++++++----------- iquail/installer/installer_osx.py | 2 +- tests/test_bundle_osx.py | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/iquail/helper/osx/plist_creator.py b/iquail/helper/osx/plist_creator.py index fa31ad1..c2d6bc2 100644 --- a/iquail/helper/osx/plist_creator.py +++ b/iquail/helper/osx/plist_creator.py @@ -49,29 +49,30 @@ def __add_icon(self, root: ET.Element, icon_name: str): root.append(self.__make_key_with_text('key', 'CFBundleIconFile')) root.append(self.__make_key_with_text('string', icon_name)) - def __create_header(self): - self.__data += self.__plist_header - def __create_tree(self) -> ET.Element: root = ET.Element('plist', {'version':'1.0'}) return root - def write_file(self): - self.__create_header() + def build_tree_and_write_file(self): tree = self.__create_tree() - self.__write_dict_to_file(tree) + + self.__data += self.__plist_header + self.__add_dict_content_to_tree(tree) self.__indent_tree(tree) - tree_data = ET.tostring(tree, encoding='unicode') - with open(self.__filename, 'w+') as f: - total_data = self.__data + tree_data - f.write(total_data) + self.__write_to_file(tree) - def __write_dict_to_file(self, root: ET.Element): + def __add_dict_content_to_tree(self, root: ET.Element): elem = ET.Element('dict') for key, value in self.plist_dict.items(): elem.append(self.__make_key_with_text('key', key)) elem.append(self.__make_key_with_text('string', value)) root.append(elem) + def __write_to_file(self, tree): + tree_data = ET.tostring(tree, encoding='unicode') + with open(self.__filename, 'w+') as f: + total_data = self.__data + tree_data + f.write(total_data) + diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index 4dae0cd..a2885c6 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -16,7 +16,7 @@ def _register(self): bundle = BundleTemplate(self.name) bundle.make() plist = PlistCreator(self.name, '/Applications', {}) - plist.write_file() + plist.build_tree_and_write_file() self._build_launcher() #self.add_to_path(self.binary, self._binary_name) diff --git a/tests/test_bundle_osx.py b/tests/test_bundle_osx.py index 71ec95c..a775ca5 100644 --- a/tests/test_bundle_osx.py +++ b/tests/test_bundle_osx.py @@ -18,5 +18,5 @@ def test_default_bundle_setup(self): def test_plist_creation(self): plist_creator = PlistCreator('test', self._tmpdir) - plist_creator.write_file() + plist_creator.build_tree_and_write_file() assert os.path.exists(os.path.join(self._test_folder_path, 'Contents', 'info.plist')) From 96f2edf0eaec404c1c5f404d5c424b7ff9f813f8 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Thu, 24 Oct 2019 11:39:35 +0200 Subject: [PATCH 22/30] Changed the error message when tkinter is not found --- iquail/controller/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/iquail/controller/__init__.py b/iquail/controller/__init__.py index a2470b7..808ce69 100644 --- a/iquail/controller/__init__.py +++ b/iquail/controller/__init__.py @@ -1,6 +1,8 @@ +import sys + from .controller_base import ControllerBase try: from .controller_tkinter import ControllerTkinter -except: - print("No display found or tkinter missing, console mode enabled !") +except ImportError as e: + print(f"Tkinter not found....", file=sys.stderr) from .controller_console import ControllerConsole From b3c39e34d6f4db8584b9970716fe11f12423e2a0 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Thu, 24 Oct 2019 11:40:16 +0200 Subject: [PATCH 23/30] Added a todo --- iquail/installer/installer_osx.py | 1 + 1 file changed, 1 insertion(+) diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index a2885c6..1b4c8af 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -12,6 +12,7 @@ def __init__(self, *args, **kwargs): self._bundle_install_path = os.path.join(os.sep, 'Applications', self.name + '.app') """ We need to put a syslink into /usr/local/bin or into a local folder inside the user's home directory""" + """ TODO: Add the icon to the bundle""" def _register(self): bundle = BundleTemplate(self.name) bundle.make() From 73f5bd9cae08ebaf9a5a891859b86bc5dd1a1172 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Wed, 11 Dec 2019 21:09:32 +0100 Subject: [PATCH 24/30] Cleaned the installer OSX file and added local installation --- iquail/installer/installer_osx.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index 1b4c8af..f784312 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -9,14 +9,14 @@ class InstallerOsx(InstallerBase): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self._bundle_install_path = os.path.join(os.sep, 'Applications', self.name + '.app') + self._bundle_install_path = os.path.join(self._get_application_folder_path(), self.name + '.app') """ We need to put a syslink into /usr/local/bin or into a local folder inside the user's home directory""" """ TODO: Add the icon to the bundle""" def _register(self): - bundle = BundleTemplate(self.name) + bundle = BundleTemplate(self.name, base_dir=self._get_application_folder_path()) bundle.make() - plist = PlistCreator(self.name, '/Applications', {}) + plist = PlistCreator(self.name, self._get_application_folder_path(), {}) plist.build_tree_and_write_file() self._build_launcher() #self.add_to_path(self.binary, self._binary_name) @@ -25,29 +25,29 @@ def _unregister(self): self.__remove_from_path(self.binary) def _registered(self): - if not os.path.exists(self.build_symlink_path(self.binary)): + if not os.path.exists(self.build_folder_path(self.binary)): return False return True def __add_to_path(self, binary, name): - os.symlink(binary, self.build_symlink_path(name)) + os.symlink(binary, self.build_folder_path(name)) def __remove_from_path(self, name): shutil.rmtree(self._bundle_install_path) - def build_symlink_path(self, name): + def _get_application_folder_path(self): if self.install_systemwide: - #TODO setup local installation - #final_folder = '/Applications' - final_folder = os.path.join(str(pathlib.Path.home()), 'Applications', self._name + '.app', 'Contents', 'MacOS') - else: - final_folder = os.path.join(str(pathlib.Path.home()), 'Applications', self._name + '.app', 'Contents', 'MacOS') + return os.path.join(os.sep, 'Applications') + return os.path.join(str(pathlib.Path.home()), 'Applications') + + def build_folder_path(self, name): + final_folder = os.path.join(self._get_application_folder_path(), self._name + '.app', 'Contents', 'MacOS') return os.path.join(final_folder, name) def _build_launcher(self): with open(os.path.join(self._bundle_install_path, 'Contents', 'MacOS', 'launcher'), 'w') as f: - content = '/usr/local/bin/python3 ~/.iquail/' + self.uid + '/iquail_launcher.py' - shebang = '#!/bin/bash\n' + shebang = '#!/usr/bin/env bash\n' + content = '/usr/bin/env python3 ~/.iquail/' + self.uid + '/iquail_launcher.py' f.write(shebang) f.write(content) st = os.stat(os.path.join(self._bundle_install_path, 'Contents', 'MacOS', 'launcher')) From 8c9dd30b9c4fa9d87d9f68ee41b5eb5972c2326f Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Wed, 11 Dec 2019 21:09:32 +0100 Subject: [PATCH 25/30] Cleaned the installer OSX file and added local installation --- iquail/installer/installer_osx.py | 1 - 1 file changed, 1 deletion(-) diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index f784312..ecc1806 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -11,7 +11,6 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._bundle_install_path = os.path.join(self._get_application_folder_path(), self.name + '.app') - """ We need to put a syslink into /usr/local/bin or into a local folder inside the user's home directory""" """ TODO: Add the icon to the bundle""" def _register(self): bundle = BundleTemplate(self.name, base_dir=self._get_application_folder_path()) From 3239bcd350cceb9ebe387e78e5fa64ef41df28d1 Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Wed, 11 Dec 2019 21:39:47 +0100 Subject: [PATCH 26/30] Refactoring --- iquail/installer/installer_osx.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index ecc1806..60518be 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -18,10 +18,9 @@ def _register(self): plist = PlistCreator(self.name, self._get_application_folder_path(), {}) plist.build_tree_and_write_file() self._build_launcher() - #self.add_to_path(self.binary, self._binary_name) def _unregister(self): - self.__remove_from_path(self.binary) + shutil.rmtree(self._bundle_install_path) def _registered(self): if not os.path.exists(self.build_folder_path(self.binary)): @@ -31,9 +30,6 @@ def _registered(self): def __add_to_path(self, binary, name): os.symlink(binary, self.build_folder_path(name)) - def __remove_from_path(self, name): - shutil.rmtree(self._bundle_install_path) - def _get_application_folder_path(self): if self.install_systemwide: return os.path.join(os.sep, 'Applications') @@ -46,7 +42,7 @@ def build_folder_path(self, name): def _build_launcher(self): with open(os.path.join(self._bundle_install_path, 'Contents', 'MacOS', 'launcher'), 'w') as f: shebang = '#!/usr/bin/env bash\n' - content = '/usr/bin/env python3 ~/.iquail/' + self.uid + '/iquail_launcher.py' + content = '/usr/bin/env python3 ' + self.launcher_binary f.write(shebang) f.write(content) st = os.stat(os.path.join(self._bundle_install_path, 'Contents', 'MacOS', 'launcher')) From 252a4b0c046bd04822eaf51b2113578b39fea9be Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Wed, 11 Dec 2019 21:43:52 +0100 Subject: [PATCH 27/30] Made the ios import exclusive to ios --- iquail/helper/__init__.py | 3 ++- iquail/installer/installer_osx.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/iquail/helper/__init__.py b/iquail/helper/__init__.py index e55ad97..9a24852 100644 --- a/iquail/helper/__init__.py +++ b/iquail/helper/__init__.py @@ -3,4 +3,5 @@ from .integrity_verifier import IntegrityVerifier, checksum_file from .configuration import Configuration, ConfVar from .linux_polkit_file import polkit_install, polkit_check -from .osx import BundleTemplate, PlistCreator +if OS_OSX: + from .osx import BundleTemplate, PlistCreator diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index 60518be..d6b1805 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -14,6 +14,7 @@ def __init__(self, *args, **kwargs): """ TODO: Add the icon to the bundle""" def _register(self): bundle = BundleTemplate(self.name, base_dir=self._get_application_folder_path()) + icon = self.get_install_path(self._icon) bundle.make() plist = PlistCreator(self.name, self._get_application_folder_path(), {}) plist.build_tree_and_write_file() From f9a0ebc8afef74c436f0d7101bf522e4bcf5346d Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Wed, 11 Dec 2019 22:08:32 +0100 Subject: [PATCH 28/30] Added support for user designed icon on the OSx installation --- examples/test_osx.py | 2 +- iquail/helper/osx/bundle_template.py | 8 ++++++++ iquail/installer/installer_osx.py | 5 +++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/examples/test_osx.py b/examples/test_osx.py index e3cb89e..0d1e18b 100644 --- a/examples/test_osx.py +++ b/examples/test_osx.py @@ -9,7 +9,7 @@ iquail.Installer( name='MacCalc', publisher='test', - icon='icon.jpeg', + icon='icon.icns', binary='maccalc', console=True, ), diff --git a/iquail/helper/osx/bundle_template.py b/iquail/helper/osx/bundle_template.py index f22932f..25bc43d 100644 --- a/iquail/helper/osx/bundle_template.py +++ b/iquail/helper/osx/bundle_template.py @@ -1,4 +1,5 @@ import os +import shutil class BundleTemplate: @@ -10,6 +11,13 @@ def __init__(self, bundle_name: str, base_dir='/Applications'): os.path.join(self.full_path, 'Contents/MacOS'), os.path.join(self.full_path, 'Contents/Resources') ] + def installIcon(self, icon_file_name, icon_quail_path): + dest_path = os.path.join(self.full_path, 'Contents/Resources', icon_file_name) + try: + shutil.copy(icon_quail_path, dest_path) + except FileNotFoundError as e: + print("Error icon file {} was not found when installing".format(icon_quail_path)) + def make(self): for path in self.names: diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index d6b1805..2a5f121 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -14,9 +14,10 @@ def __init__(self, *args, **kwargs): """ TODO: Add the icon to the bundle""" def _register(self): bundle = BundleTemplate(self.name, base_dir=self._get_application_folder_path()) - icon = self.get_install_path(self._icon) + icon_quail_path = self.get_solution_icon() bundle.make() - plist = PlistCreator(self.name, self._get_application_folder_path(), {}) + bundle.installIcon(self._icon, icon_quail_path) + plist = PlistCreator(self.name, self._get_application_folder_path(), {'CFBundleIconFile': self._icon}) plist.build_tree_and_write_file() self._build_launcher() From 3332f31c48cb7a7984b0f0f2eafc258289675bbd Mon Sep 17 00:00:00 2001 From: PEAU Clement Date: Thu, 12 Dec 2019 17:53:57 +0100 Subject: [PATCH 29/30] added github full solution handling --- examples/test_github.py | 40 ++++++++++++++++++++----------- iquail/installer/installer_osx.py | 25 ++++++++++++------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/examples/test_github.py b/examples/test_github.py index 9297a8d..5b2d0c8 100755 --- a/examples/test_github.py +++ b/examples/test_github.py @@ -2,19 +2,31 @@ import iquail -if not iquail.helper.OS_WINDOWS: +if iquail.helper.OS_LINUX: raise AssertionError("This test solution is windows only") - -iquail.run( - solution=iquail.SolutionGitHub("cmder_mini.zip", "https://github.com/cmderdev/cmder"), - installer=iquail.Installer( - publisher='cmderdev', - name='Cmder', - icon='Cmder.exe', - binary='Cmder.exe', - console=False - ), - builder=iquail.builder.Builder( - iquail.builder.CmdIcon('icon.ico') +if iquail.helper.OS_WINDOWS: + iquail.run( + solution=iquail.SolutionGitHub("cmder_mini.zip", "https://github.com/cmderdev/cmder"), + installer=iquail.Installer( + publisher='cmderdev', + name='Cmder', + icon='Cmder.exe', + binary='Cmder.exe', + console=False + ), + builder=iquail.builder.Builder( + iquail.builder.CmdIcon('icon.ico') + )) +if iquail.helper.OS_OSX: + iquail.run( + solution=iquail.SolutionGitHub("Console.app.zip", "https://github.com/macmade/Console"), + installer=iquail.Installer( + name='Console', + publisher='MacMade', + full_app=True, + binary='Console.app', + icon='', + console=True + ), + builder=iquail.builder.Builder() ) -) diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index 2a5f121..e0701dd 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -7,19 +7,28 @@ class InstallerOsx(InstallerBase): - def __init__(self, *args, **kwargs): + def __init__(self, full_app, *args, **kwargs): super().__init__(*args, **kwargs) self._bundle_install_path = os.path.join(self._get_application_folder_path(), self.name + '.app') + self.is_full_app = full_app """ TODO: Add the icon to the bundle""" def _register(self): - bundle = BundleTemplate(self.name, base_dir=self._get_application_folder_path()) - icon_quail_path = self.get_solution_icon() - bundle.make() - bundle.installIcon(self._icon, icon_quail_path) - plist = PlistCreator(self.name, self._get_application_folder_path(), {'CFBundleIconFile': self._icon}) - plist.build_tree_and_write_file() - self._build_launcher() + if self.is_full_app: + shutil.copytree(self.binary, os.path.join(self._get_application_folder_path(), self._binary_name)) + launcher_path = os.path.join(self._bundle_install_path, 'Contents', 'MacOS', self.name) + st = os.stat(launcher_path) + os.chmod(launcher_path, st.st_mode | stat.S_IEXEC) + return + else: + bundle = BundleTemplate(self.name, base_dir=self._get_application_folder_path()) + icon_quail_path = self.get_solution_icon() + bundle.make() + if self._icon: + bundle.installIcon(self._icon, icon_quail_path) + plist = PlistCreator(self.name, self._get_application_folder_path(), {'CFBundleIconFile': self._icon}) + plist.build_tree_and_write_file() + self._build_launcher() def _unregister(self): shutil.rmtree(self._bundle_install_path) From 83bd11d0480de4c570048ccb4539833008b9282e Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 12 Dec 2019 17:57:12 +0100 Subject: [PATCH 30/30] fix bugs about PATH for local binaries, added eexample for PKG with GUI --- examples/vagrant_gui.py | 46 +++++++++++++++++++++++++++++++ iquail/installer/installer_osx.py | 18 ++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 examples/vagrant_gui.py diff --git a/examples/vagrant_gui.py b/examples/vagrant_gui.py new file mode 100644 index 0000000..b35071e --- /dev/null +++ b/examples/vagrant_gui.py @@ -0,0 +1,46 @@ +#!/usr/bin/python3 +import os +import iquail +import logging + + +logging.basicConfig( + level=logging.DEBUG, + filename=os.path.join(os.path.dirname(__file__), '..', 'iquail.log'), +) + +if not iquail.helper.OS_OSX: + raise AssertionError("This test solution is macOs only") + + +class FrameSelectMiniOrFull(iquail.controller_tkinter.FrameBaseConfigure): + def __init__(self, parent, controller): + super().__init__(parent, controller) + self.version_selected = self.add_combobox("Which version would you like to install?", + ('2.2.6', '2.2.6')) + + def next_pressed(self): + print(self.version_selected.get()) + version = self.version_selected.get().lower() + zip = "cmder_mini.zip" if version == "mini" else "cmder.zip" + self.manager.config.set("zip_url", zip) + self.controller.switch_to_install_frame() + +iquail.run( + solution=iquail.SolutionLocal(['Vagrant']), + installer=iquail.Installer( + publisher='HashiCorp', + name='vagrant', + icon='vagrant.pkg', + binary='vagrant.pkg', + console=False, + launch_with_quail=True, + ), + builder=iquail.builder.Builder( + iquail.builder.CmdIcon('icon.ico'), + iquail.builder.CmdNoconsole() + ), + controller=iquail.ControllerTkinter( + install_custom_frame=FrameSelectMiniOrFull), + conf_ignore=["config/*"] +) diff --git a/iquail/installer/installer_osx.py b/iquail/installer/installer_osx.py index 2a5f121..1c32655 100644 --- a/iquail/installer/installer_osx.py +++ b/iquail/installer/installer_osx.py @@ -13,6 +13,9 @@ def __init__(self, *args, **kwargs): """ TODO: Add the icon to the bundle""" def _register(self): + if (self._should_register_as_pkg()): + self._register_as_pkg() + return bundle = BundleTemplate(self.name, base_dir=self._get_application_folder_path()) icon_quail_path = self.get_solution_icon() bundle.make() @@ -22,6 +25,9 @@ def _register(self): self._build_launcher() def _unregister(self): + if (self._should_register_as_pkg()): + #self._register_as_pkg() + return shutil.rmtree(self._bundle_install_path) def _registered(self): @@ -37,6 +43,18 @@ def _get_application_folder_path(self): return os.path.join(os.sep, 'Applications') return os.path.join(str(pathlib.Path.home()), 'Applications') + def _should_register_as_pkg(self): + if (self.binary.lower().endswith(".pkg")): + return True + return False + + def _register_as_pkg(self): + path = os.path.join(self._solution_path, self.binary) + pkg_installation = "installer -pkg " + path + " -target /" + print(path) + print(pkg_installation) + os.system("/usr/bin/osascript -e 'do shell script \"" + pkg_installation + "\" with administrator privileges'") + def build_folder_path(self, name): final_folder = os.path.join(self._get_application_folder_path(), self._name + '.app', 'Contents', 'MacOS') return os.path.join(final_folder, name)