#!/usr/bin/env python3 # Copyright (c) 2019-2020 by Silvan Calarco # Release under the terms of the GPL version 3 license from PyQt5 import QtCore from PyQt5 import QtGui from PyQt5.QtCore import pyqtProperty from PyQt5 import QtCore, QtWidgets from PyQt5 import QtWidgets, uic 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)}) 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!")}) # 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, 'fglrx': self.inst_fglrx, 'fglrx_legacy': self.inst_fglrx_legacy, 'broadcom_sta': self.inst_broadcom_sta, 'b43-firmware': self.inst_b43, 'flashplugin': self.inst_flash, 'chromium-pepper-flash': self.inst_pepperflash, 'msttcorefonts': self.inst_msttcf, 'win32codecs': self.inst_codecs, 'sun-java': self.inst_java, 'virtualbox-extension-pack': self.inst_virtualbox, 'chromium-widevine': self.inst_widevine } # 'skype': self.inst_skype, # 'spotify': self.inst_spotify, 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")) gettext.install('mambabase', '/usr/share/locale') wizard = MambabaseWizard() wizard.show() sys.exit(app.exec_())