From 726878ae242fc6146a54df649db613eb73e757c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Wed, 18 Dec 2019 12:35:31 -0300 Subject: [PATCH] [wgem] updating environment components --- bauh/gems/web/controller.py | 19 ++-- bauh/gems/web/environment.py | 180 +++++++++++------------------- bauh/gems/web/resources/locale/en | 2 +- bauh/view/qt/confirmation.py | 7 +- 4 files changed, 79 insertions(+), 129 deletions(-) diff --git a/bauh/gems/web/controller.py b/bauh/gems/web/controller.py index 7c5883c1..a83c5d4a 100644 --- a/bauh/gems/web/controller.py +++ b/bauh/gems/web/controller.py @@ -476,17 +476,17 @@ class WebApplicationManager(SoftwareManager): watcher.change_substatus(self.i18n['web.env.checking']) handler = ProcessHandler(watcher) - env_settings, to_update = self.env_updater.check_environment(app=pkg, is_x86_x64_arch=self.context.is_system_x86_64()) + env_settings = self.env_updater.read_settings() + local_config = read_config() + env_components = self.env_updater.check_environment(app=pkg, local_config=local_config, env=env_settings, is_x86_x64_arch=self.context.is_system_x86_64()) + comps_to_update = [c for c in env_components if c.update] - if to_update: - if not self._ask_update_permission(to_update, watcher): - return False - - if not self.env_updater.update(components=to_update, handler=handler): - watcher.show_message(title=self.i18n['error'], body=self.i18n['web.env.error'].format(bold(pkg.name)), type_=MessageType.ERROR) + if comps_to_update and not self._ask_update_permission(comps_to_update, watcher): return False - # TODO stopped here + if not self.env_updater.update(components=comps_to_update, handler=handler): + watcher.show_message(title=self.i18n['error'], body=self.i18n['web.env.error'].format(bold(pkg.name)), type_=MessageType.ERROR) + return False Path(INSTALLED_PATH).mkdir(parents=True, exist_ok=True) @@ -506,9 +506,10 @@ class WebApplicationManager(SoftwareManager): watcher.change_substatus(self.i18n['web.install.substatus.call_nativefier'].format(bold('nativefier'))) + electron_version = next((c for c in env_components if c.id == 'electron')).version installed = handler.handle_simple(nativefier.install(url=pkg.url, name=app_id, output_dir=app_dir, electron_version=electron_version, - system=system_env, + system=local_config['environment']['system'], cwd=INSTALLED_PATH, extra_options=install_options)) diff --git a/bauh/gems/web/environment.py b/bauh/gems/web/environment.py index d6ef6612..c17b6453 100644 --- a/bauh/gems/web/environment.py +++ b/bauh/gems/web/environment.py @@ -25,12 +25,13 @@ from bauh.view.util.translation import I18n class EnvironmentComponent: - def __init__(self, id: str, name: str, size: str, version: str, url: str): + def __init__(self, id: str, name: str, size: str, version: str, url: str, update: bool = False): self.id = id self.name = name self.size = size self.version = version self.url = url + self.update = update class EnvironmentUpdater: @@ -78,7 +79,6 @@ class EnvironmentUpdater: except: self.logger.error('Could not delete file {}'.format(tarf_path)) - def check_node_installed(self, version: str) -> bool: if not os.path.exists(NODE_DIR_PATH): return False @@ -135,34 +135,27 @@ class EnvironmentUpdater: self.logger.error('Could not delete the dir {}'.format(NODE_DIR_PATH)) return False - def _install_nativefier(self, version: str, handler: ProcessHandler) -> bool: - self.logger.info("Installing nativefier") + def _install_node_lib(self, name: str, version: str, handler: ProcessHandler): + lib_repr = '{}{}'.format(name, '@{}'.format(version) if version else '') + self.logger.info("Installing {}".format(lib_repr)) if handler and handler.watcher: - handler.watcher.change_substatus(self.i18n['web.environment.install'].format(bold('nativefier'))) + handler.watcher.change_substatus(self.i18n['web.environment.install'].format(bold(lib_repr))) - proc = SimpleProcess([NPM_BIN_PATH, 'install', 'nativefier@{}'.format(version)], cwd=ENV_PATH, extra_paths=NODE_PATHS) + proc = SimpleProcess([NPM_BIN_PATH, 'install', lib_repr], cwd=ENV_PATH, extra_paths=NODE_PATHS) - if handler: - installed = handler.handle_simple(proc)[0] + installed = handler.handle_simple(proc)[0] - if installed: - self.logger.info("nativifier {} successfully installed".format(version)) + if installed: + self.logger.info("{} successfully installed".format(lib_repr)) - return installed - else: - proc.instance.wait() + return installed - if self._is_nativefier_installed(): - self.logger.info("nativefier {} installed".format(version)) - return True - else: - self.logger.error("Could not install nativefier {}".format(version)) - for err in proc.instance.stdout: - if err: - print(err.decode()) + def _install_nativefier(self, version: str, handler: ProcessHandler) -> bool: + success = self._install_node_lib('nativefier', version, handler) - return False + if success: + return self._is_nativefier_installed() def _is_nativefier_installed(self) -> bool: return os.path.exists(NATIVEFIER_BIN_PATH) @@ -197,19 +190,20 @@ class EnvironmentUpdater: return True def download_electron(self, version: str, url: str, watcher: ProcessWatcher) -> bool: + Path(ELECTRON_PATH).mkdir(parents=True, exist_ok=True) self.logger.info("Downloading Electron {}".format(version)) electron_path = '{}/{}'.format(ELECTRON_PATH, url.split('/')[-1]) return self.file_downloader.download(file_url=url, watcher=watcher, output_path=electron_path, cwd=ELECTRON_PATH) def download_electron_sha256(self, version: str, url: str, watcher: ProcessWatcher) -> bool: self.logger.info("Downloading Electron {} sha526".format(version)) - sha256_path = '{}/{}'.format(ELECTRON_PATH, url.split('/')[-1]) + sha256_path = '{}/{}'.format(ELECTRON_PATH, url.split('/')[-1]) + '-{}'.format(version) return self.file_downloader.download(file_url=url, watcher=watcher, output_path=sha256_path, cwd=ELECTRON_PATH) def _get_electron_url(self, version: str, is_x86_x64_arch: bool) -> str: return ELECTRON_DOWNLOAD_URL.format(version=version, arch='x64' if is_x86_x64_arch else 'ia32') - def check_installed_electron(self, version: str, is_x86_x64_arch: bool) -> Dict[str, bool]: + def check_electron_installed(self, version: str, is_x86_x64_arch: bool) -> Dict[str, bool]: self.logger.info("Checking if Electron {} is installed".format(version)) res = {'electron': False, 'sha256': False} @@ -222,8 +216,11 @@ class EnvironmentUpdater: file_name = self._get_electron_url(version, is_x86_x64_arch).split('/')[-1] res['electron'] = bool([f for f in files if f == file_name]) - file_name = ELECTRON_SHA256_URL.split('/')[-1] - res['sha256'] = bool([f for f in files if f == file_name]) + if not res['electron']: + res['sha256'] = True + else: + file_name = ELECTRON_SHA256_URL.split('/')[-1] + '-{}'.format(version) + res['sha256'] = bool([f for f in files if f == file_name]) else: self.logger.info('No Electron file found in {}'.format(ELECTRON_PATH)) @@ -249,23 +246,7 @@ class EnvironmentUpdater: except requests.exceptions.ConnectionError: return - def _fill_electron_to_install(self, electron_version: str, x86_x64: bool, output: List[EnvironmentComponent]): - electron_url = self._get_electron_url(version=electron_version, is_x86_x64_arch=x86_x64) - output.append(EnvironmentComponent(name=electron_url.split('/')[-1], - version=electron_version, - url=electron_url, - size=self.http_client.get_content_length(electron_url), - id='electron')) - - def _fill_electron_sha256_to_install(self, electron_version: str, output: List[EnvironmentComponent]): - sha_url = ELECTRON_SHA256_URL.format(version=electron_version) - output.append(EnvironmentComponent(name=sha_url.split('/')[-1], - version=electron_version, - url=sha_url, - size=self.http_client.get_content_length(sha_url), - id='electron_sha256')) - - def _check_electron_async(self, pkg: WebApplication, env: dict, local_config: dict, x86_x64: bool, output: List[EnvironmentComponent]): + def _check_and_fill_electron(self, pkg: WebApplication, env: dict, local_config: dict, x86_x64: bool, output: List[EnvironmentComponent]): electron_version = env['electron']['version'] if pkg.version and pkg.version != electron_version: @@ -276,33 +257,40 @@ class EnvironmentUpdater: self.logger.warning("A custom Electron version will be used {} to install {}".format(electron_version, pkg.url)) electron_version = local_config['environment']['electron']['version'] - electron_status = self.check_installed_electron(version=electron_version, is_x86_x64_arch=x86_x64) - threads = [] + electron_status = self.check_electron_installed(version=electron_version, is_x86_x64_arch=x86_x64) - if not electron_status['electron']: - t = Thread(target=self._fill_electron_to_install, args=(electron_version, x86_x64, output)) - t.start() - threads.append(t) + electron_url = self._get_electron_url(version=electron_version, is_x86_x64_arch=x86_x64) + output.append(EnvironmentComponent(name=electron_url.split('/')[-1], + version=electron_version, + url=electron_url, + size=self.http_client.get_content_length(electron_url), + id='electron', + update=not electron_status['electron'])) - if not electron_status['sha256']: - t = Thread(target=self._fill_electron_sha256_to_install, args=(electron_version, output)) - t.start() - threads.append(t) + sha_url = ELECTRON_SHA256_URL.format(version=electron_version) + output.append(EnvironmentComponent(name=sha_url.split('/')[-1], + version=electron_version, + url=sha_url, + size=self.http_client.get_content_length(sha_url), + id='electron_sha256', + update=not electron_status['electron'] or not electron_status['sha256'])) - for t in threads: - t.join() + def _check_and_fill_node(self, env: dict, output: List[EnvironmentComponent]): + node = EnvironmentComponent(name=env['nodejs']['url'].split('/')[-1], + url=env['nodejs']['url'], + size=self.http_client.get_content_length(env['nodejs']['url']), + version=env['nodejs']['version'], + id='nodejs') + output.append(node) + + native = self._map_nativefier_file(env['nativefier']) + output.append(native) - def _check_node_async(self, env: dict, output: List[EnvironmentComponent]): if not self.check_node_installed(env['nodejs']['version']): - output.append(EnvironmentComponent(name=env['nodejs']['url'].split('/')[-1], - url=env['nodejs']['url'], - size=self.http_client.get_content_length(env['nodejs']['url']), - version=env['nodejs']['version'], - id='nodejs')) - output.append(self._map_nativefier_file(env['nativefier'])) + node.update, native.update = True, True else: if not self._check_nativefier_installed(env['nativefier']): - output.append(self._map_nativefier_file(env['nativefier'])) + native.update = True def _check_nativefier_installed(self, nativefier_settings: dict) -> bool: if not os.path.exists(NODE_MODULES_PATH): @@ -334,81 +322,39 @@ class EnvironmentUpdater: version=nativefier_settings['version'], id='nativefier') - def check_environment(self, app: WebApplication, is_x86_x64_arch: bool) -> Tuple[dict, List[EnvironmentComponent]]: - to_update, check_threads = [], [] - - env = self.read_settings() - local_config = read_config() + def check_environment(self, env: dict, local_config: dict, app: WebApplication, is_x86_x64_arch: bool) -> List[EnvironmentComponent]: + """ + :param app: + :param is_x86_x64_arch: + :return: the environment settings + """ + components, check_threads = [], [] system_env = local_config['environment'].get('system', False) if system_env: self.logger.warning("Using system's nativefier to install {}".format(app.url)) else: - node_check = Thread(target=self._check_node_async, args=(env, to_update)) + node_check = Thread(target=self._check_and_fill_node, args=(env, components)) node_check.start() check_threads.append(node_check) - elec_check = Thread(target=self._check_electron_async, args=(app, env, local_config, is_x86_x64_arch, to_update)) + elec_check = Thread(target=self._check_and_fill_electron, args=(app, env, local_config, is_x86_x64_arch, components)) elec_check.start() check_threads.append(elec_check) for t in check_threads: t.join() - return env, to_update - - def update_environment(self, is_x86_x64_arch: bool, config: dict = None, handler: ProcessHandler = None) -> dict: - settings = self.read_settings() - - if settings is None: - return - - current_config = config if config else read_config() - system_env = current_config['environment']['system'] - watcher = handler.watcher if handler else None - - if not system_env and not self.update_node(version=settings['nodejs']['version'], version_url=settings['nodejs']['url'], - watcher=watcher): - self.logger.warning('Could not install / update NodeJS') - return - - if not system_env and not self.install_nativefier(version=settings['nativefier']['version'], handler=handler): - self.logger.warning('Could not install / update nativefier') - return - - electron_version = current_config['environment']['electron']['version'] - - if electron_version: - self.logger.warning("Using custom Electron version {}".format(electron_version)) - else: - electron_version = settings['electron']['version'] - - installed = self.check_installed_electron(version=electron_version, is_x86_x64_arch=is_x86_x64_arch) - - if not installed['electron']: - if self.download_electron(version=electron_version, is_x86_x64_arch=is_x86_x64_arch, watcher=watcher): - res = self.download_electron_sha256(version=electron_version, watcher=watcher) - else: - res = False - elif not installed['sha256']: - res = self.download_electron_sha256(version=electron_version, watcher=watcher) - else: - res = True - - if res: - self.logger.info('Environment updated') - else: - self.logger.warning('Could not update the environment') - - return settings + return components def update(self, components: List[EnvironmentComponent], handler: ProcessHandler) -> bool: self.logger.info('Updating environment') + Path(ENV_PATH).mkdir(parents=True, exist_ok=True) comp_map = {c.id: c for c in components} - node_data = comp_map.get('node') + node_data = comp_map.get('nodejs') nativefier_data = comp_map.get('nativefier') if node_data: diff --git a/bauh/gems/web/resources/locale/en b/bauh/gems/web/resources/locale/en index 7d6a6e23..69aad868 100644 --- a/bauh/gems/web/resources/locale/en +++ b/bauh/gems/web/resources/locale/en @@ -5,7 +5,7 @@ web.waiting.env_updater=Updating environment web.env.checking=Checking the Web installation environment web.env.error=It seems there are issues with the Web installation environment. It wil not be possible to install {}. web.install.env_update.title=Environment update -web.install.env_update.title=The following files must be downloaded and installed +web.install.env_update.body=The following files must be downloaded and installed web.install.options.basic=basic web.install.options.advanced=advanced web.install.options_dialog.title=Installation options diff --git a/bauh/view/qt/confirmation.py b/bauh/view/qt/confirmation.py index d6f8ea57..edd2b04e 100644 --- a/bauh/view/qt/confirmation.py +++ b/bauh/view/qt/confirmation.py @@ -22,11 +22,12 @@ class ConfirmationDialog(QMessageBox): self.addButton(i18n['popup.button.no'] if not deny_label else deny_label.capitalize(), QMessageBox.NoRole) + label = None if body: if not components: self.setIcon(QMessageBox.Question) - - self.layout().addWidget(QLabel(body), 0, 1) + label = QLabel(body) + self.layout().addWidget(label, 0, 1) width = 0 if components: @@ -65,6 +66,8 @@ class ConfirmationDialog(QMessageBox): self.layout().addWidget(scroll, 1 if body else 0, 1) + if label and comps_container.sizeHint().width() > label.sizeHint().width(): + label.setText(label.text() + (' ' * int(comps_container.sizeHint().width() - label.sizeHint().width()))) if not body and width > 0: self.layout().addWidget(QLabel(' ' * int(width / 2)), 1, 1)