You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
121 lines
2.7 KiB
121 lines
2.7 KiB
/**
|
|
* InfoFetcher module
|
|
*
|
|
* @author Deminder <tremminder@gmail.com>
|
|
* @copyright 2021
|
|
* @license GNU General Public License v3.0
|
|
*/
|
|
/* exported InfoFetcher */
|
|
|
|
const { Gio, GLib } = imports.gi;
|
|
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
|
const { Convenience } = Me.imports.lib;
|
|
const { logDebug, throttleTimeout } = Convenience;
|
|
const ByteArray = imports.byteArray;
|
|
|
|
/**
|
|
*
|
|
* @param path
|
|
*/
|
|
function readFile(path) {
|
|
return new Promise((resolve, reject) => {
|
|
try {
|
|
const file = Gio.File.new_for_path(path);
|
|
file.load_contents_async(null, (f, res) => {
|
|
try {
|
|
const [, contents] = f.load_contents_finish(res);
|
|
resolve(ByteArray.toString(contents));
|
|
GLib.free(contents);
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
});
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
async function isWakeInfoLocal() {
|
|
const content = await readFile('/etc/adjtime').catch(() => '');
|
|
return content.trim().toLowerCase().endsWith('local');
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param rtc
|
|
*/
|
|
async function wakeInfo(rtc) {
|
|
const content = await readFile(`/sys/class/rtc/${rtc}/wakealarm`).catch(
|
|
() => ''
|
|
);
|
|
let timestamp = content !== '' ? parseInt(content) : -1;
|
|
if (timestamp > -1 && (await isWakeInfoLocal())) {
|
|
const dt = GLib.DateTime.new_from_unix_local(timestamp);
|
|
timestamp = dt.to_unix() - dt.get_utc_offset() / 1000000;
|
|
dt.unref();
|
|
}
|
|
return { deadline: timestamp };
|
|
}
|
|
|
|
/**
|
|
*
|
|
*/
|
|
async function shutdownInfo() {
|
|
try {
|
|
const content = await readFile('/run/systemd/shutdown/scheduled');
|
|
// content: schedule unix-timestamp (micro-seconds), warn-all, shutdown-mode
|
|
const [usec, _, mode] = content.split('\n').map(l => l.split('=')[1]);
|
|
return {
|
|
mode,
|
|
deadline: parseInt(usec) / 1000000,
|
|
};
|
|
} catch {
|
|
return { deadline: -1 };
|
|
}
|
|
}
|
|
|
|
var InfoFetcher = class {
|
|
constructor(onFetch) {
|
|
this._infoTimerId = null;
|
|
this._pending = false;
|
|
this._rtc = 'rtc0';
|
|
this._onFetch = onFetch;
|
|
[this.refresh, this._cancelRefresh] = throttleTimeout(
|
|
this._refresh.bind(this),
|
|
300
|
|
);
|
|
this.refresh();
|
|
}
|
|
|
|
_refresh() {
|
|
logDebug('Extra info refresh...');
|
|
this.stop();
|
|
// restart loop
|
|
this._infoTimerId = setInterval(this.tick.bind(this), 5000);
|
|
this.tick();
|
|
}
|
|
|
|
stop() {
|
|
if (this._infoTimerId !== null) {
|
|
clearInterval(this._infoTimerId);
|
|
}
|
|
this._cancelRefresh();
|
|
}
|
|
|
|
tick() {
|
|
if (!this._pending) {
|
|
this._pending = true;
|
|
Promise.all([shutdownInfo(), wakeInfo(this._rtc)]).then(
|
|
([schedule, wake]) => {
|
|
this._onFetch(schedule, wake);
|
|
this._pending = false;
|
|
}
|
|
);
|
|
}
|
|
}
|
|
};
|