Files
FWS-ISO/configs/releng/airootfs/usr/local/bin/fws-about
T
nocode c7221247f2 fix(fws-about): update distribution description to be more generic
Change the description from "Une distribution Arch Linux" to "Une distribution Linux" to better reflect the project's identity and avoid limiting it to Arch Linux specifically.
2026-07-07 02:46:20 +02:00

186 lines
5.6 KiB
Python
Executable File

#!/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 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 &amp; 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())