summaryrefslogtreecommitdiff
path: root/raveos-center/raveos_center/rendszerinfo.py
diff options
context:
space:
mode:
Diffstat (limited to 'raveos-center/raveos_center/rendszerinfo.py')
-rw-r--r--raveos-center/raveos_center/rendszerinfo.py240
1 files changed, 240 insertions, 0 deletions
diff --git a/raveos-center/raveos_center/rendszerinfo.py b/raveos-center/raveos_center/rendszerinfo.py
new file mode 100644
index 0000000..b526670
--- /dev/null
+++ b/raveos-center/raveos_center/rendszerinfo.py
@@ -0,0 +1,240 @@
+import json
+import os
+import platform
+import re
+import shutil
+import subprocess
+import threading
+import time
+from pathlib import Path
+
+
+def _futtat(parancs, ido=60):
+ try:
+ kimenet = subprocess.run(parancs, capture_output=True, text=True, timeout=ido)
+ except (OSError, subprocess.TimeoutExpired):
+ return None
+ return kimenet
+
+
+def os_release():
+ adat = {}
+ try:
+ for sor in Path("/etc/os-release").read_text().splitlines():
+ if "=" in sor:
+ k, _, v = sor.partition("=")
+ adat[k] = v.strip().strip('"')
+ except OSError:
+ pass
+ return adat
+
+
+def raveos_verzio():
+ adat = os_release()
+ nev = adat.get("NAME", "RaveOS")
+ verzio = adat.get("VERSION_ID") or adat.get("BUILD_ID") or ""
+ return f"{nev} {verzio}".strip()
+
+
+def kernel():
+ return platform.release()
+
+
+def asztal():
+ nev = os.environ.get("XDG_CURRENT_DESKTOP") or os.environ.get("DESKTOP_SESSION") or "ismeretlen"
+ nev = nev.split(":")[-1]
+ tipus = os.environ.get("XDG_SESSION_TYPE", "")
+ return f"{nev} ({tipus.capitalize()})" if tipus else nev
+
+
+def cpu():
+ try:
+ for sor in Path("/proc/cpuinfo").read_text().splitlines():
+ if sor.startswith("model name"):
+ nev = sor.split(":", 1)[1].strip()
+ return re.sub(r"\s+", " ", re.sub(r"\((R|TM)\)|CPU|Processor", "", nev)).strip()
+ except OSError:
+ pass
+ return platform.processor() or "ismeretlen"
+
+
+def gpuk():
+ lista = []
+ kimenet = _futtat(["lspci", "-mm"])
+ if not kimenet or kimenet.returncode != 0:
+ return lista
+ for sor in kimenet.stdout.splitlines():
+ mezok = re.findall(r'"([^"]*)"', sor)
+ if len(mezok) >= 3 and re.search(r"VGA|3D|Display", mezok[0]):
+ gyarto = mezok[1].replace("Advanced Micro Devices, Inc. ", "").replace(" Corporation", "")
+ gyarto = gyarto.replace("[AMD/ATI]", "AMD").strip()
+ nev = mezok[2]
+ talalat = re.search(r"\[([^\]]+)\]", nev)
+ lista.append(f"{gyarto} {talalat.group(1) if talalat else nev}".strip())
+ return lista
+
+
+def gpu_driverek():
+ driverek = []
+ for kartya in sorted(Path("/sys/class/drm").glob("card[0-9]")):
+ try:
+ nev = (kartya / "device" / "driver").resolve().name
+ except OSError:
+ continue
+ if nev and nev not in driverek:
+ driverek.append(nev)
+ return driverek
+
+
+def memoria():
+ try:
+ for sor in Path("/proc/meminfo").read_text().splitlines():
+ if sor.startswith("MemTotal:"):
+ kb = int(sor.split()[1])
+ return f"{kb / 1024 / 1024:.1f} GB"
+ except (OSError, ValueError):
+ pass
+ return "ismeretlen"
+
+
+def fajlrendszer(hely="/"):
+ kimenet = _futtat(["findmnt", "-no", "FSTYPE", hely])
+ if kimenet and kimenet.returncode == 0 and kimenet.stdout.strip():
+ return kimenet.stdout.strip().splitlines()[0]
+ try:
+ for sor in reversed(Path("/proc/mounts").read_text().splitlines()):
+ mezok = sor.split()
+ if len(mezok) > 2 and mezok[1] == hely:
+ return mezok[2]
+ except OSError:
+ pass
+ return "ismeretlen"
+
+
+def uzemido():
+ try:
+ mp = int(float(Path("/proc/uptime").read_text().split()[0]))
+ except (OSError, ValueError):
+ return "ismeretlen"
+ nap, mp = divmod(mp, 86400)
+ ora, mp = divmod(mp, 3600)
+ perc = mp // 60
+ if nap:
+ return f"{nap} nap {ora} óra"
+ if ora:
+ return f"{ora} óra {perc} perc"
+ return f"{perc} perc"
+
+
+def lemez(hely="/"):
+ hasznalat = shutil.disk_usage(hely)
+ return hasznalat.used, hasznalat.total
+
+
+UJRAINDITOS = re.compile(
+ r"^(linux|linux-[a-z0-9-]+|nvidia.*|mesa|lib32-mesa|amd-ucode|intel-ucode|systemd|glibc|dbus|dbus-broker)$"
+)
+
+_frissites_zar = threading.Lock()
+_frissites_tar = {"ido": 0.0, "lista": None}
+FRISSITES_TAR_IDO = 600
+
+
+def _pacman_meretek(nevek):
+ db = os.environ.get("CHECKUPDATES_DB") or f"{os.environ.get('TMPDIR', '/tmp')}/checkup-db-{os.getuid()}"
+ kimenet = _futtat(
+ ["pacman", "-Sup", "--dbpath", db, "--logfile", "/dev/null", "--print-format", "%n %s"], ido=60
+ )
+ meretek = {}
+ if kimenet and kimenet.returncode == 0:
+ for sor in kimenet.stdout.splitlines():
+ r = sor.split()
+ if len(r) == 2 and r[1].isdigit():
+ meretek[r[0]] = int(r[1])
+ return {n: meretek.get(n) for n in nevek}
+
+
+def _meret_szoveg(szoveg):
+ talalat = re.match(r"([\d.,]+)\s*([kMG]?B)", szoveg.replace("\xa0", " "))
+ if not talalat:
+ return None
+ szam = float(talalat.group(1).replace(",", "."))
+ return int(szam * {"B": 1, "kB": 1e3, "MB": 1e6, "GB": 1e9}[talalat.group(2)])
+
+
+def _frissitesek_lekerdez():
+ csomagok = []
+ if not shutil.which("checkupdates"):
+ raise RuntimeError("a checkupdates nem elérhető (pacman-contrib)")
+ pac = _futtat(["checkupdates", "--nocolor"], ido=180)
+ if not pac or pac.returncode not in (0, 2):
+ raise RuntimeError("a pacman frissítések ellenőrzése nem sikerült")
+ if pac.returncode == 0:
+ for sor in pac.stdout.splitlines():
+ r = sor.split()
+ if len(r) >= 4:
+ csomagok.append({"nev": r[0], "forras": "pacman", "regi": r[1], "uj": r[3], "meret": None})
+ meretek = _pacman_meretek([c["nev"] for c in csomagok])
+ for c in csomagok:
+ c["meret"] = meretek.get(c["nev"])
+ if shutil.which("yay"):
+ aur = _futtat(["yay", "-Qua", "--color", "never"], ido=180)
+ if aur and aur.returncode in (0, 1):
+ for sor in aur.stdout.splitlines():
+ r = sor.split()
+ if len(r) >= 4 and r[2] == "->":
+ csomagok.append({"nev": r[0], "forras": "aur", "regi": r[1], "uj": r[3], "meret": None})
+ if shutil.which("flatpak"):
+ fp = _futtat(
+ ["flatpak", "remote-ls", "--updates", "--columns=application,version,download-size"], ido=180
+ )
+ if fp and fp.returncode == 0:
+ for sor in fp.stdout.splitlines():
+ r = sor.split("\t")
+ if r and r[0] and r[0] != "Application ID":
+ csomagok.append({
+ "nev": r[0],
+ "forras": "flatpak",
+ "regi": "",
+ "uj": r[1] if len(r) > 1 else "",
+ "meret": _meret_szoveg(r[2]) if len(r) > 2 else None,
+ })
+ for c in csomagok:
+ c["ujrainditas"] = c["forras"] == "pacman" and bool(UJRAINDITOS.match(c["nev"]))
+ return csomagok
+
+
+def frissitesek(friss=False):
+ with _frissites_zar:
+ tar = _frissites_tar
+ if not friss and tar["lista"] is not None and time.monotonic() - tar["ido"] < FRISSITES_TAR_IDO:
+ return [dict(c) for c in tar["lista"]]
+ lista = _frissitesek_lekerdez()
+ tar["lista"] = lista
+ tar["ido"] = time.monotonic()
+ tar["mikor"] = time.time()
+ return [dict(c) for c in lista]
+
+
+def frissites_ellenorizve():
+ return _frissites_tar.get("mikor")
+
+
+def snapper_elerheto():
+ return bool(shutil.which("snapper")) and Path("/etc/snapper/configs/root").exists()
+
+
+def utolso_snapshot():
+ if not shutil.which("snapper"):
+ return None
+ kimenet = _futtat(["snapper", "--jsonout", "-c", "root", "list"], ido=30)
+ if not kimenet or kimenet.returncode != 0:
+ return None
+ try:
+ lista = json.loads(kimenet.stdout).get("root", [])
+ except ValueError:
+ return None
+ lista = [s for s in lista if s.get("number", 0) != 0]
+ if not lista:
+ return {}
+ return lista[-1]