368 lines
14 KiB
Python
Executable File
368 lines
14 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Copyright (c) 2019-2021 by Silvan Calarco <silvan.calarco@mambasoft.it>
|
|
# 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(
|
|
_('<html><head/><body><p align="center">' +
|
|
'<span style="font-size:14pt; font-weight:600;">' +
|
|
'All done!</span></p></body></html>'))
|
|
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("<br/>" + 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_())
|