#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from PyQt5.QtGui import QGuiApplication, QIcon, QScreen
from PyQt5.QtQuick import QQuickView
from PyQt5.QtCore import QUrl, QLocale, QTranslator, QLibraryInfo, QVariant, QAbstractListModel, \
QModelIndex, Qt, QObject, pyqtSlot, pyqtSignal, QCoreApplication
from PyQt5.QtNetwork import QNetworkConfigurationManager, QNetworkConfiguration
import sys
import os
import subprocess
from helpers import get_desktop_name, get_desktop_name2, is_installed
import pwd
# Workaround for opengl lib selection
from OpenGL import GL
translate = QCoreApplication.translate
class ConfList(QAbstractListModel):
NameRole = Qt.UserRole + 1
def __init__(self, parent=None):
super().__init__(parent)
# Changing working directory
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
os.chdir(dname)
#collect sys info
release = subprocess.getoutput('lsb_release -sd')
release = release[1:-1]
release_nb = subprocess.getoutput('lsb_release -sr')
release_nb = release_nb.strip()
kernel = subprocess.getoutput('uname -r')
if os.uname()[4] == 'x86_64':
arch = '64-bit'
elif os.uname()[4] == 'i586':
arch = '32-bit'
else:
arch = os.uname()[4]
try:
desktop = get_desktop_name(os.path.basename(os.getenv("DESKTOP_SESSION")))
except:
desktop = 'Other'
if desktop == 'Other':
desktop = get_desktop_name2(os.getenv("XDG_CURRENT_DESKTOP"))
if desktop == 'unknown':
desktop = os.getenv("XDG_CURRENT_DESKTOP")
self.screen_factor = 0.0
if desktop == 'Gnome Wayland':
import gi
gi.require_version('Gdk', '3.0')
from gi.repository.Gdk import Display
# pre-3.22, otherwise deprecated
#factor = Gdk.Screen.get_default().get_monitor_scale_factor(0)
self.screen_factor = Display.get_default().get_monitor(0).get_scale_factor()
# Search active network connections
net = QNetworkConfigurationManager()
first = True
if net.isOnline():
confs = net.allConfigurations(QNetworkConfiguration.Active)
for conf in confs:
if first:
netconfs = conf.name()
first = False
else:
netconfs += ", " + conf.name()
self.configuration = [
{'name': translate('ConfList',"Congratulations!
You are now running {}").format(release)},
{'name': translate('ConfList',"You are using linux kernel: {}").format(kernel)},
{'name': translate('ConfList',"Your system architecture is: {}").format(arch)},
{'name': translate('ConfList',"You are now using the Desktop: {}").format(desktop)},
{'name': translate('ConfList',"Your user id is: {}").format(os.getuid())},
]
if net.isOnline():
self.configuration.append({'name': translate('ConfList',"You are connected to a network through {}").format(netconfs)})
else:
self.configuration.append({'name': translate('ConfList',"You have no network connection")})
def factor(self, app):
'''
Determine screen factor
Can be specific for Gnome Wayland
'''
if self.screen_factor == 0 :
screen = app.primaryScreen()
self.screen_factor = screen.devicePixelRatio()
return self.screen_factor
def data(self, index, role=Qt.DisplayRole):
row = index.row()
return self.configuration[row]["name"]
def rowCount(self, parent=QModelIndex()):
return len(self.configuration)
def roleNames(self):
return {
ConfList.NameRole: b'name',
}
class Callbrowser(QObject):
def __init__(self):
QObject.__init__(self)
@pyqtSlot(str)
def weblink(self, link):
subprocess.Popen(["xdg-open", link])
class Launcher(QObject):
installed = pyqtSignal()
tainted = pyqtSignal()
repo = pyqtSignal()
noprogram = pyqtSignal()
def __init__(self):
QObject.__init__(self)
@pyqtSlot(QVariant)
def command(self, app):
if app.isArray():
cmd = []
for i in range(0,app.property("length").toInt()):
cmd.append(app.property(i).toString())
if cmd[0] == "gurpmi":
repo = cmd[2]
# Check if repositories are enabled
core = False
updates = False
tainted = False
t_updates = False
try:
active = subprocess.run(['urpmq','--list-media','active'], capture_output=True, text=True)
active.check_returncode()
except subprocess.CalledProcessError:
print("Error with urpmq")
return
for line in active.stdout.splitlines():
if line.startswith('Core Release'):
core = True
if line.startswith('Core Updates'):
updates = True
if line.startswith('Tainted Release'):
tainted = True
if line.startswith('Tainted Updates'):
t_updates = True
if repo == 'tainted' and not (tainted and t_updates) :
# repo not enabled
# print("Tainted not active")
self.tainted.emit()
return
if repo == '' and not (core and updates) :
# repo not enabled
# print("Core not active")
self.repo.emit()
return
proc = subprocess.Popen(['gurpmi',cmd[1]])
proc.wait()
# Give the signal to reload the applist
self.installed.emit()
return
try:
proc = subprocess.run(cmd)
except:
print(f"Exception running {cmd[0]}" )
self.noprogram.emit()
return
class Norun(QObject):
def __init__(self):
QObject.__init__(self)
self.home = os.getenv("HOME")
self.conffile = self.home + "/.config/mageiawelcome/norun.flag"
@pyqtSlot(bool)
def setRunAtLaunch(self, checked):
print("Setting",checked)
if checked:
if os.path.exists(self.conffile):
os.remove( self.conffile)
else:
os.makedirs(self.home + "/.config/mageiawelcome", exist_ok=True)
with open( self.conffile, 'w') :
pass
@pyqtSlot(result=bool)
def startupcheck(self):
return not os.path.exists(self.conffile)
class Installable(QObject):
def __init__(self):
QObject.__init__(self)
@pyqtSlot(str, str, result=bool)
def installable(self, app,repo):
is_app_installed, inst_repo = is_installed(app)
installable = (not is_app_installed) or (repo != inst_repo and inst_repo == "")
return installable
@pyqtSlot(str, str, result=bool)
def other(self, app, repo):
is_app_installed, inst_repo = is_installed(app)
return (is_app_installed and repo == '' and inst_repo != "")
def username():
user = pwd.getpwuid(os.getuid())[4] # pw_gecos, i e the real name
if user == "":
user = pwd.getpwuid(os.getuid())[0] # login
return user
if __name__ == '__main__':
app = QGuiApplication(sys.argv)
locale = QLocale.system().name()
qtTranslator = QTranslator()
if qtTranslator.load("qt_" + locale,QLibraryInfo.location(QLibraryInfo.TranslationsPath)):
app.installTranslator(qtTranslator)
appTranslator = QTranslator()
if appTranslator.load(QLocale(),"mageiawelcome","_", '/usr/share/mageiawelcome/translations'):
app.installTranslator(appTranslator)
app.setOrganizationName("Mageia")
app.setApplicationName("Mageiawelcome")
view = QQuickView()
view.setResizeMode(QQuickView.SizeRootObjectToView)
view.setTitle(app.translate('app',"Welcome to Mageia"))
app.setWindowIcon(QIcon("/usr/share/icons/hicolor/32x32/apps/mageiawelcome.png"))
cb = Callbrowser()
la = Launcher()
us = username()
ins = Installable()
cl = ConfList()
nr = Norun()
sc = nr.startupcheck()
factor = cl.factor(app)
screen = app.primaryScreen()
# if density is high, use at least factor 2 to scale the initial window. Considering high is more than 190 px/inches.
if screen.logicalDotsPerInch() > 190 :
factor = max(2.0, factor)
defaultHeight = min(int(700 * factor), screen.availableGeometry().height())
defaultWidth = min(int(1000 * factor), screen.availableGeometry().width())
centerPoint = screen.availableGeometry().center()
view.setGeometry(centerPoint.x() -defaultWidth//2, centerPoint.y() - defaultHeight//2, defaultWidth,defaultHeight)
view.rootContext().setContextProperty('link', cb)
view.rootContext().setContextProperty('launch', la)
view.rootContext().setContextProperty('user', us)
view.rootContext().setContextProperty('ConfList', cl)
view.rootContext().setContextProperty('pyinstallable', ins)
view.rootContext().setContextProperty('startupcheck', sc)
view.rootContext().setContextProperty('norun', nr)
current_path = os.path.abspath(os.path.dirname(__file__))
qml_file = os.path.join(current_path, 'mw-ui.qml')
view.setSource(QUrl.fromLocalFile(qml_file))
if view.status() == QQuickView.Error:
for error in view.errors():
print(error.description())
sys.exit(-1)
view.show()
res = app.exec_()
del view
sys.exit(res)