calendar: cache calendars
This commit is contained in:
parent
8d3cf6b6a3
commit
ff7324e7bf
3 changed files with 41 additions and 9 deletions
|
|
@ -1,5 +1,16 @@
|
||||||
|
import { pathToFileName } from "@/utils/strings";
|
||||||
import { notify } from "@/utils/system";
|
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 { calendar as config } from "config";
|
||||||
import ical from "ical.js";
|
import ical from "ical.js";
|
||||||
|
|
||||||
|
|
@ -17,6 +28,8 @@ export default class Calendar extends GObject.Object {
|
||||||
return this.instance;
|
return this.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly #cacheDir = `${CACHE}/calendars`;
|
||||||
|
|
||||||
#calCount: number = 1;
|
#calCount: number = 1;
|
||||||
#reminders: AstalIO.Time[] = [];
|
#reminders: AstalIO.Time[] = [];
|
||||||
#loading: boolean = false;
|
#loading: boolean = false;
|
||||||
|
|
@ -55,12 +68,24 @@ export default class Calendar extends GObject.Object {
|
||||||
this.#calCount = 1;
|
this.#calCount = 1;
|
||||||
|
|
||||||
const cals = await Promise.allSettled(config.webcals.get().map(c => execAsync(["curl", c])));
|
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") {
|
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;
|
const name = (comp.getFirstPropertyValue("x-wr-calname") ?? `Calendar ${this.#calCount++}`) as string;
|
||||||
this.#calendars[name] = comp;
|
this.#calendars[name] = comp;
|
||||||
} else console.error(`Failed to get calendar: ${cal.reason}`);
|
writeFileAsync(`${this.#cacheDir}/${webcal}`, icalStr).catch(console.error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.notify("calendars");
|
this.notify("calendars");
|
||||||
|
|
||||||
|
|
@ -160,6 +185,8 @@ export default class Calendar extends GObject.Object {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
GLib.mkdir_with_parents(this.#cacheDir, 0o755);
|
||||||
|
|
||||||
this.updateCalendars().catch(console.error);
|
this.updateCalendars().catch(console.error);
|
||||||
config.webcals.subscribe(() => this.updateCalendars().catch(console.error));
|
config.webcals.subscribe(() => this.updateCalendars().catch(console.error));
|
||||||
config.upcomingDays.subscribe(() => this.updateUpcoming());
|
config.upcomingDays.subscribe(() => this.updateUpcoming());
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
export const ellipsize = (str: string, len: number) => (str.length > len ? `${str.slice(0, len - 1)}…` : str);
|
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 lastSlash = path.lastIndexOf("/");
|
||||||
const lastDot = 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}` : ""}`;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { execAsync, Gio, GLib } from "astal";
|
import { execAsync, Gio, GLib } from "astal";
|
||||||
import { basename } from "./strings";
|
import { pathToFileName } from "./strings";
|
||||||
|
|
||||||
export default class Thumbnailer {
|
export default class Thumbnailer {
|
||||||
static readonly thumbnailDir = `${CACHE}/thumbnails`;
|
static readonly thumbnailDir = `${CACHE}/thumbnails`;
|
||||||
|
|
@ -13,8 +13,7 @@ export default class Thumbnailer {
|
||||||
static readonly #running = new Set<string>();
|
static readonly #running = new Set<string>();
|
||||||
|
|
||||||
static getThumbPath(path: string) {
|
static getThumbPath(path: string) {
|
||||||
const dir = path.slice(path.indexOf("/") + 1, path.lastIndexOf("/")).replaceAll("/", "-");
|
return `${this.thumbnailDir}/${pathToFileName(path, "png")}`;
|
||||||
return `${this.thumbnailDir}/${dir}-${basename(path)}.png`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async shouldThumbnail(path: string) {
|
static async shouldThumbnail(path: string) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue