#!/usr/bin/env python3 # Copyright (c) 2019-2021 by Silvan Calarco # Release under the terms of the GPL version 3 license from PyQt5 import QtGui, QtCore, QtWidgets, uic from PyQt5.QtCore import pyqtProperty from PyQt5.QtCore import QLocale, QTranslator from pathlib import Path import gettext import subprocess import os import gi gi.require_version('PackageKitGlib', '1.0') from gi.repository import PackageKitGlib as packagekit DATADIR = os.path.dirname(os.path.realpath((__file__))) + "/" class MambabaseWizard(QtWidgets.QWizard): def __init__(self, parent=None): super(MambabaseWizard, self).__init__(parent) self.welcomePage = WelcomePage(self) self.addPage(self.welcomePage) self.selectGroupsPage = SelectGroupsPage(self) self.addPage(self.selectGroupsPage) self.selectExtraPage = SelectExtraPage(self) self.addPage(self.selectExtraPage) self.installationPage = InstallationPage(self) self.addPage(self.installationPage) self.setWindowTitle(_("openmamba base network installations") + " - openmamba.org") self.setFixedSize(571,465) self.currentIdChanged.connect(self.currentIdChangedSlot) self.prepareThread = PrepareThread(self) self.installThread = InstallThread(self, self.selectGroupsPage.pkggroups) def currentIdChangedSlot(self, currentId): if currentId == 0: self.prepareThread.start() elif currentId == 3: self.installThread.start() class PrepareThread(QtCore.QThread): parent = None doneSignal = QtCore.pyqtSignal() updateProgressSignal = QtCore.pyqtSignal(dict) def __init__(self, parent=None): super(PrepareThread, self).__init__(parent) self.parent = parent self.doneSignal.connect(parent.welcomePage.completeChanged) self.updateProgressSignal.connect( parent.welcomePage.updateProgressSlot) def run(self): # Update packages list self.updateProgressSignal.emit({ 'value': 5, 'label': _("Checking installed packages...")}) self.parent.selectGroupsPage.loadPkgGroups() self.updateProgressSignal.emit({ 'value': 55, 'label': _("Checking installed extra components...")}) self.parent.selectExtraPage.setExtras() self.updateProgressSignal.emit({ 'value': 100, 'label': _("Done. Please, press the Next button to continue.")}) # Enable back and next buttons self.parent.welcomePage.done = True self.doneSignal.emit() class InstallThread(QtCore.QThread): parent = None doneSignal = QtCore.pyqtSignal() updateProgressSignal = QtCore.pyqtSignal(dict) pkggroups = {} def __init__(self, parent=None, pkggroups={}): super(InstallThread, self).__init__(parent) self.parent = parent self.pkggroups = pkggroups self.doneSignal.connect(parent.installationPage.completeChanged) self.updateProgressSignal.connect( parent.installationPage.updateProgressSlot) def run(self): install = {} install_extras = {} parent = self.parent # Disable back and next buttons parent.installationPage.done = False self.doneSignal.emit() self.updateProgressSignal.emit( { 'value': 1, 'label': _("Starting installation..."), 'details': _("Starting installation...")}) # Update packages list self.updateProgressSignal.emit({ 'value': 5, 'label': _("Updating packages list..."), 'details': _("Updating packages list...")}) result = subprocess.run(['pkcon', 'refresh'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if result.returncode == 0: if result.stdout: self.updateProgressSignal.emit({ 'details': result.stdout.decode('UTF-8')}) else: if result.stderr: self.updateProgressSignal.emit({ 'details': result.stderr.decode('UTF-8')}) # Perform system update self.updateProgressSignal.emit({ 'value': 10, 'label': _("Updating installed packages..."), 'details': _("Updating installed packages...")}) result = subprocess.run(['pkcon', 'update', '-y'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if result.returncode == 0: if result.stdout: self.updateProgressSignal.emit({ 'details': result.stdout.decode('UTF-8')}) else: if result.stderr: self.updateProgressSignal.emit({ 'details': result.stderr.decode('UTF-8')}) self.updateProgressSignal.emit({ 'value': 20 }) arch = os.uname()[4] if arch == 'i686': arch = 'i586' elif arch[:3] == 'arm': arch = 'arm' client = packagekit.Client() # Install requested package groups for group in parent.selectGroupsPage.groups_checkboxes: install[group] = \ parent.selectGroupsPage.groups_checkboxes[group].isChecked() \ and parent.selectGroupsPage.groups_checkboxes[group].isEnabled() for inst in install: if install[inst]: self.updateProgressSignal.emit({ 'label': _("Installing %s group packages..." % inst), 'details': _("Installing %s group packages..." % inst)}) for pkg in self.pkggroups[inst].split(): result =client.resolve(0, (pkg,), None, self.packagekit_progress_cb, None) pkgs = result.get_package_array() for p in pkgs: if 'installed' in p.get_data().split(':'): self.updateProgressSignal.emit({ 'details': _("Package %s is already installed" % pkg)}) break if p.get_arch() != arch: continue packageid = p.get_name() + ';' + p.get_version() + ';' \ + p.get_arch() + ';' + p.get_data() self.updateProgressSignal.emit({ 'details': _("Installing package %s" % pkg)}) client.install_packages(False, (packageid, ), None, self.packagekit_progress_cb, p.get_name()) # Install requested extra packages for extra in parent.selectExtraPage.extra_checkboxes: install_extras[extra] = \ parent.selectExtraPage.extra_checkboxes[extra].isChecked() \ and parent.selectExtraPage.extra_checkboxes[extra].isEnabled() for extra in install_extras: if install_extras[extra]: self.updateProgressSignal.emit({ 'label': _("Installing %s extra component..." % extra), 'details': _("Installing %s extra component..." % extra)}) if extra == 'nvidia': result = subprocess.run([ '/usr/share/openmamba/mambabase/nvidia-autoselect-driver', '-i'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: result = subprocess.run(['/usr/bin/openmamba-netsrpms', extra], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if result.returncode == 0: if result.stdout: self.updateProgressSignal.emit({ 'details': result.stdout.decode('UTF-8')}) else: if result.stderr: self.updateProgressSignal.emit({ 'details': result.stderr.decode('UTF-8')}) # Finished self.updateProgressSignal.emit({ 'value': 100, 'label': _("Installation finished!"), 'details': _("Installation finished!")}) # Remove any autostart file try: file_path = Path.home() / ".config/autostart/mambabase.desktop" file_path.unlink() except: None # Enable back and next buttons parent.installationPage.done = True self.doneSignal.emit() def packagekit_progress_cb(self, status, typ, data=None): if status.get_property('package'): self.updateProgressSignal.emit({ 'label': _("Installing %s package (%s)..." % (status.get_property('package').get_name(), str(status.get_percentage())))}) class WelcomePage(QtWidgets.QWizardPage): done = False def __init__(self, parent=None): super(WelcomePage, self).__init__(parent) uic.loadUi(DATADIR + "WelcomePage.ui", self) self.show() def isComplete(self): return self.done @QtCore.pyqtSlot(dict) def updateProgressSlot(self, dict): if 'value' in dict: self.progressBar.setValue(dict['value']) if 'label' in dict: self.progressLabel.setText(dict['label']) class SelectGroupsPage(QtWidgets.QWizardPage): groups_checkboxes = {} pkggroups = {} def __init__(self, parent=None): super(SelectGroupsPage, self).__init__(parent) uic.loadUi(DATADIR + "SelectGroupsPage.ui", self) self.show() def loadPkgGroups(self): self.groups_checkboxes = { 'base': self.inst_base, 'office': self.inst_office, 'multimedia_players': self.inst_players, 'multimedia_editing': self.inst_multimedia_editing, 'internet': self.inst_internet, 'graphics': self.inst_graphics, 'games': self.inst_games, 'virtualization': self.inst_virtualization, 'server': self.inst_server } #'devel': self.inst_devel # Load packages group db into a dict result = subprocess.run([DATADIR + "mambabase-pkggroups-parser.sh"], stdout=subprocess.PIPE) lines = result.stdout.decode('UTF-8').splitlines() for line in lines: if line: (key, val) = line.split("=") self.pkggroups[key] = val # Check for groups already installed client = packagekit.Client() for group in self.groups_checkboxes: group_installed = True if group in self.pkggroups: for pkg in self.pkggroups[group].split(): result = client.resolve(0, (pkg,), None, self.packagekit_progress_cb, None) pkgs_found = result.get_package_array() package_installed = False for p in pkgs_found: if 'installed' in p.get_data().split(':'): package_installed = True break if not package_installed and len(pkgs_found) > 0: group_installed = False elif len(pkgs_found) == 0: print(_("WARNING: package %s from group %s not found in repositories" % (pkg, group))) if group_installed: self.groups_checkboxes[group].setChecked(True) self.groups_checkboxes[group].setEnabled(False) def packagekit_progress_cb(self, status, typ, data=None): pass class SelectExtraPage(QtWidgets.QWizardPage): extra_checkboxes = {} def __init__(self, parent=None): super(SelectExtraPage, self).__init__(parent) uic.loadUi(DATADIR + "SelectExtraPage.ui", self) self.setCommitPage(True) self.show() def setExtras(self): self.extra_checkboxes = { 'nvidia': self.inst_nvidia, 'broadcom_sta': self.inst_broadcom_sta, 'b43-firmware': self.inst_b43, 'msttcorefonts': self.inst_msttcf, 'virtualbox-extension-pack': self.inst_virtualbox, 'chromium-widevine': self.inst_widevine } for extra in self.extra_checkboxes: result = subprocess.run(['/usr/bin/openmamba-netsrpms', '-c', extra], stdout=subprocess.PIPE) if result.returncode < 2: self.extra_checkboxes[extra].setChecked(True) self.extra_checkboxes[extra].setEnabled(False) class InstallationPage(QtWidgets.QWizardPage): done = False def __init__(self, parent=None): super(InstallationPage, self).__init__(parent) uic.loadUi(DATADIR + "InstallationPage.ui", self) self.setCommitPage(True) self.show() def isComplete(self): if self.done: self.installPageTitle.setText( _('

' + '' + 'All done!

')) return self.done @QtCore.pyqtSlot(dict) def updateProgressSlot(self, dict): if 'value' in dict: self.progressBar.setValue(dict['value']) if 'label' in dict: self.progressLabel.setText(dict['label']) if 'details' in dict: self.progressDetails.append("
" + dict['details']) if __name__ == '__main__': import sys app = QtWidgets.QApplication(sys.argv) app.setWindowIcon(QtGui.QIcon(DATADIR + "mambabase.png")) # UI translations locale = QLocale.system().name() language = locale[0:2] qtTranslator = QTranslator() if qtTranslator.load("mambabase", "/usr/share/locale/" + locale + "/LC_MESSAGES/"): app.installTranslator(qtTranslator) elif qtTranslator.load("mambabase", "/usr/share/locale/" + language + "/LC_MESSAGES/"): app.installTranslator(qtTranslator) # PY translations gettext.install('mambabase', '/usr/share/locale') wizard = MambabaseWizard() wizard.show() sys.exit(app.exec_())