forked from GitHubMirrors/silverbullet-icalendar
conductor(checkpoint): Checkpoint end of Phase 4: Cleanup & Configuration
This commit is contained in:
15
icalendar.ts
15
icalendar.ts
@@ -74,12 +74,13 @@ function convertDatesToStrings<T>(obj: T): any {
|
|||||||
// Configuration Functions
|
// Configuration Functions
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
async function getSources(): Promise<any[]> {
|
async function getSources(): Promise<{ sources: any[], syncWindowDays: number }> {
|
||||||
try {
|
try {
|
||||||
const rawConfig = await config.get("icalendar", { sources: [] }) as any;
|
const rawConfig = await config.get("icalendar", { sources: [] }) as any;
|
||||||
console.log("[iCalendar] Raw config retrieved:", JSON.stringify(rawConfig));
|
console.log("[iCalendar] Raw config retrieved:", JSON.stringify(rawConfig));
|
||||||
|
|
||||||
let sources = rawConfig.sources || [];
|
let sources = rawConfig.sources || [];
|
||||||
|
const syncWindowDays = rawConfig.syncWindowDays || 365;
|
||||||
|
|
||||||
if (sources && typeof sources === "object" && !Array.isArray(sources)) {
|
if (sources && typeof sources === "object" && !Array.isArray(sources)) {
|
||||||
const sourceArray = [];
|
const sourceArray = [];
|
||||||
@@ -91,10 +92,10 @@ async function getSources(): Promise<any[]> {
|
|||||||
sources = sourceArray;
|
sources = sourceArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sources;
|
return { sources, syncWindowDays };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("[iCalendar] Error in getSources:", e);
|
console.error("[iCalendar] Error in getSources:", e);
|
||||||
return [];
|
return { sources: [], syncWindowDays: 365 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +197,7 @@ export function expandRecurrences(icsEvent: any, windowDays = 365): any[] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchAndParseCalendar(source: any): Promise<any[]> {
|
async function fetchAndParseCalendar(source: any, windowDays = 365): Promise<any[]> {
|
||||||
console.log(`[iCalendar] Fetching from: ${source.url}`);
|
console.log(`[iCalendar] Fetching from: ${source.url}`);
|
||||||
try {
|
try {
|
||||||
const response = await fetch(source.url);
|
const response = await fetch(source.url);
|
||||||
@@ -231,7 +232,7 @@ async function fetchAndParseCalendar(source: any): Promise<any[]> {
|
|||||||
baseEvent.description = `(Warning: Unknown timezone "${rawTz}") ${baseEvent.description || ""}`;
|
baseEvent.description = `(Warning: Unknown timezone "${rawTz}") ${baseEvent.description || ""}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const expanded = expandRecurrences(baseEvent);
|
const expanded = expandRecurrences(baseEvent, windowDays);
|
||||||
for (const occurrence of expanded) {
|
for (const occurrence of expanded) {
|
||||||
const uniqueKey = `${occurrence.start}${occurrence.uid || occurrence.summary || ''}`;
|
const uniqueKey = `${occurrence.start}${occurrence.uid || occurrence.summary || ''}`;
|
||||||
occurrence.ref = await sha256Hash(uniqueKey);
|
occurrence.ref = await sha256Hash(uniqueKey);
|
||||||
@@ -247,13 +248,13 @@ async function fetchAndParseCalendar(source: any): Promise<any[]> {
|
|||||||
|
|
||||||
export async function syncCalendars() {
|
export async function syncCalendars() {
|
||||||
try {
|
try {
|
||||||
const sources = await getSources();
|
const { sources, syncWindowDays } = await getSources();
|
||||||
if (sources.length === 0) return;
|
if (sources.length === 0) return;
|
||||||
|
|
||||||
await editor.flashNotification("Syncing calendars...", "info");
|
await editor.flashNotification("Syncing calendars...", "info");
|
||||||
const allEvents: any[] = [];
|
const allEvents: any[] = [];
|
||||||
for (const source of sources) {
|
for (const source of sources) {
|
||||||
const events = await fetchAndParseCalendar(source);
|
const events = await fetchAndParseCalendar(source, syncWindowDays);
|
||||||
allEvents.push(...events);
|
allEvents.push(...events);
|
||||||
}
|
}
|
||||||
await index.indexObjects("$icalendar", allEvents);
|
await index.indexObjects("$icalendar", allEvents);
|
||||||
|
|||||||
@@ -76,6 +76,32 @@ Deno.test("expandRecurrences - EXDATE exclusion", () => {
|
|||||||
|
|
||||||
Deno.test("fetchAndParseCalendar - filter cancelled events", async () => {
|
Deno.test("fetchAndParseCalendar - filter cancelled events", async () => {
|
||||||
// This requires mocking fetch or testing the inner loop logic.
|
// This requires mocking fetch or testing the inner loop logic.
|
||||||
// For now, let's just test that we skip them if we had a list of events.
|
});
|
||||||
// Since fetchAndParseCalendar is async and uses syscalls, we'll verify the logic in the code.
|
|
||||||
|
Deno.test("resolveEventStart - ignore tzShift", async () => {
|
||||||
|
const icsEvent = {
|
||||||
|
summary: "Ignore tzShift",
|
||||||
|
start: {
|
||||||
|
date: "2025-01-15T12:00:00.000",
|
||||||
|
local: {
|
||||||
|
date: "2025-01-15T07:00:00.000",
|
||||||
|
timezone: "Eastern Standard Time"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await resolveEventStart(icsEvent);
|
||||||
|
assertEquals(result?.toISOString(), "2025-01-15T12:00:00.000Z");
|
||||||
|
});
|
||||||
|
|
||||||
|
Deno.test("expandRecurrences - custom windowDays", () => {
|
||||||
|
const icsEvent = {
|
||||||
|
summary: "Daily Meeting",
|
||||||
|
start: "2025-01-01T10:00:00",
|
||||||
|
rrule: "FREQ=DAILY"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 7 days window (Jan 1 to Jan 8) should give 8 occurrences if inclusive
|
||||||
|
const results = expandRecurrences(icsEvent, 7);
|
||||||
|
assertEquals(results.length, 8);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user