summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-01 17:27:18 +1100
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-01 17:27:18 +1100
commitff7324e7bfc1e01c8502e24a38e0729d87e63564 (patch)
tree3af12a838f191dad413c6ff7096dd83d9ee8daa5 /src
parentlauncher: hide todo action if tod not installed (diff)
downloadcaelestia-shell-ff7324e7bfc1e01c8502e24a38e0729d87e63564.tar.gz
caelestia-shell-ff7324e7bfc1e01c8502e24a38e0729d87e63564.tar.bz2
caelestia-shell-ff7324e7bfc1e01c8502e24a38e0729d87e63564.zip
calendar: cache calendars
Diffstat (limited to 'src')
-rw-r--r--src/services/calendar.ts35
-rw-r--r--src/utils/strings.ts10
-rw-r--r--src/utils/thumbnailer.ts5
3 files changed, 41 insertions, 9 deletions
diff --git a/src/services/calendar.ts b/src/services/calendar.ts
index 9743aad..9372066 100644
--- a/src/services/calendar.ts
+++ b/src/services/calendar.ts
@@ -1,5 +1,16 @@
+import { pathToFileName } from "@/utils/strings";
import { notify } from "@/utils/system";
-import { execAsync, GLib, GObject, property, register, timeout, type AstalIO } from "astal";
+import {
+ execAsync,
+ GLib,
+ GObject,
+ property,
+ readFileAsync,
+ register,
+ timeout,
+ writeFileAsync,
+ type AstalIO,
+} from "astal";
import { calendar as config } from "config";
import ical from "ical.js";
@@ -17,6 +28,8 @@ export default class Calendar extends GObject.Object {
return this.instance;
}
+ readonly #cacheDir = `${CACHE}/calendars`;
+
#calCount: number = 1;
#reminders: AstalIO.Time[] = [];
#loading: boolean = false;
@@ -55,12 +68,24 @@ export default class Calendar extends GObject.Object {
this.#calCount = 1;
const cals = await Promise.allSettled(config.webcals.get().map(c => execAsync(["curl", c])));
- for (const cal of cals) {
+ for (let i = 0; i < cals.length; i++) {
+ const cal = cals[i];
+ const webcal = pathToFileName(config.webcals.get()[i]);
+
+ let icalStr;
if (cal.status === "fulfilled") {
- const comp = new ical.Component(ical.parse(cal.value));
+ icalStr = cal.value;
+ } else {
+ console.error(`Failed to get calendar from ${config.webcals.get()[i]}:\n${cal.reason}`);
+ icalStr = await readFileAsync(`${this.#cacheDir}/${webcal}`);
+ }
+
+ if (icalStr) {
+ const comp = new ical.Component(ical.parse(icalStr));
const name = (comp.getFirstPropertyValue("x-wr-calname") ?? `Calendar ${this.#calCount++}`) as string;
this.#calendars[name] = comp;
- } else console.error(`Failed to get calendar: ${cal.reason}`);
+ writeFileAsync(`${this.#cacheDir}/${webcal}`, icalStr).catch(console.error);
+ }
}
this.notify("calendars");
@@ -160,6 +185,8 @@ export default class Calendar extends GObject.Object {
constructor() {
super();
+ GLib.mkdir_with_parents(this.#cacheDir, 0o755);
+
this.updateCalendars().catch(console.error);
config.webcals.subscribe(() => this.updateCalendars().catch(console.error));
config.upcomingDays.subscribe(() => this.updateUpcoming());
diff --git a/src/utils/strings.ts b/src/utils/strings.ts
index c2bf71a..4aaa916 100644
--- a/src/utils/strings.ts
+++ b/src/utils/strings.ts
@@ -1,7 +1,13 @@
export const ellipsize = (str: string, len: number) => (str.length > len ? `${str.slice(0, len - 1)}…` : str);
-export const basename = (path: string) => {
+export const basename = (path: string, stripExt = true) => {
const lastSlash = path.lastIndexOf("/");
const lastDot = path.lastIndexOf(".");
- return path.slice(lastSlash + 1, lastDot > lastSlash ? lastDot : undefined);
+ return path.slice(lastSlash + 1, stripExt && lastDot > lastSlash ? lastDot : undefined);
+};
+
+export const pathToFileName = (path: string, ext?: string) => {
+ const start = /[a-z]+:\/\//.test(path) ? 0 : path.indexOf("/") + 1;
+ const dir = path.slice(start, path.lastIndexOf("/")).replaceAll("/", "-");
+ return `${dir}-${basename(path, ext !== undefined)}${ext ? `.${ext}` : ""}`;
};
diff --git a/src/utils/thumbnailer.ts b/src/utils/thumbnailer.ts
index 7551870..caa3bbb 100644
--- a/src/utils/thumbnailer.ts
+++ b/src/utils/thumbnailer.ts
@@ -1,5 +1,5 @@
import { execAsync, Gio, GLib } from "astal";
-import { basename } from "./strings";
+import { pathToFileName } from "./strings";
export default class Thumbnailer {
static readonly thumbnailDir = `${CACHE}/thumbnails`;
@@ -13,8 +13,7 @@ export default class Thumbnailer {
static readonly #running = new Set<string>();
static getThumbPath(path: string) {
- const dir = path.slice(path.indexOf("/") + 1, path.lastIndexOf("/")).replaceAll("/", "-");
- return `${this.thumbnailDir}/${dir}-${basename(path)}.png`;
+ return `${this.thumbnailDir}/${pathToFileName(path, "png")}`;
}
static async shouldThumbnail(path: string) {