#!/usr/bin/env python3 # Copyright (c) 2019 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 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...")}) # Update packages list self.updateProgressSignal.emit({ 'value': 5, 'label': _("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...")}) result = subprocess.run(['pkcon', 'update'], 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 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(':'): break if p.get_arch() != arch: continue packageid = p.get_name() + ';' + p.get_version() + ';' \ + p.get_arch() + ';' + p.get_data() 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)}) result = subprocess.run(['/usr/bin/openmamba-netsrpms', extra], stdout=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!")}) # 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 MambabaseWizard(QtWidgets.QWizard): def __init__(self, parent=None): super(MambabaseWizard, self).__init__(parent) self.addPage(WelcomePage(self)) 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.finishPage = FinishPage(self) self.addPage(self.finishPage) self.setWindowTitle(_("openmamba base network installations") + " - openmamba.org") self.setFixedSize(571,465) self.currentIdChanged.connect(self.currentIdChangedSlot) self.installThread = InstallThread(self, self.selectGroupsPage.pkggroups) def currentIdChangedSlot(self, currentId): if currentId == 3: self.installThread.start() class WelcomePage(QtWidgets.QWizardPage): def __init__(self, parent=None): super(WelcomePage, self).__init__(parent) uic.loadUi('WelcomePage.ui', self) self.show() class SelectGroupsPage(QtWidgets.QWizardPage): groups_checkboxes = {} pkggroups = {} def __init__(self, parent=None): super(SelectGroupsPage, self).__init__(parent) uic.loadUi('SelectGroupsPage.ui', self) self.loadPkgGroups() 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(['/usr/libexec/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('SelectExtraPage.ui', self) self.setCommitPage(True) self.setExtras() 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, 'skype': self.inst_skype, 'spotify': self.inst_spotify, '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('InstallationPage.ui', self) self.setCommitPage(True) 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']) if 'details' in dict: self.progressDetails.setText(dict['details']) class FinishPage(QtWidgets.QWizardPage): def __init__(self, parent=None): super(FinishPage, self).__init__(parent) uic.loadUi('FinishPage.ui', self) self.show() if __name__ == '__main__': import sys app = QtWidgets.QApplication(sys.argv) app.setWindowIcon(QtGui.QIcon("mamba-128x128.png")) gettext.install('mambabase', '/usr/share/locale') wizard = MambabaseWizard() wizard.show() sys.exit(app.exec_())