Calendar import
parent
8a7f5556c4
commit
6ced731600
|
@ -99,13 +99,12 @@ define([
|
|||
'TRIGGER:'+str,
|
||||
'END:VALARM'
|
||||
]);
|
||||
// XXX ACTION:EMAIL
|
||||
// XXX ATTENDEE:mailto:xxx@xxx.xxx
|
||||
// XXX SUMMARY:Alarm notification
|
||||
});
|
||||
}
|
||||
|
||||
// XXX add hidden data (from imports)
|
||||
if (Array.isArray(data.cp_hidden)) {
|
||||
Array.prototype.push.apply(ICS, data.cp_hidden);
|
||||
}
|
||||
|
||||
ICS.push('END:VEVENT');
|
||||
});
|
||||
|
@ -115,6 +114,86 @@ define([
|
|||
return new Blob([ ICS.join('\n') ], { type: 'text/calendar;charset=utf-8' });
|
||||
};
|
||||
|
||||
module.import = function (content, id, cb) {
|
||||
require(['/lib/ical.min.js'], function () {
|
||||
var ICAL = window.ICAL;
|
||||
var res = {};
|
||||
|
||||
try {
|
||||
var jcalData = ICAL.parse(content);
|
||||
var vcalendar = new ICAL.Component(jcalData);
|
||||
} catch (e) {
|
||||
return void cb(e);
|
||||
}
|
||||
|
||||
var method = vcalendar.getFirstPropertyValue('method');
|
||||
if (method !== "PUBLISH") { return void cb('NOT_SUPPORTED'); }
|
||||
|
||||
var events = vcalendar.getAllSubcomponents('vevent');
|
||||
events.forEach(function (ev) {
|
||||
var uid = ev.getFirstPropertyValue('uid');
|
||||
if (!uid) { return; }
|
||||
|
||||
// Get start and end time
|
||||
var isAllDay = false;
|
||||
var start = ev.getFirstPropertyValue('dtstart');
|
||||
var end = ev.getFirstPropertyValue('dtend');
|
||||
if (start.isDate && end.isDate) {
|
||||
isAllDay = true;
|
||||
start = String(start);
|
||||
end.adjust(-1); // Substract one day
|
||||
end = String(end);
|
||||
} else {
|
||||
start = +start.toJSDate();
|
||||
end = +end.toJSDate();
|
||||
}
|
||||
|
||||
// Store other properties
|
||||
var used = ['dtstart', 'dtend', 'uid', 'summary', 'location', 'dtstamp'];
|
||||
var hidden = [];
|
||||
ev.getAllProperties().forEach(function (p) {
|
||||
if (used.indexOf(p.name) !== -1) { return; }
|
||||
// This is an unused property
|
||||
hidden.push(p.toICALString());
|
||||
});
|
||||
|
||||
// Get reminders
|
||||
var reminders = [];
|
||||
ev.getAllSubcomponents('valarm').forEach(function (al) {
|
||||
var action = al.getFirstPropertyValue('action');
|
||||
if (action !== 'DISPLAY') {
|
||||
// XXX email: maybe keep a notification in CryptPad?
|
||||
hidden.push(al.toString());
|
||||
return;
|
||||
}
|
||||
var trigger = al.getFirstPropertyValue('trigger');
|
||||
var minutes = -trigger.toSeconds() / 60;
|
||||
if (reminders.indexOf(minutes) === -1) { reminders.push(minutes); }
|
||||
});
|
||||
|
||||
// Create event
|
||||
res[uid] = {
|
||||
calendarId: id,
|
||||
id: uid,
|
||||
category: 'time',
|
||||
title: ev.getFirstPropertyValue('summary'),
|
||||
location: ev.getFirstPropertyValue('location'),
|
||||
isAllDay: isAllDay,
|
||||
start: start,
|
||||
end: end,
|
||||
reminders: reminders,
|
||||
cp_hidden: hidden
|
||||
};
|
||||
|
||||
if (!hidden.length) { delete res[uid].cp_hidden; }
|
||||
if (!reminders.length) { delete res[uid].reminders; }
|
||||
|
||||
});
|
||||
|
||||
cb(null, res);
|
||||
});
|
||||
};
|
||||
|
||||
return module;
|
||||
});
|
||||
|
||||
|
|
|
@ -107,6 +107,12 @@ Messages.calendar_allDay = "All day";
|
|||
cb(null, obj);
|
||||
});
|
||||
};
|
||||
var importICSCalendar = function (data, cb) {
|
||||
APP.module.execCommand('IMPORT_ICS', data, function (obj) {
|
||||
if (obj && obj.error) { return void cb(obj.error); }
|
||||
cb(null, obj);
|
||||
});
|
||||
};
|
||||
var newEvent = function (data, cb) {
|
||||
APP.module.execCommand('CREATE_EVENT', data, function (obj) {
|
||||
if (obj && obj.error) { return void cb(obj.error); }
|
||||
|
@ -466,7 +472,21 @@ Messages.calendar_allDay = "All day";
|
|||
},
|
||||
content: h('span', Messages.importButton),
|
||||
action: function (e) {
|
||||
e.stopPropagation();
|
||||
UIElements.importContent('text/calendar', function (res) {
|
||||
Export.import(res, id, function (err, json) {
|
||||
if (err) { return void UI.warn(Messages.importError); }
|
||||
importICSCalendar({
|
||||
id: id,
|
||||
json: json
|
||||
}, function (err) {
|
||||
if (err) { return void UI.warn(Messages.error); }
|
||||
UI.log(Messages.saved);
|
||||
});
|
||||
|
||||
});
|
||||
}, {
|
||||
accept: ['.ics']
|
||||
})();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -127,7 +127,7 @@ define([
|
|||
dcAlert = undefined;
|
||||
};
|
||||
|
||||
var importContent = function (type, f, cfg) {
|
||||
var importContent = UIElements.importContent = function (type, f, cfg) {
|
||||
return function () {
|
||||
var $files = $('<input>', {type:"file"});
|
||||
if (cfg && cfg.accept) {
|
||||
|
|
|
@ -434,6 +434,22 @@ ctx.calendars[channel] = {
|
|||
});
|
||||
};
|
||||
|
||||
var importICSCalendar = function (ctx, data, cId, cb) {
|
||||
var id = data.id;
|
||||
var c = ctx.calendars[id];
|
||||
if (!c || !c.proxy) { return void cb({error: "ENOENT"}); }
|
||||
var json = data.json;
|
||||
c.proxy.content = c.proxy.content || {};
|
||||
Object.keys(json).forEach(function (uid) {
|
||||
c.proxy.content[uid] = json[uid];
|
||||
});
|
||||
|
||||
Realtime.whenRealtimeSyncs(c.lm.realtime, function () {
|
||||
sendUpdate(ctx, c);
|
||||
cb();
|
||||
});
|
||||
};
|
||||
|
||||
var openCalendar = function (ctx, data, cId, cb) {
|
||||
var secret = Hash.getSecrets('calendar', data.hash, data.password);
|
||||
var hash = Hash.getEditHashFromKeys(secret);
|
||||
|
@ -785,6 +801,10 @@ ctx.calendars[channel] = {
|
|||
if (ctx.store.offline) { return void cb({error: 'OFFLINE'}); }
|
||||
return void importCalendar(ctx, data, clientId, cb);
|
||||
}
|
||||
if (cmd === 'IMPORT_ICS') {
|
||||
if (ctx.store.offline) { return void cb({error: 'OFFLINE'}); }
|
||||
return void importICSCalendar(ctx, data, clientId, cb);
|
||||
}
|
||||
if (cmd === 'ADD') {
|
||||
if (ctx.store.offline) { return void cb({error: 'OFFLINE'}); }
|
||||
return void addCalendar(ctx, data, clientId, cb);
|
||||
|
|
Loading…
Reference in New Issue