CalMerger/src/calendarUtil.js

123 lines
5.2 KiB
JavaScript
Raw Normal View History

import ICAL from './lib/ical.timezones.js';
import fs from 'fs';
import path from 'path';
import axios from 'axios';
export const MERGED_CALENDARS_DIR = path.join(process.cwd(), 'calendar');
// Ensure the merged calendars directory exists
fs.mkdirSync(MERGED_CALENDARS_DIR, { recursive: true });
// Utility to sanitize filenames
export const sanitizeFilename = (filename) => filename.replace(/[<>:"/\\|?* ]/g, '_');
// Fetch calendar data from URL or file
export async function fetchCalendarData(calendar) {
const isFilePath = !calendar.url.startsWith('http');
try {
if (isFilePath) {
return { data: fs.readFileSync(path.resolve(calendar.url), 'utf-8'), ...calendar };
} else {
const response = await axios.get(calendar.url);
return { data: response.data, ...calendar };
}
} catch (error) {
throw new Error(`Error retrieving calendar from ${calendar.url}: ${error.message}`);
}
}
// Create a top-level VCALENDAR component
export function createCalendarComponent(name) {
const calendarComponent = new ICAL.Component(['vcalendar', [], []]);
calendarComponent.updatePropertyWithValue('name', name);
calendarComponent.updatePropertyWithValue('version', '2.0');
return calendarComponent;
}
// Add events to the calendar component
export function addEventsToCalendar(calendarComponent, results) {
results.forEach((result) => {
try {
const parsed = ICAL.parse(result.data);
const component = new ICAL.Component(parsed);
// Extract and add VTIMEZONE components
const timezones = component.getAllSubcomponents('vtimezone');
timezones.forEach((timezone) => {
const tzid = timezone.getFirstPropertyValue('tzid');
if (!calendarComponent.getFirstSubcomponent((comp) => comp.name === 'vtimezone' && comp.getFirstPropertyValue('tzid') === tzid)) {
calendarComponent.addSubcomponent(timezone);
}
});
console.log(`Added VTIMEZONE components for calendar: ${result.name}`);
// component.getAllSubcomponents('vevent').forEach((event) => {
// const vevent = new ICAL.Event(event);
// const newEvent = new ICAL.Component('vevent');
2024-11-13 02:54:42 +03:00
// // Use ICAL.Time to handle dates correctly
// const startDate = vevent.startDate;
// const endDate = vevent.endDate;
// // Create new ICAL.Time objects for start and end dates
// const startTime = new ICAL.Time({
// year: startDate.year,
// month: startDate.month,
// day: startDate.day,
// hour: startDate.isDate ? null : startDate.hour,
// minute: startDate.isDate ? null : startDate.minute,
// second: startDate.isDate ? null : startDate.second,
// zone: startDate.zone
// });
// startTime.isDate = startDate.isDate;
// const endTime = new ICAL.Time({
// year: endDate.year,
// month: endDate.month,
// day: endDate.day,
// hour: endDate.isDate ? null : endDate.hour,
// minute: endDate.isDate ? null : endDate.minute,
// second: endDate.isDate ? null : endDate.second,
// zone: endDate.zone
// });
// endTime.isDate = endDate.isDate;
2024-11-13 02:54:42 +03:00
// // Retain the existing DTSTAMP from vevent
// const dtstampProperty = event.getFirstProperty('dtstamp');
// const dtstamp = dtstampProperty ? dtstampProperty.getFirstValue() : null;
// // Add properties to the new event
// newEvent.updatePropertyWithValue('uid', vevent.uid);
// if (dtstamp) {
// newEvent.updatePropertyWithValue('dtstamp', dtstamp); // Retain the existing DTSTAMP
// } else {
// console.warn('DTSTAMP not found in the original event.'); // Warn if DTSTAMP is missing
// }
// // Set the dtstart and dtend properties using ICAL.Time
// newEvent.updatePropertyWithValue('dtstart', startTime);
// newEvent.updatePropertyWithValue('dtend', endTime);
// newEvent.updatePropertyWithValue('summary', vevent.summary.trim());
// // Add the new event to the calendar component
// calendarComponent.addSubcomponent(newEvent);
// });
// // Log the added events for debugging
// console.log('Added events:', calendarComponent.toString());
} catch (error) {
console.error('Error processing calendar data:', error.message);
}
});
}
// Save calendar data to file
export function saveCalendarFile(filename, content) {
const filePath = path.join(MERGED_CALENDARS_DIR, filename);
// console.log(`Saving calendar data to file: ${filePath}`);
fs.writeFileSync(filePath, content);
return filePath;
}