Skip to content

Commit

Permalink
Merge d0f9ce9 into 76c0b64
Browse files Browse the repository at this point in the history
  • Loading branch information
georgehrke committed Sep 21, 2016
2 parents 76c0b64 + d0f9ce9 commit c79d2a6
Show file tree
Hide file tree
Showing 10 changed files with 392 additions and 250 deletions.
87 changes: 87 additions & 0 deletions js/app/service/davClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Calendar App
*
* @author Raghu Nayyar
* @author Georg Ehrke
* @copyright 2016 Raghu Nayyar <beingminimal@gmail.com>
* @copyright 2016 Georg Ehrke <oc.list@georgehrke.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/

app.service('DavClient', function($window) {
'use strict';

const client = new dav.Client({
baseUrl: OC.linkToRemote('dav/calendars'),
xmlNamespaces: {
'DAV:': 'd',
'urn:ietf:params:xml:ns:caldav': 'c',
'http://apple.com/ns/ical/': 'aapl',
'http://owncloud.org/ns': 'oc',
'http://nextcloud.com/ns': 'nc',
'http://calendarserver.org/ns/': 'cs'
}
});

client.NS_DAV = 'DAV:';
client.NS_IETF = 'urn:ietf:params:xml:ns:caldav';
client.NS_APPLE = 'http://apple.com/ns/ical/';
client.NS_OWNCLOUD = 'http://owncloud.org/ns';
client.NS_NEXTCLOUD = 'http://nextcloud.com/ns';
client.NS_CALENDARSERVER = 'http://calendarserver.org/ns/';

/**
* get absolute url for path
* @param {string} path
* @returns {string}
*/
client.buildUrl = function(path) {
if (path.substr(0,1) !== '/') {
path = '/' + path;
}

return $window.location.origin + path;
};

/**
* get a nodes full name including its namespace
* @param {Node} node
* @returns {string}
*/
client.getNodesFullName = function(node) {
return '{' + node.namespaceURI + '}' + node.localName;
};

/**
* get response code from http response
* @param {string} t
* @returns {Number}
*/
client.getResponseCodeFromHTTPResponse = function(t) {
return parseInt(t.split(' ')[1]);
};

/**
* check if request was successful
* @param {Number} status
* @returns {boolean}
*/
client.wasRequestSuccessful = function(status) {
return (status >= 200 && status <= 299);
};

return client;
});
60 changes: 0 additions & 60 deletions js/app/service/davclient.js

This file was deleted.

223 changes: 223 additions & 0 deletions js/app/service/veventService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
/**
* Calendar App
*
* @author Raghu Nayyar
* @author Georg Ehrke
* @copyright 2016 Raghu Nayyar <beingminimal@gmail.com>
* @copyright 2016 Georg Ehrke <oc.list@georgehrke.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/

app.service('VEventService', function(DavClient, StringUtility, XMLUtility, VEvent) {
'use strict';

const context = {
calendarDataPropName: '{' + DavClient.NS_IETF + '}calendar-data',
eTagPropName: '{' + DavClient.NS_DAV + '}getetag',
self: this
};

/**
* get url for event
* @param {VEvent} event
* @returns {string}
*/
context.getEventUrl = function(event) {
return event.calendar.url + event.uri;
};

/**
* get a time-range string from moment object
* @param {moment} momentObject
* @returns {string}
*/
context.getTimeRangeString = function(momentObject) {
return momentObject.format('YYYYMMDD') + 'T' + momentObject.format('HHmmss') + 'Z';
};

/**
* get all events from a calendar within a time-range
* @param {Calendar} calendar
* @param {moment} start
* @param {moment} end
* @returns {Promise}
*/
this.getAll = function (calendar, start, end) {
const [skeleton, dPropChildren] = XMLUtility.getRootSkeleton('c:calendar-query');
dPropChildren.push({
name: 'd:prop',
children: [{
name: 'd:getetag'
}, {
name: 'c:calendar-data'
}]
});
dPropChildren.push({
name: 'c:filter',
children: [{
name: 'c:comp-filter',
attributes: {
name: 'VCALENDAR'
},
children: [{
name: 'c:comp-filter',
attributes: {
name: 'VEVENT'
},
children: [{
name: 'c:time-range',
attributes: {
start: context.getTimeRangeString(start),
end: context.getTimeRangeString(end)
}
}]
}]
}]
});

const url = calendar.url;
const headers = {
'Content-Type': 'application/xml; charset=utf-8',
'Depth': 1,
'requesttoken': OC.requestToken
};
const xml = XMLUtility.serialize(skeleton);

return DavClient.request('REPORT', url, headers, xml).then(function (response) {
if (!DavClient.wasRequestSuccessful(response.status)) {
return Promise.reject(response.status);
}

const vevents = [];
for (let key in response.body) {
if (!response.body.hasOwnProperty(key)) {
continue;
}

const obj = response.body[key];
const props = obj.propStat[0].properties;
const calendarData = props[context.calendarDataPropName];
const etag = props[context.eTagPropName];
const uri = obj.href.substr(obj.href.lastIndexOf('/') + 1);

try {
const vevent = new VEvent(calendar, calendarData, etag, uri);
vevents.push(vevent);
} catch (e) {
console.log(e);
}
}

return vevents;
});
};

/**
* get an event by uri from a calendar
* @param {Calendar} calendar
* @param {string} uri
* @returns {Promise}
*/
this.get = function (calendar, uri) {
const url = calendar.url + uri;
const headers = {
'requesttoken': OC.requestToken
};

return DavClient.request('GET', url, headers, '').then(function (response) {
const calendarData = response.body;
const etag = response.xhr.getResponseHeader('ETag');

try {
return new VEvent(calendar, calendarData, etag, uri);
} catch (e) {
console.log(e);
return Promise.reject(e);
}
});
};

/**
* create a new event
* @param {Calendar} calendar
* @param {data} data
* @param {boolean} returnEvent
* @returns {Promise}
*/
this.create = function (calendar, data, returnEvent=true) {
const headers = {
'Content-Type': 'text/calendar; charset=utf-8',
'requesttoken': OC.requestToken
};
const uri = StringUtility.uid('Nextcloud', 'ics');
const url = calendar.url + uri;

return DavClient.request('PUT', url, headers, data).then(function (response) {
if (!DavClient.wasRequestSuccessful(response.status)) {
return Promise.reject(response.status);
}

if (returnEvent) {
return context.self.get(calendar, uri);
} else {
return true;
}
});
};

/**
* update an event
* @param {VEvent} event
* @returns {Promise}
*/
this.update = function (event) {
const url = context.getEventUrl;
const headers = {
'Content-Type': 'text/calendar; charset=utf-8',
'If-Match': event.etag,
'requesttoken': OC.requestToken
};
const payload = event.data;

return DavClient.request('PUT', url, headers, payload).then(function (response) {
// update etag of existing event
event.etag = response.xhr.getResponseHeader('ETag');

return DavClient.wasRequestSuccessful(response.status);
});
};

/**
* delete an event
* @param {VEvent} event
* @returns {Promise}
*/
this.delete = function (event) {
const url = context.getEventUrl(event);
const headers = {
'If-Match': event.etag,
'requesttoken': OC.requestToken
};

return DavClient.request('DELETE', url, headers, '').then(function (response) {
if (DavClient.wasRequestSuccessful(response.status)) {
return true;
} else {
return Promise.reject(response.status);
}
});
};
});
Loading

0 comments on commit c79d2a6

Please sign in to comment.