mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-07 02:24:16 +02:00
[wgem] updating environment components
This commit is contained in:
@@ -476,17 +476,17 @@ class WebApplicationManager(SoftwareManager):
|
|||||||
watcher.change_substatus(self.i18n['web.env.checking'])
|
watcher.change_substatus(self.i18n['web.env.checking'])
|
||||||
handler = ProcessHandler(watcher)
|
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 comps_to_update and not self._ask_update_permission(comps_to_update, watcher):
|
||||||
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)
|
|
||||||
return False
|
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)
|
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')))
|
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,
|
installed = handler.handle_simple(nativefier.install(url=pkg.url, name=app_id, output_dir=app_dir,
|
||||||
electron_version=electron_version,
|
electron_version=electron_version,
|
||||||
system=system_env,
|
system=local_config['environment']['system'],
|
||||||
cwd=INSTALLED_PATH,
|
cwd=INSTALLED_PATH,
|
||||||
extra_options=install_options))
|
extra_options=install_options))
|
||||||
|
|
||||||
|
|||||||
@@ -25,12 +25,13 @@ from bauh.view.util.translation import I18n
|
|||||||
|
|
||||||
class EnvironmentComponent:
|
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.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.size = size
|
self.size = size
|
||||||
self.version = version
|
self.version = version
|
||||||
self.url = url
|
self.url = url
|
||||||
|
self.update = update
|
||||||
|
|
||||||
|
|
||||||
class EnvironmentUpdater:
|
class EnvironmentUpdater:
|
||||||
@@ -78,7 +79,6 @@ class EnvironmentUpdater:
|
|||||||
except:
|
except:
|
||||||
self.logger.error('Could not delete file {}'.format(tarf_path))
|
self.logger.error('Could not delete file {}'.format(tarf_path))
|
||||||
|
|
||||||
|
|
||||||
def check_node_installed(self, version: str) -> bool:
|
def check_node_installed(self, version: str) -> bool:
|
||||||
if not os.path.exists(NODE_DIR_PATH):
|
if not os.path.exists(NODE_DIR_PATH):
|
||||||
return False
|
return False
|
||||||
@@ -135,34 +135,27 @@ class EnvironmentUpdater:
|
|||||||
self.logger.error('Could not delete the dir {}'.format(NODE_DIR_PATH))
|
self.logger.error('Could not delete the dir {}'.format(NODE_DIR_PATH))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _install_nativefier(self, version: str, handler: ProcessHandler) -> bool:
|
def _install_node_lib(self, name: str, version: str, handler: ProcessHandler):
|
||||||
self.logger.info("Installing nativefier")
|
lib_repr = '{}{}'.format(name, '@{}'.format(version) if version else '')
|
||||||
|
self.logger.info("Installing {}".format(lib_repr))
|
||||||
|
|
||||||
if handler and handler.watcher:
|
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:
|
if installed:
|
||||||
self.logger.info("nativifier {} successfully installed".format(version))
|
self.logger.info("{} successfully installed".format(lib_repr))
|
||||||
|
|
||||||
return installed
|
return installed
|
||||||
else:
|
|
||||||
proc.instance.wait()
|
|
||||||
|
|
||||||
if self._is_nativefier_installed():
|
def _install_nativefier(self, version: str, handler: ProcessHandler) -> bool:
|
||||||
self.logger.info("nativefier {} installed".format(version))
|
success = self._install_node_lib('nativefier', version, handler)
|
||||||
return True
|
|
||||||
else:
|
|
||||||
self.logger.error("Could not install nativefier {}".format(version))
|
|
||||||
for err in proc.instance.stdout:
|
|
||||||
if err:
|
|
||||||
print(err.decode())
|
|
||||||
|
|
||||||
return False
|
if success:
|
||||||
|
return self._is_nativefier_installed()
|
||||||
|
|
||||||
def _is_nativefier_installed(self) -> bool:
|
def _is_nativefier_installed(self) -> bool:
|
||||||
return os.path.exists(NATIVEFIER_BIN_PATH)
|
return os.path.exists(NATIVEFIER_BIN_PATH)
|
||||||
@@ -197,19 +190,20 @@ class EnvironmentUpdater:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def download_electron(self, version: str, url: str, watcher: ProcessWatcher) -> bool:
|
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))
|
self.logger.info("Downloading Electron {}".format(version))
|
||||||
electron_path = '{}/{}'.format(ELECTRON_PATH, url.split('/')[-1])
|
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)
|
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:
|
def download_electron_sha256(self, version: str, url: str, watcher: ProcessWatcher) -> bool:
|
||||||
self.logger.info("Downloading Electron {} sha526".format(version))
|
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)
|
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:
|
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')
|
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))
|
self.logger.info("Checking if Electron {} is installed".format(version))
|
||||||
res = {'electron': False, 'sha256': False}
|
res = {'electron': False, 'sha256': False}
|
||||||
|
|
||||||
@@ -222,8 +216,11 @@ class EnvironmentUpdater:
|
|||||||
file_name = self._get_electron_url(version, is_x86_x64_arch).split('/')[-1]
|
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])
|
res['electron'] = bool([f for f in files if f == file_name])
|
||||||
|
|
||||||
file_name = ELECTRON_SHA256_URL.split('/')[-1]
|
if not res['electron']:
|
||||||
res['sha256'] = bool([f for f in files if f == file_name])
|
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:
|
else:
|
||||||
self.logger.info('No Electron file found in {}'.format(ELECTRON_PATH))
|
self.logger.info('No Electron file found in {}'.format(ELECTRON_PATH))
|
||||||
|
|
||||||
@@ -249,23 +246,7 @@ class EnvironmentUpdater:
|
|||||||
except requests.exceptions.ConnectionError:
|
except requests.exceptions.ConnectionError:
|
||||||
return
|
return
|
||||||
|
|
||||||
def _fill_electron_to_install(self, electron_version: str, 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_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]):
|
|
||||||
electron_version = env['electron']['version']
|
electron_version = env['electron']['version']
|
||||||
|
|
||||||
if pkg.version and pkg.version != 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))
|
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_version = local_config['environment']['electron']['version']
|
||||||
|
|
||||||
electron_status = self.check_installed_electron(version=electron_version, is_x86_x64_arch=x86_x64)
|
electron_status = self.check_electron_installed(version=electron_version, is_x86_x64_arch=x86_x64)
|
||||||
threads = []
|
|
||||||
|
|
||||||
if not electron_status['electron']:
|
electron_url = self._get_electron_url(version=electron_version, is_x86_x64_arch=x86_x64)
|
||||||
t = Thread(target=self._fill_electron_to_install, args=(electron_version, x86_x64, output))
|
output.append(EnvironmentComponent(name=electron_url.split('/')[-1],
|
||||||
t.start()
|
version=electron_version,
|
||||||
threads.append(t)
|
url=electron_url,
|
||||||
|
size=self.http_client.get_content_length(electron_url),
|
||||||
|
id='electron',
|
||||||
|
update=not electron_status['electron']))
|
||||||
|
|
||||||
if not electron_status['sha256']:
|
sha_url = ELECTRON_SHA256_URL.format(version=electron_version)
|
||||||
t = Thread(target=self._fill_electron_sha256_to_install, args=(electron_version, output))
|
output.append(EnvironmentComponent(name=sha_url.split('/')[-1],
|
||||||
t.start()
|
version=electron_version,
|
||||||
threads.append(t)
|
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:
|
def _check_and_fill_node(self, env: dict, output: List[EnvironmentComponent]):
|
||||||
t.join()
|
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']):
|
if not self.check_node_installed(env['nodejs']['version']):
|
||||||
output.append(EnvironmentComponent(name=env['nodejs']['url'].split('/')[-1],
|
node.update, native.update = True, True
|
||||||
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']))
|
|
||||||
else:
|
else:
|
||||||
if not self._check_nativefier_installed(env['nativefier']):
|
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:
|
def _check_nativefier_installed(self, nativefier_settings: dict) -> bool:
|
||||||
if not os.path.exists(NODE_MODULES_PATH):
|
if not os.path.exists(NODE_MODULES_PATH):
|
||||||
@@ -334,81 +322,39 @@ class EnvironmentUpdater:
|
|||||||
version=nativefier_settings['version'],
|
version=nativefier_settings['version'],
|
||||||
id='nativefier')
|
id='nativefier')
|
||||||
|
|
||||||
def check_environment(self, app: WebApplication, is_x86_x64_arch: bool) -> Tuple[dict, List[EnvironmentComponent]]:
|
def check_environment(self, env: dict, local_config: dict, app: WebApplication, is_x86_x64_arch: bool) -> List[EnvironmentComponent]:
|
||||||
to_update, check_threads = [], []
|
"""
|
||||||
|
:param app:
|
||||||
env = self.read_settings()
|
:param is_x86_x64_arch:
|
||||||
local_config = read_config()
|
:return: the environment settings
|
||||||
|
"""
|
||||||
|
components, check_threads = [], []
|
||||||
|
|
||||||
system_env = local_config['environment'].get('system', False)
|
system_env = local_config['environment'].get('system', False)
|
||||||
|
|
||||||
if system_env:
|
if system_env:
|
||||||
self.logger.warning("Using system's nativefier to install {}".format(app.url))
|
self.logger.warning("Using system's nativefier to install {}".format(app.url))
|
||||||
else:
|
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()
|
node_check.start()
|
||||||
check_threads.append(node_check)
|
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()
|
elec_check.start()
|
||||||
check_threads.append(elec_check)
|
check_threads.append(elec_check)
|
||||||
|
|
||||||
for t in check_threads:
|
for t in check_threads:
|
||||||
t.join()
|
t.join()
|
||||||
|
|
||||||
return env, to_update
|
return components
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
def update(self, components: List[EnvironmentComponent], handler: ProcessHandler) -> bool:
|
def update(self, components: List[EnvironmentComponent], handler: ProcessHandler) -> bool:
|
||||||
self.logger.info('Updating environment')
|
self.logger.info('Updating environment')
|
||||||
|
Path(ENV_PATH).mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
comp_map = {c.id: c for c in components}
|
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')
|
nativefier_data = comp_map.get('nativefier')
|
||||||
|
|
||||||
if node_data:
|
if node_data:
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ web.waiting.env_updater=Updating environment
|
|||||||
web.env.checking=Checking the Web installation 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.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=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.basic=basic
|
||||||
web.install.options.advanced=advanced
|
web.install.options.advanced=advanced
|
||||||
web.install.options_dialog.title=Installation options
|
web.install.options_dialog.title=Installation options
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ class ConfirmationDialog(QMessageBox):
|
|||||||
|
|
||||||
self.addButton(i18n['popup.button.no'] if not deny_label else deny_label.capitalize(), QMessageBox.NoRole)
|
self.addButton(i18n['popup.button.no'] if not deny_label else deny_label.capitalize(), QMessageBox.NoRole)
|
||||||
|
|
||||||
|
label = None
|
||||||
if body:
|
if body:
|
||||||
if not components:
|
if not components:
|
||||||
self.setIcon(QMessageBox.Question)
|
self.setIcon(QMessageBox.Question)
|
||||||
|
label = QLabel(body)
|
||||||
self.layout().addWidget(QLabel(body), 0, 1)
|
self.layout().addWidget(label, 0, 1)
|
||||||
|
|
||||||
width = 0
|
width = 0
|
||||||
if components:
|
if components:
|
||||||
@@ -65,6 +66,8 @@ class ConfirmationDialog(QMessageBox):
|
|||||||
|
|
||||||
self.layout().addWidget(scroll, 1 if body else 0, 1)
|
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:
|
if not body and width > 0:
|
||||||
self.layout().addWidget(QLabel(' ' * int(width / 2)), 1, 1)
|
self.layout().addWidget(QLabel(' ' * int(width / 2)), 1, 1)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user