Files
olympics-calendar/src/ics.ts
Fabrice Lamant b6bf9ad1c1 add medals table
2024-08-04 12:03:19 +02:00

61 lines
1.8 KiB
TypeScript

import * as fs from "node:fs";
import Debug from "debug";
import { Event } from "./types";
const debug = Debug("paris2024:ics");
/**
* generateICS generates the calendar for given events on ICS format
* @param {string} title
* @param {string} key
* @param {object[]} events
*/
export const generateICS = (title: string, key: string, events: Event[]): void => {
// debug(`Generating ICS file for ${title} (${key}) with ${events.length} events`);
const lines: string[] = [];
lines.push("BEGIN:VCALENDAR");
lines.push("VERSION:2.0");
lines.push(`PRODID:-//fabrice404//olympics-calendar//${key}//EN`);
lines.push(`X-WR-CALNAME:${title}`);
lines.push(`NAME:${title}`);
events.forEach((event) => {
lines.push("BEGIN:VEVENT");
lines.push(
...Object.entries(event)
.filter(([key]) => !key.startsWith("_"))
.map(([key, value]) => {
let result = `${key}:${value}`;
if (result.length > 75) {
if (key === "DESCRIPTION") {
const lines = [];
while (result.length > 75) {
let index = 75;
while (result[index] !== " " && index > 0) {
index--;
}
lines.push(result.slice(0, index));
result = " " + result.slice(index).trim();
}
lines.push(result);
return lines.join("\r\n").trim();
}
return `${key}:${value}`.slice(0, 75);
}
return `${key}:${value}`;
}),
);
lines.push("END:VEVENT");
});
lines.push("END:VCALENDAR");
const calendarPath = `${__dirname}/../docs/${key}.ics`;
const folder = calendarPath.split("/").slice(0, -1).join("/");
fs.mkdirSync(folder, { recursive: true });
fs.writeFileSync(calendarPath, lines.join("\r\n"));
};