Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/mail.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'js/service/davservice.js')
-rw-r--r--js/service/davservice.js223
1 files changed, 223 insertions, 0 deletions
diff --git a/js/service/davservice.js b/js/service/davservice.js
new file mode 100644
index 000000000..a73dfcfa2
--- /dev/null
+++ b/js/service/davservice.js
@@ -0,0 +1,223 @@
+/**
+ * @author Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * ownCloud - Mail
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+define(function(require) {
+ 'use strict';
+
+ var _ = require('underscore');
+ var $ = require('jquery');
+ var Backbone = require('backbone');
+ var dav = require('davclient');
+ var ical = require('ical');
+ var OC = require('OC');
+ var Radio = require('radio');
+ var Calendar = require('models/dav/calendar');
+
+ Radio.dav.reply('calendars', getUserCalendars);
+ Radio.dav.reply('calendar:import', importCalendarEvent);
+
+ var 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://calendarserver.org/ns/': 'cs'
+ }
+ });
+ var props = [
+ '{DAV:}displayname',
+ '{urn:ietf:params:xml:ns:caldav}calendar-description',
+ '{urn:ietf:params:xml:ns:caldav}calendar-timezone',
+ '{http://apple.com/ns/ical/}calendar-order',
+ '{http://apple.com/ns/ical/}calendar-color',
+ '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set',
+ '{http://owncloud.org/ns}calendar-enabled',
+ '{DAV:}acl',
+ '{DAV:}owner',
+ '{http://owncloud.org/ns}invite'
+ ];
+
+ function getResponseCodeFromHTTPResponse(t) {
+ return parseInt(t.split(' ')[1]);
+ }
+
+ function getACLFromResponse(properties) {
+ var canWrite = false;
+ var acl = properties['{DAV:}acl'];
+ if (acl) {
+ for (var k = 0; k < acl.length; k++) {
+ var href = acl[k].getElementsByTagNameNS('DAV:', 'href');
+ if (href.length === 0) {
+ continue;
+ }
+ href = href[0].textContent;
+ var writeNode = acl[k].getElementsByTagNameNS('DAV:', 'write');
+ if (writeNode.length > 0) {
+ canWrite = true;
+ }
+ }
+ }
+ properties.canWrite = canWrite;
+ }
+ ;
+
+ function getCalendarData(properties) {
+ getACLFromResponse(properties);
+
+ var data = {
+ displayname: properties['{DAV:}displayname'],
+ color: properties['{http://apple.com/ns/ical/}calendar-color'],
+ order: properties['{http://apple.com/ns/ical/}calendar-order'],
+ components: {
+ vevent: false
+ },
+ writable: properties.canWrite
+ };
+
+ var components = properties['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'] || [];
+ for (var i = 0; i < components.length; i++) {
+ var name = components[i].attributes.getNamedItem('name').textContent.toLowerCase();
+ if (data.components.hasOwnProperty(name)) {
+ data.components[name] = true;
+ }
+ }
+
+ return data;
+ }
+
+ function getUserCalendars() {
+ var defer = $.Deferred();
+ var url = OC.linkToRemote('dav/calendars') + '/' + OC.currentUser + '/';
+
+ client.propFind(url, props, 1, {
+ 'requesttoken': OC.requestToken
+ }).then(function(data) {
+ var calendars = new Backbone.Collection();
+
+ _.each(data.body, function(cal) {
+ if (cal.propStat.length < 1) {
+ return;
+ }
+ if (getResponseCodeFromHTTPResponse(cal.propStat[0].status) === 200) {
+ var properties = getCalendarData(cal.propStat[0].properties);
+ if (properties && properties.components.vevent && properties.writable === true) {
+ properties.url = cal.href;
+ calendars.push(new Calendar(properties));
+ }
+ }
+ });
+ defer.resolve(calendars);
+ }, function() {
+ defer.reject();
+ });
+
+ return defer.promise();
+ }
+
+ function getRandomString() {
+ var str = '';
+ for (var i = 0; i < 7; i++) {
+ str += Math.random().toString(36).substring(7);
+ }
+ return str;
+ }
+
+ function createICalElement() {
+ var root = new ical.Component(['vcalendar', [], []]);
+
+ root.updatePropertyWithValue('prodid', '-//ownCloud Mail');
+
+ return root;
+ }
+
+ function splitCalendar(data) {
+ var timezones = [];
+ var allObjects = {};
+ var jCal = ical.parse(data);
+ var components = new ical.Component(jCal);
+
+ var vtimezones = components.getAllSubcomponents('vtimezone');
+ _.each(vtimezones, function(vtimezone) {
+ timezones.push(vtimezone);
+ });
+
+ var componentNames = ['vevent', 'vjournal', 'vtodo'];
+ _.each(componentNames, function(componentName) {
+ var vobjects = components.getAllSubcomponents(componentName);
+ allObjects[componentName] = {};
+
+ _.each(vobjects, function(vobject) {
+ var uid = vobject.getFirstPropertyValue('uid');
+ allObjects[componentName][uid] = allObjects[componentName][uid] || [];
+ allObjects[componentName][uid].push(vobject);
+ });
+ });
+
+ var split = [];
+ _.each(componentNames, function(componentName) {
+ split[componentName] = [];
+ _.each(allObjects[componentName], function(objects) {
+ var component = createICalElement();
+ _.each(timezones, function(timezone) {
+ component.addSubcomponent(timezone);
+ });
+ _.each(objects, function(object) {
+ component.addSubcomponent(object);
+ });
+ split[componentName].push(component.toString());
+ });
+ });
+
+ return {
+ name: components.getFirstPropertyValue('x-wr-calname'),
+ color: components.getFirstPropertyValue('x-apple-calendar-color'),
+ split: split
+ };
+ }
+
+ function importCalendarEvent(url, data) {
+ var defer = $.Deferred();
+ var xhrs = [];
+
+ var file = splitCalendar(data);
+
+ var componentNames = ['vevent', 'vjournal', 'vtodo'];
+ _.each(componentNames, function(componentName) {
+ _.each(file.split[componentName], function(component) {
+ xhrs.push($.ajax({
+ url: url + getRandomString(),
+ method: 'PUT',
+ contentType: 'text/calendar; charset=utf-8',
+ data: component,
+ error: function() {
+ defer.reject();
+ }
+ }));
+ });
+ });
+
+ $.when.apply($, xhrs).done(function() {
+ defer.resolve();
+ });
+
+ return defer.promise();
+ }
+});