97 lines
3.7 KiB
QML
97 lines
3.7 KiB
QML
pragma Singleton
|
|
|
|
import QtQuick
|
|
import Quickshell.Io
|
|
import "." as S
|
|
|
|
QtObject {
|
|
id: root
|
|
|
|
property string systemState: "unknown"
|
|
property string userState: "unknown"
|
|
property var systemUnits: []
|
|
property var userUnits: []
|
|
readonly property int totalFailedCount: systemUnits.length + userUnits.length
|
|
|
|
signal journalReady(string unitName, bool isUser, string text)
|
|
|
|
function refresh() {
|
|
if (!_pollProc.running)
|
|
_pollProc.running = true;
|
|
}
|
|
|
|
function fetchJournal(unitName, isUser) {
|
|
_journalProc.command = isUser ? ["journalctl", "--user", "-u", unitName, "-n", "80", "--no-pager", "--output=short-precise"] : ["journalctl", "-u", unitName, "-n", "80", "--no-pager", "--output=short-precise"];
|
|
_journalProc._unitName = unitName;
|
|
_journalProc._isUser = isUser;
|
|
if (_journalProc.running)
|
|
_journalProc.running = false;
|
|
_journalProc.running = true;
|
|
}
|
|
|
|
function restartUnit(unitName, isUser) {
|
|
_restartProc.command = isUser ? ["systemctl", "--user", "restart", unitName] : ["pkexec", "systemctl", "restart", unitName];
|
|
if (_restartProc.running)
|
|
_restartProc.running = false;
|
|
_restartProc.running = true;
|
|
}
|
|
|
|
function _parseState(json) {
|
|
try {
|
|
return JSON.parse(json).data || "unknown";
|
|
} catch (e) {
|
|
return "unknown";
|
|
}
|
|
}
|
|
|
|
function _parseUnits(json) {
|
|
try {
|
|
const parsed = JSON.parse(json);
|
|
return (parsed.data?.[0] || []).map(u => ({
|
|
name: u[0],
|
|
description: u[1],
|
|
loadState: u[2],
|
|
activeState: u[3],
|
|
subState: u[4]
|
|
}));
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
property Timer _poll: Timer {
|
|
interval: S.Modules.systemd.interval ?? 15000
|
|
running: S.Modules.systemd.enable
|
|
repeat: true
|
|
triggeredOnStart: true
|
|
onTriggered: if (!_pollProc.running)
|
|
_pollProc.running = true
|
|
}
|
|
|
|
// 4 lines of output: systemState, systemUnits, userState, userUnits
|
|
property Process _pollProc: Process {
|
|
command: ["sh", "-c", "busctl get-property --json=short org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager SystemState 2>/dev/null || echo '{}'; " + "busctl call --json=short org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager ListUnitsFiltered as 1 failed 2>/dev/null || echo '{}'; " + "busctl --user get-property --json=short org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager SystemState 2>/dev/null || echo '{}'; " + "busctl --user call --json=short org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager ListUnitsFiltered as 1 failed 2>/dev/null || echo '{}'"]
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
const lines = text.trim().split("\n");
|
|
root.systemState = root._parseState(lines[0] ?? "");
|
|
root.systemUnits = root._parseUnits(lines[1] ?? "");
|
|
root.userState = root._parseState(lines[2] ?? "");
|
|
root.userUnits = root._parseUnits(lines[3] ?? "");
|
|
}
|
|
}
|
|
}
|
|
|
|
property Process _journalProc: Process {
|
|
property string _unitName: ""
|
|
property bool _isUser: false
|
|
stdout: StdioCollector {
|
|
onStreamFinished: root.journalReady(root._journalProc._unitName, root._journalProc._isUser, text)
|
|
}
|
|
}
|
|
|
|
property Process _restartProc: Process {
|
|
onRunningChanged: if (!running)
|
|
root.refresh()
|
|
}
|
|
}
|