Skip to content

Commit ffcafe2

Browse files
systemUptime@KopfdesDaemons: Add options for start date and uptime days (#1533)
* Closes #1530 --------- Co-authored-by: Georg Sieber <it@georg-sieber.de>
1 parent 6bebafd commit ffcafe2

10 files changed

Lines changed: 365 additions & 215 deletions

File tree

systemUptime@KopfDesDaemons/files/systemUptime@KopfDesDaemons/desklet.js

Lines changed: 142 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -14,140 +14,155 @@ const UUID = "systemUptime@KopfDesDaemons";
1414
Gettext.bindtextdomain(UUID, GLib.get_home_dir() + "/.local/share/locale");
1515

1616
function _(str) {
17-
return Gettext.dgettext(UUID, str);
17+
return Gettext.dgettext(UUID, str);
1818
}
1919

2020
class MyDesklet extends Desklet.Desklet {
21-
constructor(metadata, deskletId) {
22-
super(metadata, deskletId);
23-
24-
this.settings = new Settings.DeskletSettings(this, metadata["uuid"], deskletId);
25-
26-
// Bind settings properties
27-
this.settings.bindProperty(Settings.BindingDirection.IN, "fontSize", "fontSize", this.onSettingsChanged.bind(this));
28-
this.settings.bindProperty(Settings.BindingDirection.IN, "colorLabel", "colorLabel", this.onSettingsChanged.bind(this));
29-
30-
this.fontSize = this.settings.getValue("fontSize") || 20;
31-
this.colorLabel = this.settings.getValue("colorLabel") || "rgb(51, 209, 122)";
32-
this._timeout = null;
33-
34-
this.setHeader(_("System Uptime"));
35-
this.setupLayout();
36-
this.getStartupTime();
37-
this.updateUptime();
38-
}
39-
40-
setupLayout() {
41-
// Create labels for uptime
42-
this.uptimeLabel = this.createLabel(_("Uptime:") + " ", this.colorLabel);
43-
this.uptimeValue = this.createLabel(_("Loading..."));
44-
45-
const uptimeRow = this.createRow([this.uptimeLabel, this.uptimeValue]);
46-
47-
// Create labels for startup time
48-
this.startTimeLabel = this.createLabel(_("System start time:") + " ", this.colorLabel);
49-
this.startupValue = this.createLabel(_("Loading..."));
50-
51-
const startupRow = this.createRow([this.startTimeLabel, this.startupValue]);
52-
53-
// Combine all into the main container
54-
const contentBox = new St.BoxLayout({ vertical: true });
55-
contentBox.set_style("margin-left: 0.5em;");
56-
contentBox.add_child(startupRow);
57-
contentBox.add_child(uptimeRow);
58-
59-
this.container = new St.BoxLayout();
60-
this.container.add_child(contentBox);
61-
62-
Mainloop.idle_add(() => {
63-
let computedHeight = contentBox.get_height();
64-
65-
const clockIcon = this.getImageAtScale(
66-
`${this.metadata.path}/clock.svg`,
67-
computedHeight,
68-
computedHeight,
69-
);
70-
71-
this.container.insert_child_below(clockIcon, contentBox);
72-
clockIcon.queue_relayout();
73-
74-
return false;
75-
});
76-
77-
this.setContent(this.container);
78-
}
79-
80-
createLabel(text, color = "inherit") {
81-
return new St.Label({
82-
text,
83-
y_align: St.Align.START,
84-
style: `font-size: ${this.fontSize}px; color: ${color};`
85-
});
86-
}
87-
88-
createRow(children) {
89-
const row = new St.BoxLayout();
90-
children.forEach(child => row.add_child(child));
91-
return row;
92-
}
93-
94-
updateUptime() {
95-
try {
96-
const [result, out] = GLib.spawn_command_line_sync("awk '{print $1}' /proc/uptime");
97-
if (!result || !out) throw new Error("Could not get system uptime.");
98-
99-
const uptimeInSeconds = parseFloat(out.toString().trim());
100-
const hours = Math.floor(uptimeInSeconds / 3600);
101-
const minutes = Math.floor((uptimeInSeconds % 3600) / 60);
102-
103-
this.uptimeValue.set_text(`${hours} ${_("hours")} ${minutes} ${_("minutes")}`);
104-
} catch (error) {
105-
this.uptimeValue.set_text("Error");
106-
global.logError(`${UUID}: ${error.message}`);
107-
}
108-
109-
if (this._timeout) Mainloop.source_remove(this._timeout);
110-
this._timeout = Mainloop.timeout_add_seconds(60, () => this.updateUptime());
111-
}
112-
113-
getStartupTime() {
114-
try {
115-
const [result, out] = GLib.spawn_command_line_sync("uptime -s");
116-
if (!result || !out) throw new Error("Could not get system startup time.");
117-
118-
this.startupValue.set_text(out.toString().split(" ")[1].trim());
119-
} catch (error) {
120-
this.startupValue.set_text("Error");
121-
global.logError(`${UUID}: ${error.message}`);
122-
}
123-
}
124-
125-
onSettingsChanged() {
126-
this.setupLayout();
127-
this.updateUptime();
128-
this.getStartupTime();
129-
}
130-
131-
on_desklet_removed() {
132-
if (this._timeout) Mainloop.source_remove(this._timeout);
21+
constructor(metadata, deskletId) {
22+
super(metadata, deskletId);
23+
24+
this.settings = new Settings.DeskletSettings(this, metadata["uuid"], deskletId);
25+
26+
// Bind settings properties
27+
this.settings.bindProperty(Settings.BindingDirection.IN, "fontSize", "fontSize", this.onSettingsChanged.bind(this));
28+
this.settings.bindProperty(Settings.BindingDirection.IN, "colorLabel", "colorLabel", this.onSettingsChanged.bind(this));
29+
this.settings.bindProperty(Settings.BindingDirection.IN, "showStartDate", "showStartDate", this.onSettingsChanged.bind(this));
30+
this.settings.bindProperty(Settings.BindingDirection.IN, "showUptimeInDays", "showUptimeInDays", this.onSettingsChanged.bind(this));
31+
32+
this.fontSize = this.settings.getValue("fontSize") || 20;
33+
this.colorLabel = this.settings.getValue("colorLabel") || "rgb(51, 209, 122)";
34+
this._timeout = null;
35+
36+
this.setHeader(_("System Uptime"));
37+
this.setupLayout();
38+
this.getStartupTime();
39+
this.updateUptime();
40+
}
41+
42+
setupLayout() {
43+
// Create labels for uptime
44+
this.uptimeLabel = this.createLabel(_("Uptime:") + " ", this.colorLabel);
45+
this.uptimeValue = this.createLabel(_("Loading..."));
46+
47+
const uptimeRow = this.createRow([this.uptimeLabel, this.uptimeValue]);
48+
49+
// Create labels for startup time
50+
this.startTimeLabel = this.createLabel(_("Start time:") + " ", this.colorLabel);
51+
this.startupValue = this.createLabel(_("Loading..."));
52+
53+
const startupRow = this.createRow([this.startTimeLabel, this.startupValue]);
54+
55+
// Combine all into the main container
56+
const contentBox = new St.BoxLayout({ vertical: true });
57+
contentBox.set_style("margin-left: 0.5em;");
58+
contentBox.add_child(startupRow);
59+
contentBox.add_child(uptimeRow);
60+
61+
this.container = new St.BoxLayout();
62+
this.container.add_child(contentBox);
63+
64+
Mainloop.idle_add(() => {
65+
let computedHeight = contentBox.get_height();
66+
67+
const clockIcon = this.getImageAtScale(`${this.metadata.path}/clock.svg`, computedHeight, computedHeight);
68+
69+
this.container.insert_child_below(clockIcon, contentBox);
70+
clockIcon.queue_relayout();
71+
72+
return false;
73+
});
74+
75+
this.setContent(this.container);
76+
}
77+
78+
createLabel(text, color = "inherit") {
79+
return new St.Label({
80+
text,
81+
y_align: St.Align.START,
82+
style: `font-size: ${this.fontSize}px; color: ${color};`,
83+
});
84+
}
85+
86+
createRow(children) {
87+
const row = new St.BoxLayout();
88+
children.forEach((child) => row.add_child(child));
89+
return row;
90+
}
91+
92+
updateUptime() {
93+
let uptimeInSeconds = 0;
94+
try {
95+
const [result, out] = GLib.spawn_command_line_sync("awk '{print $1}' /proc/uptime");
96+
if (!result || !out) throw new Error("Could not get system uptime.");
97+
uptimeInSeconds = parseFloat(out.toString().trim());
98+
99+
if (this.showUptimeInDays) {
100+
const days = Math.floor(uptimeInSeconds / 86400);
101+
const hours = Math.floor((uptimeInSeconds % 86400) / 3600);
102+
const minutes = Math.floor(((uptimeInSeconds % 86400) % 3600) / 60);
103+
104+
this.uptimeValue.set_text(`${days} ${_("days")} ${hours} ${_("hrs")} ${minutes} ${_("min")}`);
105+
} else {
106+
const hours = Math.floor(uptimeInSeconds / 3600);
107+
const minutes = Math.floor((uptimeInSeconds % 3600) / 60);
108+
109+
this.uptimeValue.set_text(`${hours} ${_("hours")} ${minutes} ${_("minutes")}`);
110+
}
111+
} catch (error) {
112+
this.uptimeValue.set_text("Error");
113+
global.logError(`${UUID}: ${error.message}`);
133114
}
134115

135-
getImageAtScale(imageFileName, width, height) {
136-
const pixBuf = GdkPixbuf.Pixbuf.new_from_file_at_size(imageFileName, width, height);
137-
const image = new Clutter.Image();
138-
image.set_data(
139-
pixBuf.get_pixels(),
140-
pixBuf.get_has_alpha() ? Cogl.PixelFormat.RGBA_8888 : Cogl.PixelFormat.RGBA_888,
141-
width, height,
142-
pixBuf.get_rowstride()
143-
);
144-
145-
const actor = new Clutter.Actor({ width, height });
146-
actor.set_content(image);
147-
return actor;
116+
if (this._timeout) Mainloop.source_remove(this._timeout);
117+
this._timeout = Mainloop.timeout_add_seconds(60, () => this.updateUptime());
118+
}
119+
120+
getStartupTime() {
121+
try {
122+
const [result, out] = GLib.spawn_command_line_sync("uptime -s");
123+
if (!result || !out) throw new Error("Could not get system startup time.");
124+
125+
const dateTime = out.toString().split(" ");
126+
const date = dateTime[0].split("-");
127+
128+
if (this.showStartDate) {
129+
this.startupValue.set_text(date[2] + "." + date[1] + "." + date[0] + ", " + dateTime[1].trim());
130+
} else {
131+
this.startupValue.set_text(dateTime[1].trim());
132+
}
133+
} catch (error) {
134+
this.startupValue.set_text("Error");
135+
global.logError(`${UUID}: ${error.message}`);
148136
}
137+
}
138+
139+
onSettingsChanged() {
140+
this.setupLayout();
141+
this.updateUptime();
142+
this.getStartupTime();
143+
}
144+
145+
on_desklet_removed() {
146+
if (this._timeout) Mainloop.source_remove(this._timeout);
147+
}
148+
149+
getImageAtScale(imageFileName, width, height) {
150+
const pixBuf = GdkPixbuf.Pixbuf.new_from_file_at_size(imageFileName, width, height);
151+
const image = new Clutter.Image();
152+
image.set_data(
153+
pixBuf.get_pixels(),
154+
pixBuf.get_has_alpha() ? Cogl.PixelFormat.RGBA_8888 : Cogl.PixelFormat.RGBA_888,
155+
width,
156+
height,
157+
pixBuf.get_rowstride()
158+
);
159+
160+
const actor = new Clutter.Actor({ width, height });
161+
actor.set_content(image);
162+
return actor;
163+
}
149164
}
150165

151166
function main(metadata, deskletId) {
152-
return new MyDesklet(metadata, deskletId);
167+
return new MyDesklet(metadata, deskletId);
153168
}
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
2-
"uuid": "systemUptime@KopfDesDaemons",
3-
"name": "System Uptime",
4-
"description": "Displays the current system uptime.",
5-
"version": "1.0",
6-
"max-instances": "50"
7-
}
2+
"uuid": "systemUptime@KopfDesDaemons",
3+
"name": "System Uptime",
4+
"description": "Displays the current system uptime.",
5+
"version": "1.0",
6+
"max-instances": "50",
7+
"author": "KopfdesDaemons"
8+
}

systemUptime@KopfDesDaemons/files/systemUptime@KopfDesDaemons/po/ca.po

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ msgstr ""
77
"Project-Id-Version: systemUptime@KopfDesDaemons 1.0\n"
88
"Report-Msgid-Bugs-To: https://github.com/linuxmint/cinnamon-spices-desklets/"
99
"issues\n"
10-
"POT-Creation-Date: 2024-12-18 21:26+0100\n"
10+
"POT-Creation-Date: 2025-07-31 22:57+0200\n"
1111
"PO-Revision-Date: \n"
1212
"Last-Translator: Dan <d3vf4n-linux (at) tutanota (dot) com>\n"
1313
"Language-Team: \n"
@@ -19,30 +19,42 @@ msgstr ""
1919
"X-Generator: Poedit 3.0.1\n"
2020

2121
#. metadata.json->name
22-
#. desklet.js:34
22+
#. desklet.js:61
2323
msgid "System Uptime"
2424
msgstr "Temps d'ús del sistema"
2525

26-
#. desklet.js:42
26+
#. desklet.js:69
2727
msgid "Uptime:"
2828
msgstr "Temps d'ús:"
2929

30-
#. desklet.js:43 desklet.js:49
30+
#. desklet.js:70 desklet.js:79
3131
msgid "Loading..."
3232
msgstr "S'està carregant..."
3333

34-
#. desklet.js:48
35-
msgid "System start time:"
36-
msgstr "Hora d'inici del sistema:"
34+
#. desklet.js:76
35+
msgid "Start time:"
36+
msgstr "Hora d'inici:"
3737

38-
#. desklet.js:91
39-
msgid "hours"
38+
#. desklet.js:139
39+
msgid "days"
40+
msgstr "dies"
41+
42+
#. desklet.js:139
43+
msgid "hrs"
4044
msgstr "hores"
4145

42-
#. desklet.js:91
43-
msgid "minutes"
46+
#. desklet.js:139
47+
msgid "min"
4448
msgstr "minuts"
4549

50+
#. desklet.js:146
51+
msgid "hours"
52+
msgstr ""
53+
54+
#. desklet.js:146
55+
msgid "minutes"
56+
msgstr ""
57+
4658
#. metadata.json->description
4759
msgid "Displays the current system uptime."
4860
msgstr "Mostra el temps de funcionament del sistema."
@@ -58,3 +70,12 @@ msgstr "Mida de la lletra"
5870
#. settings-schema.json->colorLabel->description
5971
msgid "Label color"
6072
msgstr "Color de les etiquetes"
73+
74+
#. settings-schema.json->showStartDate->description
75+
#, fuzzy
76+
msgid "Show start date"
77+
msgstr "Hora d'inici:"
78+
79+
#. settings-schema.json->showUptimeInDays->description
80+
msgid "Show uptime in days"
81+
msgstr ""

0 commit comments

Comments
 (0)