99 lines
2.8 KiB
QML
99 lines
2.8 KiB
QML
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs
|
|
pragma Singleton
|
|
|
|
// Read-only events already synchronized by Thunderbird. This deliberately does
|
|
// not connect to DAV or store credentials; Thunderbird remains the DAV client.
|
|
Singleton {
|
|
id: source
|
|
|
|
property var events: []
|
|
property int tick: 0
|
|
property string error: ""
|
|
property real updatedAt: 0
|
|
|
|
function refresh() {
|
|
if (reader.running)
|
|
return;
|
|
reader.command = ["python3", Quickshell.env("HOME") + "/.config/quickshell/thunderbird-calendar.py"];
|
|
reader.running = true;
|
|
}
|
|
|
|
function forDay(year, month, day) {
|
|
source.tick;
|
|
return source.events.filter((event) => {
|
|
const date = new Date(event.startMs);
|
|
return date.getFullYear() === year && date.getMonth() === month && date.getDate() === day;
|
|
});
|
|
}
|
|
|
|
function upcoming(limit) {
|
|
source.tick;
|
|
const now = Loc.nowMs();
|
|
return source.events.filter((event) => event.startMs >= now).slice(0, limit || source.events.length).map((event) => ({
|
|
"item": source.asAgendaItem(event),
|
|
"at": new Date(event.startMs)
|
|
}));
|
|
}
|
|
|
|
function hasOn(year, month, day) {
|
|
return source.forDay(year, month, day).length > 0;
|
|
}
|
|
|
|
function asAgendaItem(event) {
|
|
const date = new Date(event.startMs);
|
|
return {
|
|
"id": "thunderbird:" + event.id,
|
|
"name": event.name,
|
|
"calendar": event.calendar,
|
|
"source": "thunderbird",
|
|
"startMs": event.startMs,
|
|
"endMs": event.endMs,
|
|
"hour": date.getHours(),
|
|
"minute": date.getMinutes(),
|
|
"repeat": ""
|
|
};
|
|
}
|
|
|
|
Process {
|
|
id: reader
|
|
|
|
command: []
|
|
|
|
stdout: StdioCollector {
|
|
onStreamFinished: {
|
|
if (this.text.trim() === "")
|
|
return;
|
|
try {
|
|
const result = JSON.parse(this.text);
|
|
if (!result.error) {
|
|
source.events = result.events || [];
|
|
source.error = "";
|
|
source.updatedAt = Date.now();
|
|
source.tick++;
|
|
} else {
|
|
source.error = result.error;
|
|
}
|
|
} catch (e) {
|
|
source.error = "Could not read Thunderbird calendar cache";
|
|
}
|
|
}
|
|
}
|
|
|
|
onExited: (code) => {
|
|
if (code !== 0 && source.error === "")
|
|
source.error = "Could not read Thunderbird calendar cache";
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
interval: 300000
|
|
repeat: true
|
|
running: true
|
|
triggeredOnStart: true
|
|
onTriggered: source.refresh()
|
|
}
|
|
}
|