feat(fws-about): add fws-about dialog application for system information
Add a new GTK3-based Python application that displays an "About FWS" dialog with two tabs: - "Le projet FWS" tab: shows project name, description, features, and home URL - "Système" tab: displays system information including OS, kernel, desktop environment, hardware (CPU, memory, GPUs, disks) The application detects system information from /proc, lsblk, lspci, and environment variables. It replaces the default Xfce About dialog with FWS branding.
This commit is contained in:
+185
@@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# FWS — fenêtre « À propos » : deux onglets, « Le projet FWS » (ce qu'est FWS,
|
||||||
|
# version, liens) et « Système » (matériel + logiciel détectés). Remplace le
|
||||||
|
# « About Xfce » de libxfce4ui par une page de marque FWS. GTK3 (python-gobject
|
||||||
|
# installé avec le bureau).
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
import gi
|
||||||
|
|
||||||
|
gi.require_version("Gtk", "3.0")
|
||||||
|
gi.require_version("Gdk", "3.0") # sinon gi charge Gdk 4.0 (conflit avec Gtk3)
|
||||||
|
from gi.repository import Gdk, GLib, Gtk # noqa: E402
|
||||||
|
|
||||||
|
GLib.set_prgname("fws-about")
|
||||||
|
|
||||||
|
|
||||||
|
def _osrelease():
|
||||||
|
data = {}
|
||||||
|
for path in ("/etc/os-release", "/usr/lib/os-release"):
|
||||||
|
try:
|
||||||
|
with open(path) as fh:
|
||||||
|
for line in fh:
|
||||||
|
m = re.match(r'^([A-Z_]+)=(.*)$', line.strip())
|
||||||
|
if m:
|
||||||
|
data[m.group(1)] = m.group(2).strip('"')
|
||||||
|
break
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def _cmd(*argv):
|
||||||
|
try:
|
||||||
|
return subprocess.check_output(argv, text=True,
|
||||||
|
stderr=subprocess.DEVNULL).strip()
|
||||||
|
except (OSError, subprocess.CalledProcessError):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def _cpu():
|
||||||
|
try:
|
||||||
|
with open("/proc/cpuinfo") as fh:
|
||||||
|
for line in fh:
|
||||||
|
if line.startswith("model name"):
|
||||||
|
return line.split(":", 1)[1].strip()
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
return "inconnu"
|
||||||
|
|
||||||
|
|
||||||
|
def _mem():
|
||||||
|
try:
|
||||||
|
with open("/proc/meminfo") as fh:
|
||||||
|
for line in fh:
|
||||||
|
if line.startswith("MemTotal"):
|
||||||
|
kib = int(line.split()[1])
|
||||||
|
return f"{kib / 1048576:.1f} Gio"
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
return "inconnu"
|
||||||
|
|
||||||
|
|
||||||
|
def _gpus():
|
||||||
|
out = []
|
||||||
|
for line in _cmd("lspci").splitlines():
|
||||||
|
low = line.lower()
|
||||||
|
if "vga" in low or "3d" in low or "display" in low:
|
||||||
|
out.append(line.split(":", 2)[-1].strip())
|
||||||
|
return out or ["inconnu"]
|
||||||
|
|
||||||
|
|
||||||
|
def _desktop():
|
||||||
|
if os.environ.get("HYPRLAND_INSTANCE_SIGNATURE"):
|
||||||
|
return "Hyprland"
|
||||||
|
env = os.environ.get("XDG_CURRENT_DESKTOP") \
|
||||||
|
or os.environ.get("DESKTOP_SESSION") or ""
|
||||||
|
return env or "inconnu"
|
||||||
|
|
||||||
|
|
||||||
|
def _session_type():
|
||||||
|
t = os.environ.get("XDG_SESSION_TYPE", "")
|
||||||
|
return {"wayland": "Wayland", "x11": "X11"}.get(t, t or "inconnu")
|
||||||
|
|
||||||
|
|
||||||
|
def _disks():
|
||||||
|
out = []
|
||||||
|
for line in _cmd("lsblk", "-dno", "NAME,SIZE,MODEL,TYPE").splitlines():
|
||||||
|
f = line.split()
|
||||||
|
if f and f[-1] == "disk":
|
||||||
|
out.append(" ".join(f[:-1]))
|
||||||
|
return out or ["inconnu"]
|
||||||
|
|
||||||
|
|
||||||
|
def _grid(rows):
|
||||||
|
grid = Gtk.Grid(column_spacing=18, row_spacing=8, margin=18)
|
||||||
|
for i, (key, val) in enumerate(rows):
|
||||||
|
k = Gtk.Label(xalign=1)
|
||||||
|
k.set_markup(f"<b>{GLib.markup_escape_text(key)}</b>")
|
||||||
|
k.get_style_context().add_class("dim-label")
|
||||||
|
v = Gtk.Label(label=val, xalign=0, selectable=True)
|
||||||
|
v.set_line_wrap(True)
|
||||||
|
grid.attach(k, 0, i, 1, 1)
|
||||||
|
grid.attach(v, 1, i, 1, 1)
|
||||||
|
return grid
|
||||||
|
|
||||||
|
|
||||||
|
def _project_tab(osr):
|
||||||
|
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10, margin=20)
|
||||||
|
title = Gtk.Label()
|
||||||
|
name = osr.get("PRETTY_NAME") or osr.get("NAME") or "FWS Linux"
|
||||||
|
title.set_markup(f"<span size='xx-large' weight='bold'>{name}</span>")
|
||||||
|
box.pack_start(title, False, False, 0)
|
||||||
|
|
||||||
|
tag = Gtk.Label(label="Une distribution Arch Linux pensée pour remplacer "
|
||||||
|
"Windows : bureau prêt à l'emploi, jeux, VR et "
|
||||||
|
"compatibilité applicative.")
|
||||||
|
tag.set_line_wrap(True)
|
||||||
|
tag.set_max_width_chars(52)
|
||||||
|
box.pack_start(tag, False, False, 0)
|
||||||
|
|
||||||
|
feats = Gtk.Label()
|
||||||
|
feats.set_markup(
|
||||||
|
"<b>Inclus :</b> installateur graphique · plusieurs bureaux "
|
||||||
|
"(GNOME, KDE, Hyprland, i3, XFCE) · Steam & Proton-GE · "
|
||||||
|
"réalité virtuelle (SteamVR) · winboat (applications Windows) · "
|
||||||
|
"pare-feu · réparation système intégrée.")
|
||||||
|
feats.set_line_wrap(True)
|
||||||
|
feats.set_max_width_chars(52)
|
||||||
|
feats.set_xalign(0)
|
||||||
|
box.pack_start(feats, False, False, 6)
|
||||||
|
|
||||||
|
home = osr.get("HOME_URL") or "https://github.com/You-re-like-Windows-a-bitch/fws"
|
||||||
|
link = Gtk.LinkButton.new_with_label(home, "Site du projet")
|
||||||
|
box.pack_start(link, False, False, 0)
|
||||||
|
return box
|
||||||
|
|
||||||
|
|
||||||
|
def _system_tab(osr):
|
||||||
|
rows = [
|
||||||
|
("Système", osr.get("PRETTY_NAME", "FWS Linux")),
|
||||||
|
("Build", osr.get("BUILD_ID", "rolling")),
|
||||||
|
("Noyau", _cmd("uname", "-r") or "inconnu"),
|
||||||
|
("Bureau", _desktop()),
|
||||||
|
("Affichage", _session_type()),
|
||||||
|
("Nom de machine", _cmd("hostname") or os.uname().nodename),
|
||||||
|
("Processeur", _cpu()),
|
||||||
|
("Mémoire", _mem()),
|
||||||
|
("Carte(s) graphique(s)", "\n".join(_gpus())),
|
||||||
|
("Disque(s)", "\n".join(_disks())),
|
||||||
|
]
|
||||||
|
scroll = Gtk.ScrolledWindow()
|
||||||
|
scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
||||||
|
scroll.add(_grid(rows))
|
||||||
|
return scroll
|
||||||
|
|
||||||
|
|
||||||
|
class AboutWindow(Gtk.Window):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(title="À propos de FWS")
|
||||||
|
self.set_default_size(520, 460)
|
||||||
|
self.set_position(Gtk.WindowPosition.CENTER)
|
||||||
|
self.set_type_hint(Gdk.WindowTypeHint.DIALOG)
|
||||||
|
|
||||||
|
osr = _osrelease()
|
||||||
|
notebook = Gtk.Notebook()
|
||||||
|
notebook.append_page(_project_tab(osr), Gtk.Label(label="Le projet FWS"))
|
||||||
|
notebook.append_page(_system_tab(osr), Gtk.Label(label="Système"))
|
||||||
|
self.add(notebook)
|
||||||
|
self.connect("destroy", Gtk.main_quit)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if not Gtk.init_check()[0]:
|
||||||
|
return 1
|
||||||
|
win = AboutWindow()
|
||||||
|
win.show_all()
|
||||||
|
Gtk.main()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user