Created
January 24, 2025 20:20
-
-
Save WomB0ComB0/32491215a8f249dc71a6f584b53270d1 to your computer and use it in GitHub Desktop.
Create ICS files based on input
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @fileoverview Creates an ICS calendar file with recurring events based on provided configuration | |
*/ | |
import ical, { ICalEventRepeatingFreq, ICalWeekday } from 'ical-generator'; | |
import { writeFileSync } from 'fs'; | |
import { DateTime } from 'luxon'; | |
import yargs from 'yargs'; | |
import { hideBin } from 'yargs/helpers'; | |
import type { ICalRepeatingOptions } from 'ical-generator/dist/index.d.ts'; | |
/** | |
* Weekday constants for easier event scheduling | |
*/ | |
// @ts-ignore | |
const | |
monday = ICalWeekday.MO, | |
wednesday = ICalWeekday.WE, | |
saturday = ICalWeekday.SA, | |
sunday = ICalWeekday.SU, | |
tuesday = ICalWeekday.TU, | |
thursday = ICalWeekday.TH, | |
friday = ICalWeekday.FR; | |
/** | |
* Array of event configurations | |
* @type {Array<{ | |
* title: string, | |
* description: string, | |
* start: string, | |
* end: string, | |
* days: ICalWeekday[] | |
* }>} | |
*/ | |
const events: { title: string; description: string; start: string; end: string; days: ICalWeekday[] }[] = [ | |
{ | |
title: "LeetCode Practice", | |
description: "Daily coding practice session", | |
start: "19:00", | |
end: "20:00", | |
days: [sunday, tuesday, thursday, saturday] | |
} | |
]; | |
/** | |
* Main function that generates the ICS calendar file | |
* @async | |
* @returns {Promise<void>} Promise that resolves when the file is written | |
*/ | |
async function main(): Promise<void> { | |
// Parse command line arguments | |
const argv = await yargs(hideBin(process.argv)) | |
.option('repeat', { | |
alias: 'r', | |
type: 'boolean', | |
description: 'Whether the events should repeat', | |
default: true, | |
}) | |
.option('duration', { | |
alias: 'd', | |
type: 'number', | |
description: 'How long the events should repeat (in days)', | |
default: 90, | |
}) | |
.option('timezone', { | |
alias: 't', | |
type: 'string', | |
description: 'Timezone for the events', | |
default: 'America/New_York', | |
}) | |
.parseAsync(); | |
const timezone = argv.timezone; | |
const calendar = ical({ name: 'My Schedule', timezone }); | |
// Calculate start and end dates for events | |
const startDate = DateTime.now().setZone(timezone); | |
const endDate = argv.repeat ? startDate.plus({ days: argv.duration }) : startDate; | |
// Create calendar events | |
events.forEach(event => { | |
// Configure recurrence rule for repeating events | |
const recurrenceRule = { | |
freq: ICalEventRepeatingFreq.WEEKLY, | |
byDay: event.days.map(day => day), | |
until: endDate.toJSDate(), | |
} satisfies ICalRepeatingOptions; | |
// Calculate event start and end times | |
const startTime = DateTime.fromISO(`${startDate.toISODate()}T${event.start}:00`, { zone: timezone }); | |
const endTime = DateTime.fromISO(`${startDate.toISODate()}T${event.end}:00`, { zone: timezone }); | |
// Create the calendar event | |
calendar.createEvent({ | |
start: startTime.toJSDate(), | |
end: endTime.toJSDate(), | |
summary: event.title, | |
timezone: timezone, | |
repeating: recurrenceRule | |
}); | |
}); | |
// Write calendar to file | |
writeFileSync('schedule.ics', calendar.toString()); | |
console.log("ICS file generated successfully!"); | |
} | |
/** | |
* Entry point - only run main if this is the main module | |
*/ | |
if (require.main === module) { | |
main().catch(console.error); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment