use ical-expander to get events and repeating occurences

add option to enable global saving of calendar entrie
This commit is contained in:
basti76
2018-09-19 20:34:36 +02:00
parent 64c8e6e763
commit 644ad15241
2 changed files with 48 additions and 29 deletions

View File

@ -2,7 +2,7 @@ module.exports = function (RED) {
const dav = require('dav') const dav = require('dav')
const webdav = require('webdav') const webdav = require('webdav')
const fs = require('fs') const fs = require('fs')
const ICAL = require('ical.js') const IcalExpander = require('ical-expander')
const moment = require('moment') const moment = require('moment')
function NextcloudConfigNode (config) { function NextcloudConfigNode (config) {
@ -22,13 +22,15 @@ module.exports = function (RED) {
this.calendar = config.calendar this.calendar = config.calendar
this.pastWeeks = config.pastWeeks || 0 this.pastWeeks = config.pastWeeks || 0
this.futureWeeks = config.futureWeeks || 4 this.futureWeeks = config.futureWeeks || 4
this.saveData = config.saveData || true
this.savedCalendars = {}
const node = this const node = this
node.warn('Node init') node.warn('Node init')
node.on('input', (msg) => { node.on('input', (msg) => {
let savedCalendars = this.context().global.get('owncloud/calendars') || {} if (this.saveData) this.savedCalendars = this.context().global.get('nextcloud/calendars') || {}
let startDate = moment().startOf('day').subtract(this.pastWeeks, 'weeks').format('YYYYMMDD[T]HHmmss[Z]') let startDate = moment().startOf('day').subtract(this.pastWeeks, 'weeks')
let endDate = moment().startOf('day').add(this.futureWeeks, 'weeks').format('YYYYMMDD[T]HHmmss[Z]') let endDate = moment().endOf('day').add(this.futureWeeks, 'weeks')
const filters = [{ const filters = [{
type: 'comp-filter', type: 'comp-filter',
attrs: { name: 'VCALENDAR' }, attrs: { name: 'VCALENDAR' },
@ -38,8 +40,8 @@ module.exports = function (RED) {
children: [{ children: [{
type: 'time-range', type: 'time-range',
attrs: { attrs: {
start: startDate, start: startDate.format('YYYYMMDD[T]HHmmss[Z]'),
end: endDate end: endDate.format('YYYYMMDD[T]HHmmss[Z]')
} }
}] }]
}] }]
@ -68,21 +70,22 @@ module.exports = function (RED) {
if (!calName || !calName.length || (calName && calName.length && calName === calendar.displayName)) { if (!calName || !calName.length || (calName && calName.length && calName === calendar.displayName)) {
dav.listCalendarObjects(calendar, { xhr: xhr, filters: filters }) dav.listCalendarObjects(calendar, { xhr: xhr, filters: filters })
.then(function (calendarEntries) { .then(function (calendarEntries) {
let icsList = { 'payload': { 'name': calendar.displayName, 'data': [] } } let msg = { 'payload': { 'name': calendar.displayName, 'data': [] } }
calendarEntries.forEach(function (calendarEntry) { calendarEntries.forEach(function (calendarEntry) {
try { try {
let jCalData = ICAL.parse(calendarEntry.calendarData) const ics = calendarEntry.calendarData
let component = new ICAL.Component(jCalData) const icalExpander = new IcalExpander({ ics, maxIterations: 100 })
let vevent = component.getFirstSubcomponent('vevent') const events = icalExpander.between(startDate.toDate(), endDate.toDate())
var event = new ICAL.Event(vevent) msg.payload.data = msg.payload.data.concat(convertEvents(events))
icsList.payload.data.push(convertEvent(event))
} catch (error) { } catch (error) {
node.error('Error parsing calendar data: ' + error) node.error('Error parsing calendar data: ' + error)
} }
}) })
savedCalendars[calendar.displayName] = icsList.payload.data if (this.saveData) {
node.context().global.set('owncloud/calendars', savedCalendars) this.savedCalendars[calendar.displayName] = msg.payload.data
node.send(icsList) node.context().global.set('nextcloud/calendars', this.savedCalendars)
}
node.send(msg)
}, function () { }, function () {
node.error('Nextcloud:CalDAV -> get ics went wrong.') node.error('Nextcloud:CalDAV -> get ics went wrong.')
}) })
@ -93,19 +96,35 @@ module.exports = function (RED) {
}) })
}) })
function convertEvent (event) { function convertEvents (events) {
const retVal = {} // node.warn(events)
retVal.start = event.startDate.toString() const mappedEvents = events.events.map(e => ({
retVal.end = event.endDate.toString() startDate: e.startDate.toString(),
retVal.summary = event.summary || '' endDate: e.endDate.toString(),
retVal.description = event.description || '' summary: e.summary || '',
retVal.attendees = event.attendees description: e.description || '',
retVal.duration = event.duration attendees: e.attendees,
retVal.location = event.location || '' duration: e.duration,
retVal.organizer = event.organizer || '' location: e.location || '',
retVal.uid = event.uid || '' organizer: e.organizer || '',
retVal.isRecurring = event.isRecurring() uid: e.uid || '',
return retVal isRecurring: false,
allDay: (e.duration.toSeconds() === 86400)
}))
const mappedOccurrences = events.occurrences.map(o => ({
startDate: o.startDate.toString(),
endDate: o.endDate.toString(),
summary: o.item.summary || '',
description: o.item.description || '',
attendees: o.item.attendees,
duration: o.item.duration,
location: o.item.location || '',
organizer: o.item.organizer || '',
uid: o.item.uid || '',
isRecurring: true,
allDay: (o.item.duration.toSeconds() === 86400)
}))
return [].concat(mappedEvents, mappedOccurrences)
} }
} }
RED.nodes.registerType('nextcloud-caldav', NextcloudCalDav) RED.nodes.registerType('nextcloud-caldav', NextcloudCalDav)

View File

@ -18,7 +18,7 @@
], ],
"dependencies": { "dependencies": {
"dav": "^1.8.0", "dav": "^1.8.0",
"ical.js": "^1.2.2", "ical-expander": "^2.0.0",
"moment": "^2.22.2", "moment": "^2.22.2",
"webdav": "^1.5.2" "webdav": "^1.5.2"
}, },