[web] downloading environment.yml from the cloud

This commit is contained in:
Vinícius Moreira
2019-12-10 17:55:16 -03:00
parent d4c8d67433
commit b4533413e6
7 changed files with 79 additions and 64 deletions

View File

@@ -26,6 +26,7 @@ To contribute with this project, have a look at [CONTRIBUTING.md](https://github
- **python-requests**
- **python-pip**
- **python-pyqt5**
- **python-yaml**
##### Optional
- **flatpak**: to be able to handle Flatpak applications

View File

@@ -12,4 +12,4 @@ NATIVEFIER_BIN_PATH = '{}/.bin/nativefier'.format(NODE_MODULES_PATH)
ELECTRON_PATH = '{}/.cache/electron'.format(HOME_PATH)
ELECTRON_DOWNLOAD_URL = 'https://github.com/electron/electron/releases/download/v{version}/electron-v{version}-linux-{arch}.zip'
ELECTRON_SHA256_URL = 'https://github.com/electron/electron/releases/download/v{version}/SHASUMS256.txt'
ELECTRON_VERSION = '0.5.12'
URL_ENVIRONMENT_SETTINGS = 'https://raw.githubusercontent.com/vinifmor/bauh-files/master/web/environment.yml'

View File

@@ -30,7 +30,8 @@ class WebApplicationManager(SoftwareManager):
def __init__(self, context: ApplicationContext):
super(WebApplicationManager, self).__init__(context=context)
self.http_client = context.http_client
self.node_updater = NodeUpdater(logger=context.logger, file_downloader=context.file_downloader, i18n=context.i18n)
self.node_updater = NodeUpdater(logger=context.logger, http_client=context.http_client,
file_downloader=context.file_downloader, i18n=context.i18n)
self.enabled = True
def search(self, words: str, disk_loader: DiskCacheLoader, limit: int = -1, is_url: bool = False) -> SearchResult:

View File

@@ -5,37 +5,41 @@ import tarfile
import traceback
from pathlib import Path
import requests
import yaml
from bauh.api.abstract.download import FileDownloader
from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.exception import NoInternetException
from bauh.api.http import HttpClient
from bauh.commons import system
from bauh.commons.html import bold
from bauh.commons.system import SimpleProcess, ProcessHandler, run_cmd
from bauh.gems.web import BIN_PATH, NODE_DIR_PATH, NODE_BIN_PATH, NPM_BIN_PATH, NODE_MODULES_PATH, NATIVEFIER_BIN_PATH, \
ELECTRON_PATH, ELECTRON_DOWNLOAD_URL, ELECTRON_SHA256_URL, ELECTRON_VERSION
ELECTRON_PATH, ELECTRON_DOWNLOAD_URL, ELECTRON_SHA256_URL, URL_ENVIRONMENT_SETTINGS
from bauh.view.util.translation import I18n
class NodeUpdater:
def __init__(self, logger: logging.Logger, file_downloader: FileDownloader, i18n: I18n):
def __init__(self, logger: logging.Logger, http_client: HttpClient, file_downloader: FileDownloader, i18n: I18n):
self.logger = logger
self.file_downloader = file_downloader
self.i18n = i18n
self.http_client = http_client
def _is_internet_available(self) -> bool:
self.logger.info('Checking internet connection')
# TODO
return True
def _download_and_install(self, cloud_version: str, watcher: ProcessWatcher ) -> bool:
npm_dlink = 'https://nodejs.org/dist/v12.13.1/node-v12.13.1-linux-x64.tar.xz'
self.logger.info("Downloading NodeJS {}: {}".format(cloud_version, npm_dlink))
def _download_and_install(self, version: str, version_url: str, watcher: ProcessWatcher) -> bool:
self.logger.info("Downloading NodeJS {}: {}".format(version, version_url))
tarf_path = '{}/{}'.format(BIN_PATH, npm_dlink.split('/')[-1])
downloaded = self.file_downloader.download(npm_dlink, watcher=watcher, output_path=tarf_path, cwd=BIN_PATH)
tarf_path = '{}/{}'.format(BIN_PATH, version_url.split('/')[-1])
downloaded = self.file_downloader.download(version_url, watcher=watcher, output_path=tarf_path, cwd=BIN_PATH)
if not downloaded:
self.logger.error("Could not download '{}'. Aborting...".format(npm_dlink))
self.logger.error("Could not download '{}'. Aborting...".format(version_url))
return False
else:
try:
@@ -56,29 +60,22 @@ class NodeUpdater:
except:
self.logger.error('Could not delete file {}'.format(tarf_path))
def update_node(self, watcher: ProcessWatcher = None) -> bool:
if not self._is_internet_available():
raise NoInternetException()
self.logger.info('Checking Node version from bauh-files')
# TODO
cloud_version = 'v12.13.1'
def update_node(self, version: str, version_url: str, watcher: ProcessWatcher = None) -> bool:
Path(BIN_PATH).mkdir(parents=True, exist_ok=True)
if not os.path.exists(NODE_DIR_PATH):
if not self._download_and_install(cloud_version, watcher):
return False
return self._download_and_install(version=version, version_url=version_url, watcher=watcher)
else:
installed_version = system.run_cmd('{} --version'.format(NODE_BIN_PATH))
if installed_version:
installed_version = installed_version.strip()
self.logger.info('Node -> installed: {}. cloud: {}.'.format(installed_version, cloud_version))
self.logger.info('Node -> installed: {}. cloud: {}.'.format(installed_version, version))
if cloud_version != installed_version:
return self._download_and_install(cloud_version, watcher)
if version != installed_version:
self.logger.info("The NodeJs installed version is different from the Cloud.")
return self._download_and_install(version=version, version_url=version_url, watcher=watcher)
else:
self.logger.info("Node is already up to date")
return True
@@ -87,15 +84,18 @@ class NodeUpdater:
self.logger.info("Removing {}".format(NODE_DIR_PATH))
try:
shutil.rmtree(NODE_DIR_PATH)
return self._download_and_install(cloud_version, watcher)
return self._download_and_install(version=version, version_url=version_url, watcher=watcher)
except:
self.logger.error('Could not delete the dir {}'.format(NODE_DIR_PATH))
return False
def _install_nativefier(self, handler: ProcessHandler) -> bool:
def _install_nativefier(self, version: str, handler: ProcessHandler) -> bool:
self.logger.info("Installing nativefier")
# TODO freeze specific version
proc = SimpleProcess([NPM_BIN_PATH, 'install', 'nativefier'], cwd=BIN_PATH)
if handler and handler.watcher:
handler.watcher.change_substatus(self.i18n['web.environment.install'].format(bold('nativefier')))
proc = SimpleProcess([NPM_BIN_PATH, 'install', 'nativefier@{}'.format(version)], cwd=BIN_PATH)
if handler:
return handler.handle_simple(proc)[0]
@@ -103,22 +103,17 @@ class NodeUpdater:
proc.instance.wait()
if self._is_nativefier_installed():
self.logger.info("nativefier installed")
self.logger.info("nativefier {} installed".format(version))
return True
else:
self.logger.error("Could not install nativefier")
self.logger.error("Could not install nativefier {}".format(version))
return False
def _is_nativefier_installed(self) -> bool:
try:
return bool(system.run_cmd('{} --version'.format(NATIVEFIER_BIN_PATH)))
except:
self.logger.error("Could not determine the installed nativefier version")
traceback.print_exc()
return False
return os.path.exists(NATIVEFIER_BIN_PATH)
def install_nativefier(self, remove_modules: bool = False, handler: ProcessHandler = None) -> bool:
self.logger.info("Preparing to install nativefier")
def install_nativefier(self, version: str, remove_modules: bool = False, handler: ProcessHandler = None) -> bool:
self.logger.info("Preparing to install nativefier {}".format(version))
if remove_modules and os.path.exists(NODE_MODULES_PATH):
self.logger.info('Removing old dir {}'.format(NODE_MODULES_PATH))
@@ -128,10 +123,10 @@ class NodeUpdater:
self.logger.error('Could not remove dir {}. Aborting...'.format(NODE_MODULES_PATH))
return False
return self._install_nativefier(handler)
return self._install_nativefier(version=version, handler=handler)
else:
if not self._is_nativefier_installed():
return self._install_nativefier(handler)
return self._install_nativefier(version=version, handler=handler)
self.logger.info("Nativefier is already installed")
return True
@@ -140,18 +135,14 @@ class NodeUpdater:
self.logger.info("Downloading Electron {}".format(version))
arch = 'ia32' if not is_x86_x64_arch else 'x64'
Path(ELECTRON_PATH).mkdir(parents=True, exist_ok=True)
electron_url = ELECTRON_DOWNLOAD_URL.format(arch=arch, version=version)
electron_path = '{}/{}'.format(ELECTRON_PATH, electron_url.split('/')[-1])
return self.file_downloader.download(file_url=electron_url, watcher=watcher, output_path=electron_path,cwd=ELECTRON_PATH)
return self.file_downloader.download(file_url=electron_url, watcher=watcher, output_path=electron_path, cwd=ELECTRON_PATH)
def _download_electron_sha256(self, version: str, watcher: ProcessWatcher) -> bool:
self.logger.info("Downloading Electron {} sha526".format(version))
Path(ELECTRON_PATH).mkdir(parents=True, exist_ok=True)
sha256_url = ELECTRON_SHA256_URL.format(version=version)
sha256_path = '{}/{}'.format(ELECTRON_PATH, sha256_url.split('/')[-1])
return self.file_downloader.download(file_url=sha256_url, watcher=watcher, output_path=sha256_path, cwd=ELECTRON_PATH)
@@ -161,7 +152,9 @@ class NodeUpdater:
if not os.path.exists(ELECTRON_PATH):
self.logger.info("Electron is not installed")
self._download_electron(version=version, is_x86_x64_arch=is_x86_x64_arch, watcher=watcher)
Path(ELECTRON_PATH).mkdir(parents=True, exist_ok=True)
if self._download_electron(version=version, is_x86_x64_arch=is_x86_x64_arch, watcher=watcher):
return self._download_electron_sha256(version=version, watcher=watcher)
else:
files = run_cmd('ls', print_error=False, cwd=ELECTRON_PATH)
@@ -191,20 +184,37 @@ class NodeUpdater:
return False
def update_environment(self, is_x86_x64_arch: bool, handler: ProcessHandler = None):
if not self.update_node(handler.watcher if handler else None):
self.logger.warning('Could not update the environment')
def update_environment(self, is_x86_x64_arch: bool, handler: ProcessHandler = None) -> bool:
try:
res = self.http_client.get(URL_ENVIRONMENT_SETTINGS)
if not res:
self.logger.warning('Could not retrieve the environments settings from the cloud')
return False
try:
settings = yaml.safe_load(res.content)
except yaml.YAMLError:
self.logger.error('Could not parse environment settings: {}'.format(res.text))
return False
if not self.update_node(version=settings['nodejs']['version'], version_url=settings['nodejs']['url'],
watcher=handler.watcher if handler else None):
self.logger.warning('Could not install / update NodeJS')
return False
if not self.install_nativefier(version=settings['nativefier']['version'], handler=handler):
self.logger.warning('Could not install / update nativefier')
return False
res = self.install_electron(version=settings['electron']['version'], is_x86_x64_arch=is_x86_x64_arch,
watcher=handler.watcher if handler else None)
if res:
self.logger.info('Environment updated')
else:
self.logger.warning('Could not update the environment')
return res
except requests.exceptions.ConnectionError:
return False
if not self.install_nativefier(handler=handler):
self.logger.warning('Could not update the environment')
return False
res = self.install_electron(version=ELECTRON_VERSION, is_x86_x64_arch=is_x86_x64_arch, watcher=handler.watcher if handler else None)
if res:
self.logger.info('Environment updated')
else:
self.logger.warning('Could not update the environment')
return res

View File

@@ -1 +1,2 @@
gem.web.info=It allows to install Web applications on your system
gem.web.info=It allows to install Web applications on your system
web.environment.install=Installing {}

View File

@@ -1 +1,2 @@
gem.web.info=Permite instalar aplicações Web no seu sistema
gem.web.info=Permite instalar aplicações Web no seu sistema
web.environment.nativefier=Instalando {}

View File

@@ -1,3 +1,4 @@
pyqt5>=5.12
requests>=2.22
colorama>=0.4.1
pyyaml>=5.2