4 commits - plugins/calendar plugins/libcalendaring
Thomas Brüderli
bruederli at kolabsys.com
Wed Oct 16 13:08:02 CEST 2013
plugins/calendar/calendar.php | 21 +++++++++++++++------
plugins/calendar/calendar_ui.js | 17 +++++++++++++++++
plugins/libcalendaring/libcalendaring.js | 6 +++++-
plugins/libcalendaring/libvcalendar.php | 9 +++++++++
4 files changed, 46 insertions(+), 7 deletions(-)
New commits:
commit 6dbbdba8a0f49ca35775d5699cbaf8edb8659017
Merge: 6951f8d 5c6a528
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Oct 16 13:07:36 2013 +0200
Merge branch 'master' of ssh://git.kolab.org/git/roundcubemail-plugins-kolab
commit 6951f8d4a4e710f959c0df3895fc57c61bfbb0f8
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Oct 16 13:01:55 2013 +0200
Catch errors on iCal import and provide appropriate feedback to the user (#2353)
diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index 4dec708..de4645e 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -975,10 +975,18 @@ class calendar extends rcube_plugin
if (!$err && $_FILES['_data']['tmp_name']) {
$calendar = get_input_value('calendar', RCUBE_INPUT_GPC);
- $events = $this->get_ical()->import_from_file($_FILES['_data']['tmp_name']);
-
- $count = $errors = 0;
$rangestart = $_REQUEST['_range'] ? date_create("now -" . intval($_REQUEST['_range']) . " months") : 0;
+ $count = $errors = 0;
+
+ try {
+ $events = $this->get_ical()->import_from_file($_FILES['_data']['tmp_name'], 'UTF-8', true);
+ }
+ catch (Exception $e) {
+ $errors = 1;
+ $msg = $e->getMessage();
+ $events = array();
+ }
+
foreach ($events as $event) {
// TODO: correctly handle recurring events which start before $rangestart
if ($event['end'] < $rangestart && (!$event['recurrence'] || ($event['recurrence']['until'] && $event['recurrence']['until'] < $rangestart)))
@@ -1000,8 +1008,9 @@ class calendar extends rcube_plugin
$this->rc->output->command('display_message', $this->gettext('importnone'), 'notice');
$this->rc->output->command('plugin.import_success', array('source' => $calendar));
}
- else
- $this->rc->output->command('display_message', $this->gettext('importerror'), 'error');
+ else {
+ $this->rc->output->command('plugin.import_error', array('message' => $this->gettext('importerror') . ($msg ? ': ' . $msg : '')));
+ }
}
else {
if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
@@ -1012,7 +1021,7 @@ class calendar extends rcube_plugin
$msg = rcube_label('fileuploaderror');
}
- $this->rc->output->command('display_message', $msg, 'error');
+ $this->rc->output->command('plugin.import_error', array('message' => $msg));
$this->rc->output->command('plugin.unlock_saving', false);
}
diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index 81e350f..d627253 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -1963,10 +1963,17 @@ function rcube_calendar_ui(settings)
if (form && form.elements._data.value) {
rcmail.async_upload_form(form, 'import_events', function(e) {
rcmail.set_busy(false, null, me.saving_lock);
+ $('.ui-dialog-buttonpane button', $dialog.parent()).button('enable');
+
+ // display error message if no sophisticated response from server arrived (e.g. iframe load error)
+ if (me.import_succeeded === null)
+ rcmail.display_message(rcmail.get_label('importerror', 'calendar'), 'error');
});
// display upload indicator
+ me.import_succeeded = null;
me.saving_lock = rcmail.set_busy(true, 'uploading');
+ $('.ui-dialog-buttonpane button', $dialog.parent()).button('disable');
}
};
@@ -1981,6 +1988,7 @@ function rcube_calendar_ui(settings)
closeOnEscape: false,
title: rcmail.gettext('importevents', 'calendar'),
close: function() {
+ $('.ui-dialog-buttonpane button', $dialog.parent()).button('enable');
$dialog.dialog("destroy").hide();
},
buttons: buttons,
@@ -1992,6 +2000,7 @@ function rcube_calendar_ui(settings)
// callback from server if import succeeded
this.import_success = function(p)
{
+ this.import_succeeded = true;
$("#eventsimport:ui-dialog").dialog('close');
rcmail.set_busy(false, null, me.saving_lock);
rcmail.gui_objects.importform.reset();
@@ -2000,6 +2009,13 @@ function rcube_calendar_ui(settings)
this.refresh(p);
};
+ // callback from server to report errors on import
+ this.import_error = function(p)
+ {
+ this.import_succeeded = false;
+ rcmail.display_message(p.message || rcmail.get_label('importerror', 'calendar'), 'error');
+ }
+
// show URL of the given calendar in a dialog box
this.showurl = function(calendar)
{
@@ -2762,6 +2778,7 @@ window.rcmail && rcmail.addEventListener('init', function(evt) {
rcmail.addEventListener('plugin.unlock_saving', function(p){ cal.unlock_saving(); });
rcmail.addEventListener('plugin.refresh_calendar', function(p){ cal.refresh(p); });
rcmail.addEventListener('plugin.import_success', function(p){ cal.import_success(p); });
+ rcmail.addEventListener('plugin.import_error', function(p){ cal.import_error(p); });
// let's go
var cal = new rcube_calendar_ui($.extend(rcmail.env.calendar_settings, rcmail.env.libcal_settings));
commit 1f851a7663e1ffd738ccb5357b386e88fdd11828
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Oct 16 12:46:13 2013 +0200
iCal parsing can consume high memory when file contains lots of events. Abort import if memory is expected to get exhausted (#2353)
diff --git a/plugins/libcalendaring/libvcalendar.php b/plugins/libcalendaring/libvcalendar.php
index c23d40b..24781c9 100644
--- a/plugins/libcalendaring/libvcalendar.php
+++ b/plugins/libcalendaring/libvcalendar.php
@@ -113,6 +113,15 @@ class libvcalendar
// TODO: convert charset to UTF-8 if other
try {
+ // estimate the memory usage and try to avoid fatal errors when allowed memory gets exhausted
+ $count = substr_count($vcal, 'BEGIN:VEVENT');
+ $memory_available = parse_bytes(ini_get('memory_limit')) - (function_exists('memory_get_usage') ? memory_get_usage() : 16*1024*1024);
+ $expected_memory = $count * 70*1024; // assume ~ 70K per event (empirically determined)
+
+ if ($memory_available > 0 && $expected_memory > $memory_available) {
+ throw new Exception("iCal file too big");
+ }
+
$vobject = VObject\Reader::read($vcal, VObject\Reader::OPTION_FORGIVING | VObject\Reader::OPTION_IGNORE_INVALID_LINES);
if ($vobject)
return $this->import_from_vobject($vobject);
commit dae0af24cd19d8c533ab4f89ea7eda8e495ed92a
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Oct 16 12:30:20 2013 +0200
Avoid warnings if libcalendaring env variables are not set (#2356)
diff --git a/plugins/libcalendaring/libcalendaring.js b/plugins/libcalendaring/libcalendaring.js
index 73d1c1e..5dcc3d4 100644
--- a/plugins/libcalendaring/libcalendaring.js
+++ b/plugins/libcalendaring/libcalendaring.js
@@ -23,12 +23,16 @@
function rcube_libcalendaring(settings)
{
// member vars
- this.settings = settings;
+ this.settings = settings || {};
this.alarm_ids = [];
this.alarm_dialog = null;
this.snooze_popup = null;
this.dismiss_link = null;
+ // abort if env isn't set
+ if (!settings || !settings.date_format)
+ return;
+
// private vars
var me = this;
var gmt_offset = (new Date().getTimezoneOffset() / -60) - (settings.timezone || 0) - (settings.dst || 0);
More information about the commits
mailing list