Skip to content

Commit

Permalink
display reocurring tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
geritwagner committed Jan 15, 2025
1 parent 5abc106 commit 1b02cb6
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 43 deletions.
117 changes: 75 additions & 42 deletions .github/workflows/generate_ical.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');
const { DateTime } = require('luxon'); // For timezone handling
const { DateTime } = require('luxon');
const { RRule } = require('rrule');

function parseDateTime(dateTimeString) {
// Parse "YYYY-MM-DD HH:MM" into Berlin timezone [YYYY, MM, DD, HH, MM]
Expand All @@ -21,36 +22,58 @@ function parseDateTime(dateTimeString) {
}

async function loadEvents() {
const yamlText = fs.readFileSync('docs/calendar/events.yaml', 'utf8');
const events = yaml.load(yamlText);
try {
const yamlText = fs.readFileSync('./docs/calendar/events.yaml', 'utf8'); // Read the YAML file
const events = yaml.load(yamlText);

if (!Array.isArray(events)) {
throw new Error('Parsed YAML is not an array');
}
if (!Array.isArray(events)) {
throw new Error("Parsed YAML is not an array");
}

return events
.map(event => {
const start = parseDateTime(event.start);
const end = parseDateTime(event.end);
const expandedEvents = [];
for (const event of events) {
const startDate = new Date(event.start);
const endDate = new Date(event.end);

if (!start || !end) {
console.warn(`Skipping event with invalid dates: ${JSON.stringify(event)}`);
return null; // Skip invalid events
}
if (event.recurrence) {
const rrule = new RRule({
...RRule.parseString(event.recurrence),
dtstart: startDate,
});

return {
start,
end,
title: event.title,
description: event.description || '',
location: event.location || '',
recurrence: event.recurrence || null, // Include recurrence if provided
};
})
.filter(event => event !== null); // Filter out invalid events
rrule.all().forEach(date => {
const end = new Date(date.getTime() + (endDate - startDate));
expandedEvents.push({
start: date.toISOString(),
end: end.toISOString(),
title: event.title,
color: event.color,
location: event.location,
description: event.description,
});
});
} else {
// Non-recurring event
expandedEvents.push({
start: event.start,
end: event.end,
title: event.title,
color: event.color,
location: event.location,
description: event.description,
});
}
}

console.log("Expanded events:", expandedEvents);
return expandedEvents;
} catch (error) {
console.error("Error fetching or parsing YAML:", error);
return [];
}
}


function generateICal(events) {
const vtimezone = `
BEGIN:VTIMEZONE
Expand All @@ -71,33 +94,43 @@ TZNAME:CEST
END:DAYLIGHT
END:VTIMEZONE`;

function parseDate(input) {
try {
if (typeof input === 'string' && input.includes('T')) {
return DateTime.fromISO(input);
} else if (typeof input === 'string') {
return DateTime.fromFormat(input, "yyyy-MM-dd HH:mm");
} else {
throw new Error("Invalid date format");
}
} catch (error) {
console.error("Error parsing date:", input, error);
return null;
}
}

const vevents = events
.map(event => {
const recurrenceRule = event.recurrence ? `RRULE:${event.recurrence}` : '';
const dtstart = parseDate(event.start);
const dtend = parseDate(event.end);

if (!dtstart || !dtend) {
console.error("Skipping event due to invalid dates:", event);
return null;
}

return `
BEGIN:VEVENT
UID:${Math.random().toString(36).substring(2, 15)}
SUMMARY:${event.title}
DTSTAMP:${DateTime.now().toUTC().toFormat("yyyyMMdd'T'HHmmss'Z'")}
DTSTART;TZID=Europe/Berlin:${DateTime.fromObject({
year: event.start[0],
month: event.start[1],
day: event.start[2],
hour: event.start[3],
minute: event.start[4],
}).toFormat("yyyyMMdd'T'HHmmss")}
DTEND;TZID=Europe/Berlin:${DateTime.fromObject({
year: event.end[0],
month: event.end[1],
day: event.end[2],
hour: event.end[3],
minute: event.end[4],
}).toFormat("yyyyMMdd'T'HHmmss")}
${recurrenceRule}
DESCRIPTION:${event.description}
LOCATION:${event.location}
DTSTART;TZID=Europe/Berlin:${dtstart.toFormat("yyyyMMdd'T'HHmmss")}
DTEND;TZID=Europe/Berlin:${dtend.toFormat("yyyyMMdd'T'HHmmss")}
DESCRIPTION:${event.description || ''}
LOCATION:${event.location || ''}
END:VEVENT`;
})
.filter(Boolean) // Remove null values
.join("\n");

return `BEGIN:VCALENDAR
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/update_calendar_ics.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
node-version: '16'

- name: Install dependencies
run: npm install js-yaml ics luxon
run: npm install js-yaml ics luxon rrule

- name: Generate iCal File
run: node .github/workflows/generate_ical.js
Expand Down
1 change: 1 addition & 0 deletions docs/02.calendar.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ nav_order: 3
<script src="https://cdn.jsdelivr.net/npm/@event-calendar/[email protected]/event-calendar.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/4.1.0/js-yaml.min.js"></script>
<script src="calendar/ics.js"></script>
<script src="https://cdn.jsdelivr.net/npm/rrule/dist/es5/rrule.min.js"></script>

# 02 Calendar

Expand Down

0 comments on commit 1b02cb6

Please sign in to comment.