use ical-expander to get events and repeating occurences
add option to enable global saving of calendar entrie
This commit is contained in:
75
nextcloud.js
75
nextcloud.js
@ -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)
|
||||||
|
|||||||
@ -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"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user