summaryrefslogtreecommitdiff
path: root/raveos-app-installer/raveos-app-installer.py
diff options
context:
space:
mode:
authorNippy <nippy@Nippy-Mac-mini.local>2026-10-09 10:49:26 +0200
committerNippy <nippy@Nippy-Mac-mini.local>2026-10-09 10:49:26 +0200
commit91978706279a19a3ac96393630876f3e50cbc518 (patch)
tree1355da60486a305aefeea4e55543bbf1008715b3 /raveos-app-installer/raveos-app-installer.py
parent17a23f8a0cec5439d674d90c593497e4ceed2c68 (diff)
downloadRaveOS-PKGBUILD-91978706279a19a3ac96393630876f3e50cbc518.tar.gz
RaveOS-PKGBUILD-91978706279a19a3ac96393630876f3e50cbc518.zip
fix
Diffstat (limited to 'raveos-app-installer/raveos-app-installer.py')
-rw-r--r--raveos-app-installer/raveos-app-installer.py295
1 files changed, 234 insertions, 61 deletions
diff --git a/raveos-app-installer/raveos-app-installer.py b/raveos-app-installer/raveos-app-installer.py
index d5a9149..d696a58 100644
--- a/raveos-app-installer/raveos-app-installer.py
+++ b/raveos-app-installer/raveos-app-installer.py
@@ -31,15 +31,11 @@ import subprocess
import sys
from pathlib import Path
-# ─────────────────────────────────────────────────────────────────────────────
-# Konstansok / útvonalak
-# ─────────────────────────────────────────────────────────────────────────────
APP_NAME = "RaveOS App Installer"
APP_ID = "raveos-app-installer" # Wayland app_id (Hyprland window rule-okhoz)
APP_VERSION = "3.1"
-# app-list.json keresési sorrend: a script mellett -> /usr/share -> ~/.config
_SCRIPT_DIR = Path(__file__).resolve().parent
APP_LIST_CANDIDATES = [
_SCRIPT_DIR / "app-list.json",
@@ -47,9 +43,6 @@ APP_LIST_CANDIDATES = [
Path.home() / ".config" / "raveos" / "app-list.json",
]
-# ─────────────────────────────────────────────────────────────────────────────
-# Téma (a welcome app stílusa)
-# ─────────────────────────────────────────────────────────────────────────────
C = {
"bg": "#232427",
@@ -68,7 +61,6 @@ C = {
"danger_hi": "#c56458",
}
-# Per-type kis badge színek (visszafogottak)
TYPE_LABEL = {
"pacman": "pacman",
"aur": "AUR",
@@ -79,9 +71,6 @@ TYPE_LABEL = {
}
-# ─────────────────────────────────────────────────────────────────────────────
-# Nyelv (hu/en) - session-szintű, alapértelmezett hu, a welcome app mintájára
-# ─────────────────────────────────────────────────────────────────────────────
_current_lang = "hu"
@@ -90,6 +79,30 @@ T = {
"header_backup": {"hu": " · MENTÉS / VISSZAÁLLÍTÁS", "en": " · BACKUP / RESTORE"},
"nav_backup": {"hu": "Mentés / Visszaállítás", "en": "Backup / Restore"},
"nav_back": {"hu": "← Vissza", "en": "← Back"},
+ "nav_sb": {"hu": "Secure Boot", "en": "Secure Boot"},
+ "header_sb": {"hu": " · SECURE BOOT", "en": " · SECURE BOOT"},
+ "sb_desc": {"hu": "A telepített rendszer aláírása és a kulcsok telepítése a firmware-be.\nWindows dual-boot mellett is biztonságos (Microsoft kulcsok megőrizve).", "en": "Sign the installed system and enroll the keys into the firmware.\nSafe with dual-boot Windows (Microsoft keys preserved)."},
+ "sb_lbl_sb": {"hu": "Secure Boot", "en": "Secure Boot"},
+ "sb_lbl_setup": {"hu": "Setup Mode", "en": "Setup Mode"},
+ "sb_lbl_keys": {"hu": "Gépkulcs", "en": "Machine key"},
+ "sb_lbl_signed": {"hu": "Aláírások", "en": "Signatures"},
+ "sb_val_on": {"hu": "bekapcsolva", "en": "enabled"},
+ "sb_val_off": {"hu": "kikapcsolva", "en": "disabled"},
+ "sb_val_yes": {"hu": "igen", "en": "yes"},
+ "sb_val_no": {"hu": "nem", "en": "no"},
+ "sb_val_ok": {"hu": "rendben", "en": "ok"},
+ "sb_val_missing": {"hu": "hiányzik", "en": "missing"},
+ "sb_btn_refresh": {"hu": "Állapot frissítése", "en": "Refresh status"},
+ "sb_btn_setup": {"hu": "Secure Boot beállítása", "en": "Set up Secure Boot"},
+ "sb_btn_resign": {"hu": "Újra-aláírás", "en": "Re-sign"},
+ "sb_pending": {"hu": "Újraindítás szükséges a befejezéshez!", "en": "Reboot required to finish!"},
+ "sb_bl_warn": {"hu": "BitLocker: ha Windows-on be van kapcsolva, előbb indítsd el a Windowst és futtasd: manage-bde -protectors -disable C: -rebootcount 2 — vagy legyen kéznél a helyreállítási kulcs.", "en": "BitLocker: if enabled on Windows, boot Windows first and run: manage-bde -protectors -disable C: -rebootcount 2 — or have the recovery key ready."},
+ "sb_done_title": {"hu": "Secure Boot beállítva", "en": "Secure Boot configured"},
+ "sb_done_msg": {"hu": "Az aláírások és a kulcsok készen vannak.\n\nA BIOS-ban állítsd: Secure Boot → Enabled, majd indítsd újra a gépet.", "en": "Signatures and keys are ready.\n\nIn the BIOS set: Secure Boot → Enabled, then reboot."},
+ "sb_reboot_title": {"hu": "Újraindítás szükséges", "en": "Reboot required"},
+ "sb_reboot_msg": {"hu": "A BIOS-ban töröld a Secure Boot kulcsokat (Clear Secure Boot keys → Setup Mode).\nMentés után indítsd újra a gépet — a beállítás boot után automatikusan befejeződik.\n\nÚjraindítsam most?", "en": "In the BIOS clear the Secure Boot keys (Clear Secure Boot keys → Setup Mode).\nSave and reboot — the setup finishes automatically after boot.\n\nReboot now?"},
+ "sb_err_title": {"hu": "Secure Boot hiba", "en": "Secure Boot error"},
+ "sb_err_msg": {"hu": "A művelet nem sikerült — a részletek a naplóban láthatók.", "en": "The operation failed — details are in the log."},
"tab_all": {"hu": "Összes", "en": "All"},
"tab_installed": {"hu": "Telepített", "en": "Installed"},
"search_placeholder": {"hu": "Keresés…", "en": "Search…"},
@@ -296,9 +309,6 @@ def build_qss() -> str:
"""
-# ─────────────────────────────────────────────────────────────────────────────
-# Adat: katalógus betöltés + telepítettség detektálás
-# ─────────────────────────────────────────────────────────────────────────────
def load_catalog() -> list:
"""app-list.json beolvasása az első létező útvonalról."""
@@ -368,9 +378,6 @@ def is_installed(app: dict, idx: dict) -> bool:
return False
-# ─────────────────────────────────────────────────────────────────────────────
-# Parancs-építés (telepítés / eltávolítás), batch-elve backendenként
-# ─────────────────────────────────────────────────────────────────────────────
def _root_prefix(gui: bool) -> list:
"""GUI -> sudo -S (jelszó stdin-ről), terminál -> sudo, ha már root -> semmi."""
@@ -419,8 +426,6 @@ def plan_commands(apps: list, install: bool, gui: bool) -> list:
if aur:
if install:
- # --answer* nelkul a yay a PKGBUILD-diff/edit prompt-nal orokre
- # varakozik (nincs csatolt terminal a stream_command-hoz)
steps.append((f"AUR: {', '.join(aur)}",
["yay", "-S", "--needed", "--noconfirm",
"--answerclean", "None", "--answerdiff", "None",
@@ -447,10 +452,6 @@ def plan_commands(apps: list, install: bool, gui: bool) -> list:
steps.append((f"flatpak uninstall: {fid}",
["flatpak", "uninstall", "--user", "-y", fid]))
- # Config seedelés: pacman/aur/flatpak-user tipusu appoknal a config_dir/
- # config_dest mezok alapjan bemasoljuk az elore elkeszitett configot a
- # user home-jaba, telepites utan. (script tipusnal ezt a sajat bash
- # script intezi, azoknal nem kell ez a lepes.)
if install:
_home = os.path.expanduser("~")
for a in apps:
@@ -471,10 +472,6 @@ def plan_commands(apps: list, install: bool, gui: bool) -> list:
f"cp {cp_flag} {shlex.quote(str(src))}/. {shlex.quote(dest)}/ && "
f"rm -f {shlex.quote(dest)}/Singleton*"]))
- # Config seedelés (több-utas változat): olyan appoknal, ahol tobb kulon
- # forras/cel par van (pl. PhotoGIMP: GIMP config + .desktop + ikonok
- # kulon-kulon helyre), a "config_mappings" listat hasznaljuk a fenti
- # egyszeru config_dir/config_dest helyett.
if install:
_home = os.path.expanduser("~")
for a in apps:
@@ -496,7 +493,6 @@ def plan_commands(apps: list, install: bool, gui: bool) -> list:
f"cp {cp_flag} {shlex.quote(str(src))}/. {shlex.quote(dest)}/ && "
f"rm -f {shlex.quote(dest)}/Singleton*"]))
- # Script env: a szkript tudja ki a tényleges user (sudo után root fut)
_caller = os.environ.get("USER") or os.environ.get("LOGNAME") or ""
_caller_home = os.path.expanduser("~")
_caller_uid = str(os.getuid())
@@ -547,9 +543,6 @@ def stream_command(label: str, cmd: list, emit, password: str = "") -> bool:
return ok
-# ─────────────────────────────────────────────────────────────────────────────
-# GUI rész (csak ha van PyQt6 / display)
-# ─────────────────────────────────────────────────────────────────────────────
BACKUP_LIST_CANDIDATES = [
_SCRIPT_DIR / "data/backup/backup-paths.json",
@@ -578,7 +571,6 @@ def run_gui() -> int:
from PyQt6.QtCore import Qt, QThread, pyqtSignal
from PyQt6.QtGui import QFont, QFontDatabase
- # ── display font helper (Bebas Neue, fallbackkel) ────────────────────────
def display_font(size: int, weight=QFont.Weight.Normal) -> QFont:
for fam in ("Bebas Neue", "Oswald", "Anton"):
if fam in QFontDatabase.families():
@@ -591,7 +583,6 @@ def run_gui() -> int:
f.setLetterSpacing(QFont.SpacingType.PercentageSpacing, 102)
return f
- # ── háttér worker ────────────────────────────────────────────────────────
class Worker(QThread):
log = pyqtSignal(str)
progress = pyqtSignal(int) # 0..100
@@ -613,7 +604,6 @@ def run_gui() -> int:
self.progress.emit(int((i + 1) / total * 100))
self.done.emit(ok, total)
- # ── egy app sor widget ───────────────────────────────────────────────────
class Row(QFrame):
def __init__(self, app, installed):
super().__init__()
@@ -652,7 +642,6 @@ def run_gui() -> int:
f"color:{C['accent_hi'] if installed else C['text_mut']}; font-size:12px;")
lay.addWidget(status)
- # sorra kattintás is váltja a checkboxot (message tipusnal dialogot mutat)
self.setCursor(Qt.CursorShape.PointingHandCursor)
def mousePressEvent(self, e):
@@ -664,7 +653,34 @@ def run_gui() -> int:
self.cb.toggle()
super().mousePressEvent(e)
- # ── backup worker ────────────────────────────────────────────────────────
+ class SbWorker(QThread):
+ log = pyqtSignal(str)
+ done = pyqtSignal(int)
+
+ def __init__(self, mode, password):
+ super().__init__()
+ self.mode = mode
+ self.password = password
+
+ def run(self):
+ cmd = ["sudo", "-S", "-p", "", "raveos-secureboot-setup", self.mode]
+ self.log.emit(f"$ {' '.join(cmd)}")
+ try:
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
+ stdin=subprocess.PIPE, text=True, bufsize=1)
+ if self.password:
+ proc.stdin.write(self.password + "\n")
+ proc.stdin.flush()
+ proc.stdin.close()
+ except OSError as exc:
+ self.log.emit(f"[HIBA] {exc}")
+ self.done.emit(1)
+ return
+ for line in proc.stdout:
+ self.log.emit(line.rstrip("\n"))
+ proc.wait()
+ self.done.emit(proc.returncode)
+
class BackupWorker(QThread):
log = pyqtSignal(str)
progress = pyqtSignal(int)
@@ -792,7 +808,6 @@ def run_gui() -> int:
except Exception as exc:
self.done.emit(False, str(exc))
- # ── fő ablak ─────────────────────────────────────────────────────────────
class Main(QMainWindow):
def __init__(self, catalog):
super().__init__()
@@ -801,6 +816,7 @@ def run_gui() -> int:
self.idx = installed_index()
self.rows = []
self.worker = None
+ self.sb_worker = None
self.backup_worker = None
self.backup_checkboxes = {} # item_id -> (QCheckBox, abs_path, label, requires_root)
self._sudo_pw = ""
@@ -815,7 +831,6 @@ def run_gui() -> int:
outer.setContentsMargins(0, 0, 0, 0)
outer.setSpacing(0)
- # ── Header ───────────────────────────────────────────────────────
header = QFrame()
header.setObjectName("Header")
hl = QHBoxLayout(header)
@@ -852,6 +867,11 @@ def run_gui() -> int:
self._style_lang_btns()
hl.addSpacing(12)
+ self.btn_sb = QPushButton(tr("nav_sb"))
+ self.btn_sb.clicked.connect(self._go_sb)
+ hl.addWidget(self.btn_sb)
+ hl.addSpacing(8)
+
self.btn_nav = QPushButton(tr("nav_backup"))
self.btn_nav.clicked.connect(self._go_backup)
hl.addWidget(self.btn_nav)
@@ -861,11 +881,9 @@ def run_gui() -> int:
hl.addWidget(ver)
outer.addWidget(header)
- # ── Stack ─────────────────────────────────────────────────────────
self.stack = QStackedWidget()
outer.addWidget(self.stack, 1)
- # ── Oldal 0: Apps ─────────────────────────────────────────────────
apps_page = QWidget()
bl = QVBoxLayout(apps_page)
bl.setContentsMargins(20, 16, 20, 16)
@@ -935,7 +953,6 @@ def run_gui() -> int:
self.stack.addWidget(apps_page)
- # ── Oldal 1: Backup / Restore ─────────────────────────────────────
bk_page = QWidget()
bbl = QVBoxLayout(bk_page)
bbl.setContentsMargins(20, 16, 20, 16)
@@ -987,10 +1004,75 @@ def run_gui() -> int:
self.stack.addWidget(bk_page)
+ sb_page = QWidget()
+ sbl = QVBoxLayout(sb_page)
+ sbl.setContentsMargins(20, 16, 20, 16)
+ sbl.setSpacing(12)
+
+ self.sb_desc = QLabel(tr("sb_desc"))
+ self.sb_desc.setWordWrap(True)
+ self.sb_desc.setStyleSheet(f"color:{C['text_dim']};")
+ sbl.addWidget(self.sb_desc)
+
+ self.sb_lbls = {}
+ self.sb_vals = {}
+ srow1 = QHBoxLayout()
+ srow1.setSpacing(8)
+ srow2 = QHBoxLayout()
+ srow2.setSpacing(8)
+ for i, key in enumerate(("sb_lbl_sb", "sb_lbl_setup", "sb_lbl_keys", "sb_lbl_signed")):
+ lbl = QLabel(tr(key))
+ lbl.setStyleSheet(f"color:{C['text_dim']};")
+ val = QLabel("-")
+ val.setStyleSheet(f"color:{C['text']}; font-weight:600;")
+ self.sb_lbls[key] = lbl
+ self.sb_vals[key] = val
+ box = QHBoxLayout()
+ box.setSpacing(6)
+ box.addWidget(lbl)
+ box.addWidget(val)
+ (srow1 if i < 2 else srow2).addLayout(box)
+ (srow1 if i < 2 else srow2).addSpacing(24)
+ srow1.addStretch(1)
+ srow2.addStretch(1)
+ sbl.addLayout(srow1)
+ sbl.addLayout(srow2)
+
+ self.sb_warn = QLabel(tr("sb_bl_warn"))
+ self.sb_warn.setWordWrap(True)
+ self.sb_warn.setStyleSheet("color:#d0a24c;")
+ sbl.addWidget(self.sb_warn)
+
+ self.sb_pending = QLabel(tr("sb_pending"))
+ self.sb_pending.setStyleSheet("color:#d0a24c; font-weight:700;")
+ self.sb_pending.hide()
+ sbl.addWidget(self.sb_pending)
+
+ sb_row = QHBoxLayout()
+ sb_row.setSpacing(8)
+ self.btn_sb_refresh = QPushButton(tr("sb_btn_refresh"))
+ self.btn_sb_refresh.clicked.connect(self._sb_refresh)
+ self.btn_sb_setup = QPushButton(tr("sb_btn_setup"))
+ self.btn_sb_setup.setObjectName("Primary")
+ self.btn_sb_setup.clicked.connect(self._sb_setup)
+ self.btn_sb_resign = QPushButton(tr("sb_btn_resign"))
+ self.btn_sb_resign.clicked.connect(self._sb_resign)
+ sb_row.addWidget(self.btn_sb_refresh)
+ sb_row.addWidget(self.btn_sb_setup)
+ sb_row.addWidget(self.btn_sb_resign)
+ sb_row.addStretch(1)
+ sbl.addLayout(sb_row)
+
+ self.sb_log = QPlainTextEdit()
+ self.sb_log.setObjectName("Log")
+ self.sb_log.setReadOnly(True)
+ sbl.addWidget(self.sb_log, 1)
+
+ self.stack.addWidget(sb_page)
+
self.build_rows()
self.apply_filter()
- # ── nyelv ─────────────────────────────────────────────────────────────
def _style_lang_btns(self):
active = (
f"QPushButton {{ background: {C['accent']}; color: #15240f;"
@@ -1016,9 +1098,23 @@ def run_gui() -> int:
self._retranslate_all()
def _retranslate_all(self):
- on_backup = self.stack.currentIndex() == 1
- self.header_sep.setText(tr("header_backup") if on_backup else tr("header_installer"))
- self.btn_nav.setText(tr("nav_back") if on_backup else tr("nav_backup"))
+ idx = self.stack.currentIndex()
+ if idx == 1:
+ self.header_sep.setText(tr("header_backup"))
+ elif idx == 2:
+ self.header_sep.setText(tr("header_sb"))
+ else:
+ self.header_sep.setText(tr("header_installer"))
+ self.btn_nav.setText(tr("nav_back") if idx != 0 else tr("nav_backup"))
+ self.btn_sb.setText(tr("nav_sb"))
+ self.sb_desc.setText(tr("sb_desc"))
+ for key, lbl in self.sb_lbls.items():
+ lbl.setText(tr(key))
+ self.sb_warn.setText(tr("sb_bl_warn"))
+ self.sb_pending.setText(tr("sb_pending"))
+ self.btn_sb_refresh.setText(tr("sb_btn_refresh"))
+ self.btn_sb_setup.setText(tr("sb_btn_setup"))
+ self.btn_sb_resign.setText(tr("sb_btn_resign"))
self.tab_all.setText(tr("tab_all"))
self.tab_inst.setText(tr("tab_installed"))
self.search.setPlaceholderText(tr("search_placeholder"))
@@ -1042,7 +1138,6 @@ def run_gui() -> int:
self.scroll.verticalScrollBar().setValue(keep_scroll)
self.build_backup_items()
- # ── backup lista építés (nyelvváltáskor is újraépül) ────────────────────
def build_backup_items(self):
prev_checked = {iid: cb.isChecked() for iid, (cb, _, _, _) in self.backup_checkboxes.items()}
while self.bk_vl.count():
@@ -1098,13 +1193,11 @@ def run_gui() -> int:
self.bk_vl.addWidget(brow)
self.bk_vl.addStretch(1)
- # ── frissítés ─────────────────────────────────────────────────────────
def _refresh_and_filter(self):
self.idx = installed_index()
self.build_rows()
self.apply_filter()
- # ── navigáció ─────────────────────────────────────────────────────────
def _go_backup(self):
self.stack.setCurrentIndex(1)
self.header_sep.setText(tr("header_backup"))
@@ -1119,7 +1212,99 @@ def run_gui() -> int:
self.btn_nav.clicked.disconnect()
self.btn_nav.clicked.connect(self._go_backup)
- # ── lista építés ──────────────────────────────────────────────────────
+ def _go_sb(self):
+ self.stack.setCurrentIndex(2)
+ self.header_sep.setText(tr("header_sb"))
+ self.btn_nav.setText(tr("nav_back"))
+ self.btn_nav.clicked.disconnect()
+ self.btn_nav.clicked.connect(self._go_apps)
+ self._sb_refresh()
+
+ def _sb_refresh(self):
+ self.sb_log.clear()
+ import time
+ out = ""
+ cached = self._sudo_pw if (self._sudo_pw and (time.time() - self._sudo_pw_ts) < 300) else ""
+ try:
+ for cmd in (["raveos-secureboot-setup", "--status"],
+ ["sudo", "-n", "raveos-secureboot-setup", "--status"]):
+ res = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
+ out = res.stdout
+ if out.strip():
+ break
+ if not out.strip() and cached:
+ res = subprocess.run(["sudo", "-S", "-p", "", "raveos-secureboot-setup", "--status"],
+ input=cached + "\n", capture_output=True, text=True, timeout=15)
+ out = res.stdout
+ except (OSError, subprocess.TimeoutExpired) as exc:
+ self.sb_log.appendPlainText(f"[HIBA] {exc}")
+ return
+ data = {}
+ for line in out.splitlines():
+ if "=" in line and not line.startswith("["):
+ k, _, val = line.partition("=")
+ data[k.strip()] = val.strip()
+ elif line.strip():
+ self.sb_log.appendPlainText(line)
+ if not data:
+ if not out.strip():
+ self.sb_log.appendPlainText("[raveos-sb] Az allapot nem olvashato.")
+ return
+ on = lambda x: tr("sb_val_on") if x == "1" else tr("sb_val_off")
+ yes = lambda x: tr("sb_val_yes") if x == "1" else tr("sb_val_no")
+ ok = lambda x: tr("sb_val_ok") if x == "1" else tr("sb_val_missing")
+ self.sb_vals["sb_lbl_sb"].setText(on(data.get("secureboot", "?")))
+ self.sb_vals["sb_lbl_setup"].setText(yes(data.get("setupmode", "?")))
+ self.sb_vals["sb_lbl_keys"].setText(ok(data.get("keys", "0")))
+ self.sb_vals["sb_lbl_signed"].setText(ok(data.get("signed", "0")))
+ self.sb_pending.setVisible(data.get("pending") == "1")
+
+ def _sb_run(self, mode):
+ if self.sb_worker and self.sb_worker.isRunning():
+ return
+ import time
+ if os.geteuid() != 0:
+ if self._sudo_pw and (time.time() - self._sudo_pw_ts) < 300:
+ password = self._sudo_pw
+ else:
+ password = self._ask_password()
+ if not password:
+ return
+ self._sudo_pw = password
+ self._sudo_pw_ts = time.time()
+ else:
+ password = ""
+ self.sb_log.clear()
+ self.btn_sb_setup.setEnabled(False)
+ self.btn_sb_resign.setEnabled(False)
+ self.btn_sb_refresh.setEnabled(False)
+ self.sb_worker = SbWorker(mode, password)
+ self.sb_worker.log.connect(self.sb_log.appendPlainText)
+ self.sb_worker.done.connect(self._sb_finished)
+ self.sb_worker.start()
+
+ def _sb_setup(self):
+ self._sb_run("--setup")
+
+ def _sb_resign(self):
+ self._sb_run("--resign")
+
+ def _sb_finished(self, rc):
+ self.btn_sb_setup.setEnabled(True)
+ self.btn_sb_resign.setEnabled(True)
+ self.btn_sb_refresh.setEnabled(True)
+ self._sb_refresh()
+ if rc == 0:
+ QMessageBox.information(self, tr("sb_done_title"), tr("sb_done_msg"))
+ elif rc == 10:
+ answer = QMessageBox.question(
+ self, tr("sb_reboot_title"), tr("sb_reboot_msg"),
+ QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No)
+ if answer == QMessageBox.StandardButton.Yes:
+ subprocess.Popen(["systemctl", "reboot"])
+ else:
+ QMessageBox.critical(self, tr("sb_err_title"), tr("sb_err_msg"))
+
def build_rows(self):
for r in self.rows:
r.setParent(None)
@@ -1154,7 +1339,6 @@ def run_gui() -> int:
return [r.app for r in self.rows
if r.cb.isChecked() and r.isVisible() and not r.is_message]
- # ── app akció ─────────────────────────────────────────────────────────
def _ask_password(self) -> str:
"""Jelszó dialog - egyszer fut az akció elején. Üres string = megszakítva."""
err_msg = ""
@@ -1221,7 +1405,6 @@ def run_gui() -> int:
return pw
err_msg = tr("dlg_pw_wrong_err")
except Exception:
- # Ha az ellenőrzés nem sikerül, elfogadjuk és hagyjuk a parancsot hibázni
return pw
def run_action(self, install: bool):
@@ -1236,7 +1419,6 @@ def run_gui() -> int:
self.log.appendPlainText(tr("log_nothing_to_do"))
return
- # Jelszó - 5 percen belül megjegyzett jelszót újra felhasználjuk
import time
if os.geteuid() != 0:
if self._sudo_pw and (time.time() - self._sudo_pw_ts) < 300:
@@ -1281,7 +1463,6 @@ def run_gui() -> int:
self.search.setEnabled(not busy)
self.cat.setEnabled(not busy)
- # ── backup akciók ─────────────────────────────────────────────────────
def _bk_browse(self):
path, _ = QFileDialog.getSaveFileName(
self, tr("filedialog_caption"), str(Path.home()), "Tar archive (*.tar.gz)")
@@ -1365,7 +1546,6 @@ def run_gui() -> int:
self.bk_log.appendPlainText(f"\n{tr('bk_result_ok') if ok else tr('bk_result_err')}: {msg}")
self._bk_set_busy(False)
- # ── alkalmazás bootstrap ─────────────────────────────────────────────────
if shutil.which("hyprctl"):
subprocess.run(
["hyprctl", "keyword", "windowrulev2",
@@ -1390,9 +1570,6 @@ def run_gui() -> int:
return app.exec()
-# ─────────────────────────────────────────────────────────────────────────────
-# CLI rész
-# ─────────────────────────────────────────────────────────────────────────────
def _resolve(names, catalog):
by = {a["name"].lower(): a for a in catalog}
@@ -1425,9 +1602,6 @@ def cli_action(names, catalog, install: bool):
print("Nincs végrehajtható lépés.")
return 1
- # sudo -S jelszo nelkul a stdin pipe nyitva marad iras/EOF nelkul,
- # es a folyamat orokre lefagy - a GUI-nak van jelszo dialogja, a
- # CLI-nek eddig nem volt.
password = ""
if os.geteuid() != 0 and any(
len(cmd) >= 2 and cmd[0] == "sudo" and cmd[1] == "-S" for _, cmd in steps
@@ -1457,7 +1631,6 @@ def main():
cli_mode = args.list or args.installed or args.install or args.remove
if not cli_mode:
- # GUI-t user-ként indítsd (Wayland) - root GUI ne!
if os.geteuid() == 0:
print("Figyelem: a GUI-t NE rootként indítsd. "
"Futtasd sima userként, a jogot pkexec kéri majd.")