diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..d41e493
Binary files /dev/null and b/.DS_Store differ
diff --git a/_index.js b/_index.js
new file mode 100644
index 0000000..3f592cf
--- /dev/null
+++ b/_index.js
@@ -0,0 +1,231 @@
+module.exports = function(RED) {
+ //require('https').globalAgent.options.ca = require('ssl-root-cas/latest').create();
+
+ let dav = require('dav')
+ let webdav = require('webdav')
+ const fs = require('fs')
+ const https = require('https');
+ const httpsAgent = new https.Agent({rejectUnauthorized: false});
+
+ function NextcloudConfigNode(n) {
+ RED.nodes.createNode(this, n)
+ this.address = n.address
+ }
+ RED.nodes.registerType('nextcloud-credentials', NextcloudConfigNode, {
+ credentials: {
+ user: {type: 'text'},
+ pass: {type: 'password'}
+ }
+ })
+
+ function NextcloudCalDav(n) {
+ RED.nodes.createNode(this, n)
+ this.server = RED.nodes.getNode(n.server)
+ this.calendar = n.calendar
+ let node = this
+
+ node.on('input', function(msg) {
+ const xhr = new dav.transport.Basic (
+ new dav.Credentials({
+ username: node.server.credentials.user,
+ password: node.server.credentials.pass
+ })
+ )
+ // Server + Basepath
+ let calDavUri = node.server.address + '/remote.php/dav/calendars/'
+ // User
+ calDavUri += node.server.credentials.user + '/'
+ dav.createAccount({ server: calDavUri, xhr: xhr })
+ .then(function(account) {
+ if (!account.calendars) {
+ node.error('Nextcloud:CalDAV -> no calendars found.')
+ return
+ }
+ // account instanceof dav.Account
+ account.calendars.forEach(function(calendar) {
+ // Wenn Kalender gesetzt ist, dann nur diesen abrufen
+ let c = msg.calendar || node.calendar
+ if (!c || !c.length || (c && c.length && c === calendar.displayName)) {
+ dav.listCalendarObjects(calendar, { xhr: xhr })
+ .then(function(calendarEntries) {
+ let icsList = {'payload': {'name': calendar.displayName, 'data': []}}
+ calendarEntries.forEach(function(calendarEntry) {
+ const keyValue = calendarEntry.calendarData.split('\n')
+ let icsJson = {}
+ for (let x = 0; x < keyValue.length; x++) {
+ const temp = keyValue[x].split(':')
+ icsJson[temp[0]] = temp[1]
+ }
+ icsList.payload.data.push(icsJson)
+ })
+ node.send(icsList)
+ }, function(){
+ node.error('Nextcloud:CalDAV -> get ics went wrong.')
+ })
+ }
+ })
+ }, function(){
+ node.error('Nextcloud:CalDAV -> get calendars went wrong.')
+ })
+ })
+ }
+ RED.nodes.registerType('nextcloud-caldav', NextcloudCalDav)
+
+
+ function NextcloudCardDav(n) {
+ RED.nodes.createNode(this, n)
+ this.server = RED.nodes.getNode(n.server)
+ this.addressBook = n.addressBook
+ let node = this
+
+ node.on('input', function(msg) {
+ const xhr = new dav.transport.Basic (
+ new dav.Credentials({
+ username: node.server.credentials.user,
+ password: node.server.credentials.pass
+ })
+ )
+
+ // Server + Basepath
+ let cardDavUri = node.server.address + '/remote.php/dav/addressbooks/users/'
+ // User
+ cardDavUri += node.server.credentials.user + '/'
+// ToDo Filter ?
+ dav.createAccount({ server: cardDavUri, xhr: xhr, accountType: 'carddav' })
+ .then(function(account) {
+ if (!account.addressBooks) {
+ node.error('Nextcloud:CardDAV -> no addressbooks found.')
+ return
+ }
+ // account instanceof dav.Account
+ account.addressBooks.forEach(function(addressBook) {
+ // Wenn Adressbuch gesetzt ist, dann nur diesen abrufen
+ let c = msg.addressBook || node.addressBook
+ if (!c || !c.length || (c && c.length && c === addressBook.displayName)) {
+ dav.listVCards(addressBook, { xhr: xhr })
+ .then(function(addressBookEntries) {
+ let vcfList = {'payload': {'name': addressBook.displayName, 'data': []}}
+ addressBookEntries.forEach(function(addressBookEntry) {
+ const keyValue = addressBookEntry.addressData.split('\n')
+ let vcfJson = {}
+ for (let x = 0; x < keyValue.length; x++) {
+ const temp = keyValue[x].split(':')
+ vcfJson[temp[0]] = temp[1]
+ }
+ vcfList.payload.data.push(vcfJson)
+ })
+ node.send(vcfList)
+ }, function(){
+ node.error('Nextcloud:CardDAV -> get cards went wrong.')
+ })
+ }
+ })
+ }, function(){
+ node.error('Nextcloud:CardDAV -> get addressBooks went wrong.')
+ })
+
+ })
+ }
+ RED.nodes.registerType('nextcloud-carddav', NextcloudCardDav)
+
+
+ function NextcloudWebDavList(n) {
+ RED.nodes.createNode(this, n)
+ this.server = RED.nodes.getNode(n.server)
+ this.directory = n.directory
+ let node = this
+
+ node.on('input', function(msg) {
+ const webDavUri = node.server.address + '/remote.php/webdav/'
+ const client = webdav(webDavUri, node.server.credentials.user, node.server.credentials.pass, httpsAgent)
+ let directory = ''
+ if (msg.directory) {
+ directory = '/' + msg.directory
+ } else if (node.directory && node.directory.length) {
+ directory = '/' + node.directory
+ }
+ directory = directory.replace('//', '/')
+
+ client.getDirectoryContents(directory)
+ .then(function (contents) {
+ node.send({'payload': contents})
+ }, function (error) {
+ node.error('Nextcloud:WebDAV -> get directory content went wrong.' + JSON.stringify(error))
+ })
+ })
+ }
+ RED.nodes.registerType('nextcloud-webdav-list', NextcloudWebDavList)
+
+
+ function NextcloudWebDavOut(n) {
+ RED.nodes.createNode(this, n)
+ this.server = RED.nodes.getNode(n.server)
+ this.filename = n.filename
+ let node = this
+
+ node.on('input', function(msg) {
+ const webDavUri = node.server.address + '/remote.php/webdav/'
+ const client = webdav(webDavUri, node.server.credentials.user, node.server.credentials.pass)
+ let filename = ''
+ if (msg.filename) {
+ filename = '/' + msg.filename
+ } else if (node.filename && node.filename.length) {
+ filename = '/' + node.filename
+ } else {
+ node.error('Nextcloud:WebDAV -> no filename specified.')
+ return
+ }
+ filename = filename.replace('//', '/')
+ node.warn(filename)
+ client.getFileContents(filename)
+ .then(function (contents) {
+ node.send({'payload': contents})
+ }, function (error) {
+ node.error('Nextcloud:WebDAV -> get file went wrong.' + JSON.stringify(error))
+ })
+ })
+ }
+ RED.nodes.registerType('nextcloud-webdav-out', NextcloudWebDavOut)
+
+
+ function NextcloudWebDavIn(n) {
+ RED.nodes.createNode(this, n)
+ this.server = RED.nodes.getNode(n.server)
+ this.directory = n.directory
+ this.filename = n.filename
+ let node = this
+
+ node.on('input', function(msg) {
+ // Read upload file
+ let filename = node.filename
+ if (msg.filename) {
+ filename = msg.filename
+ }
+ const name = filename.substr((filename.lastIndexOf('/') + 1), filename.length)
+ const file = fs.readFileSync(filename);
+ // Set upload directory
+ let directory = '/'
+ if (msg.directory) {
+ directory += msg.directory + '/'
+ } else if (node.directory && node.directory.length) {
+ directory += node.directory + '/'
+ }
+ directory = directory.replace('//', '/')
+
+
+ const webDavUri = node.server.address + '/remote.php/webdav/'
+ // https://nextcloud.jkoschke.me/remote.php/dav/files/jan/
+ const client = webdav(webDavUri, node.server.credentials.user, node.server.credentials.pass, httpsAgent);
+
+ client.putFileContents(directory + name, file, { format: 'binary' })
+ .then(function(contents) {
+ console.log(contents)
+ node.send({'payload': JSON.parse(contents)})
+ }, function(e) {
+ console.log(e);
+ node.error('Nextcloud:WebDAV -> send file went wrong.')
+ })
+ })
+ }
+ RED.nodes.registerType('nextcloud-webdav-in', NextcloudWebDavIn)
+}
diff --git a/nextcloud-cal.html b/nextcloud-cal.html
new file mode 100644
index 0000000..bd5b9bb
--- /dev/null
+++ b/nextcloud-cal.html
@@ -0,0 +1,72 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/nextcloud-cal.js b/nextcloud-cal.js
new file mode 100644
index 0000000..315d9ab
--- /dev/null
+++ b/nextcloud-cal.js
@@ -0,0 +1,115 @@
+module.exports = function(RED){
+ const dav = require('dav')
+ const IcalExpander = require('ical-expander')
+ const moment = require('moment')
+ const https = require('https')
+
+ function NextcloudCalDav (config) {
+ RED.nodes.createNode(this, config)
+ this.server = RED.nodes.getNode(config.server)
+ this.calendar = config.calendar
+ this.pastWeeks = config.pastWeeks || 0
+ this.futureWeeks = config.futureWeeks || 4
+ const node = this
+
+ node.on('input', (msg) => {
+ let startDate = moment().startOf('day').subtract(this.pastWeeks, 'weeks')
+ let endDate = moment().endOf('day').add(this.futureWeeks, 'weeks')
+ const filters = [{
+ type: 'comp-filter',
+ attrs: { name: 'VCALENDAR' },
+ children: [{
+ type: 'comp-filter',
+ attrs: { name: 'VEVENT' },
+ children: [{
+ type: 'time-range',
+ attrs: {
+ start: startDate.format('YYYYMMDD[T]HHmmss[Z]'),
+ end: endDate.format('YYYYMMDD[T]HHmmss[Z]')
+ }
+ }]
+ }]
+ }]
+ // dav.debug.enabled = true;
+ const xhr = new dav.transport.Basic(
+ new dav.Credentials({
+ username: node.server.credentials.user,
+ password: node.server.credentials.pass
+ })
+ )
+ // Server + Basepath
+ let calDavUri = node.server.address + '/remote.php/dav/calendars/'
+ // User
+ calDavUri += node.server.credentials.user + '/'
+ dav.createAccount({ server: calDavUri, xhr: xhr, loadCollections: true, loadObjects: true })
+ .then(function (account) {
+ if (!account.calendars) {
+ node.error('Nextcloud:CalDAV -> no calendars found.')
+ return
+ }
+ // account instanceof dav.Account
+ account.calendars.forEach(function (calendar) {
+ // Wenn Kalender gesetzt ist, dann nur diesen abrufen
+ let calName = msg.calendar || node.calendar
+ if (!calName || !calName.length || (calName && calName.length && calName === calendar.displayName)) {
+ dav.listCalendarObjects(calendar, { xhr: xhr, filters: filters })
+ .then(function (calendarEntries) {
+ let msg = { 'payload': { 'name': calendar.displayName, 'data': [] } }
+ calendarEntries.forEach(function (calendarEntry) {
+ try {
+ const ics = calendarEntry.calendarData
+ const icalExpander = new IcalExpander({ ics, maxIterations: 100 })
+ const events = icalExpander.between(startDate.toDate(), endDate.toDate())
+ msg.payload.data = msg.payload.data.concat(convertEvents(events))
+ } catch (error) {
+ node.error('Error parsing calendar data: ' + error)
+ }
+ })
+ node.send(msg)
+ }, function () {
+ node.error('Nextcloud:CalDAV -> get ics went wrong.')
+ })
+ }
+ })
+ }, function () {
+ node.error('Nextcloud:CalDAV -> get calendars went wrong.')
+ })
+ })
+
+ function convertEvents (events) {
+ const mappedEvents = events.events.map(_convertEvent)
+ const mappedOccurrences = events.occurrences.map(_convertEvent)
+ return [].concat(mappedEvents, mappedOccurrences)
+ }
+
+ function _convertEvent (e) {
+ if (e) {
+ let startDate = e.startDate.toString()
+ let endDate = e.endDate.toString()
+
+ if (e.item) {
+ e = e.item
+ }
+ if (e.duration.wrappedJSObject) {
+ delete e.duration.wrappedJSObject
+ }
+
+ return {
+ startDate: startDate,
+ endDate: endDate,
+ summary: e.summary || '',
+ description: e.description || '',
+ attendees: e.attendees,
+ duration: e.duration.toICALString(),
+ durationSeconds: e.duration.toSeconds(),
+ location: e.location || '',
+ organizer: e.organizer || '',
+ uid: e.uid || '',
+ isRecurring: false,
+ allDay: ((e.duration.toSeconds() % 86400) === 0)
+ }
+ }
+ }
+ }
+ RED.nodes.registerType('nextcloud-caldav', NextcloudCalDav)
+}
\ No newline at end of file
diff --git a/nextcloud-card.html b/nextcloud-card.html
new file mode 100644
index 0000000..578662a
--- /dev/null
+++ b/nextcloud-card.html
@@ -0,0 +1,62 @@
+
+
+
+
+
diff --git a/nextcloud-card.js b/nextcloud-card.js
new file mode 100644
index 0000000..e2b5cbe
--- /dev/null
+++ b/nextcloud-card.js
@@ -0,0 +1,60 @@
+module.exports = function(RED){
+
+ const dav = require('dav')
+ const https = require('https')
+
+ function NextcloudCardDav (config) {
+ RED.nodes.createNode(this, config)
+ this.server = RED.nodes.getNode(config.server)
+ this.addressBook = config.addressBook
+ const node = this
+
+ node.on('input', (msg) => {
+ const xhr = new dav.transport.Basic(
+ new dav.Credentials({
+ username: node.server.credentials.user,
+ password: node.server.credentials.pass
+ })
+ )
+
+ // Server + Basepath
+ let cardDavUri = node.server.address + '/remote.php/dav/addressbooks/users/'
+ // User
+ cardDavUri += node.server.credentials.user + '/'
+ // ToDo Filter ?
+ dav.createAccount({ server: cardDavUri, xhr: xhr, accountType: 'carddav' })
+ .then(function (account) {
+ if (!account.addressBooks) {
+ node.error('Nextcloud:CardDAV -> no addressbooks found.')
+ return
+ }
+ // account instanceof dav.Account
+ account.addressBooks.forEach(function (addressBook) {
+ // Wenn Adressbuch gesetzt ist, dann nur diesen abrufen
+ let c = msg.addressBook || node.addressBook
+ if (!c || !c.length || (c && c.length && c === addressBook.displayName)) {
+ dav.listVCards(addressBook, { xhr: xhr })
+ .then(function (addressBookEntries) {
+ let vcfList = { 'payload': { 'name': addressBook.displayName, 'data': [] } }
+ addressBookEntries.forEach(function (addressBookEntry) {
+ const keyValue = addressBookEntry.addressData.split('\n')
+ let vcfJson = {}
+ for (let x = 0; x < keyValue.length; x++) {
+ const temp = keyValue[x].split(':')
+ vcfJson[temp[0]] = temp[1]
+ }
+ vcfList.payload.data.push(vcfJson)
+ })
+ node.send(vcfList)
+ }, function () {
+ node.error('Nextcloud:CardDAV -> get cards went wrong.')
+ })
+ }
+ })
+ }, function () {
+ node.error('Nextcloud:CardDAV -> get addressBooks went wrong.')
+ })
+ })
+ }
+ RED.nodes.registerType('nextcloud-carddav', NextcloudCardDav)
+}
\ No newline at end of file
diff --git a/nextcloud-config.html b/nextcloud-config.html
new file mode 100644
index 0000000..e079edc
--- /dev/null
+++ b/nextcloud-config.html
@@ -0,0 +1,45 @@
+
+
+
diff --git a/nextcloud-config.js b/nextcloud-config.js
new file mode 100644
index 0000000..89c6bd3
--- /dev/null
+++ b/nextcloud-config.js
@@ -0,0 +1,13 @@
+module.exports = function (RED) {
+ function NextcloudConfigNode(n) {
+ RED.nodes.createNode(this, n)
+ this.address = n.address;
+ this.insecure = n.insecure;
+ }
+ RED.nodes.registerType('nextcloud-credentials', NextcloudConfigNode, {
+ credentials: {
+ user: { type: 'text' },
+ pass: { type: 'password' }
+ }
+ })
+}
diff --git a/nextcloud.html b/nextcloud.html
index 905c8fe..4a932b6 100644
--- a/nextcloud.html
+++ b/nextcloud.html
@@ -1,188 +1,3 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-