From c387565a45dfa11c708921e4d5aec5b57ab96764 Mon Sep 17 00:00:00 2001 From: Christoph Haas Date: Wed, 14 May 2014 23:30:00 +0000 Subject: [PATCH] calendarimporter 2.1.0: - ics sync is now implemented --- backend/README.txt | 14 ++ backend/config.php | 1 + backend/functions.php | 165 ++++++++++++++++++ backend/sync.php | 150 ++++++++++++++++ build.xml | 3 +- changelog.txt | 3 + js/ABOUT.js | 2 +- js/external/Ext.util.base64.js | 47 +++++ js/settings/SettingsCalSyncWidget.js | 14 +- .../dialogs/CalSyncEditContentPanel.js | 6 +- js/settings/dialogs/CalSyncEditPanel.js | 27 ++- js/settings/ui/CalSyncPanel.js | 2 +- manifest.xml | 3 +- php/download.php | 2 +- php/ical/class.icalparser.php | 2 +- php/module.calendar.php | 4 +- php/plugin.calendarimporter.php | 20 +++ php/upload.php | 2 +- test.php | 77 -------- 19 files changed, 430 insertions(+), 114 deletions(-) create mode 100644 backend/README.txt create mode 100644 backend/config.php create mode 100644 backend/functions.php create mode 100644 backend/sync.php create mode 100644 js/external/Ext.util.base64.js delete mode 100644 test.php diff --git a/backend/README.txt b/backend/README.txt new file mode 100644 index 0000000..e004f5b --- /dev/null +++ b/backend/README.txt @@ -0,0 +1,14 @@ +Backend setup: + +1. Create a Admin User in Zarafa: +zarafa-admin -c adminuser -e admin@domain.com -f "Calendar Sync Admin" -p topsecretpw -a 1 + +2. Edit the config.php to fit your needs. + +3. Setup cron to run your script every 10 minutes (or whatever...) + +4. If you get an error, make sure that the mapi module is loaded for php-cli: + * Add: /etc/php5/cli/conf.d/50-mapi.ini + * Content: extension=mapi.so + +Never run the backend script as root! \ No newline at end of file diff --git a/backend/config.php b/backend/config.php new file mode 100644 index 0000000..093b626 --- /dev/null +++ b/backend/config.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/backend/functions.php b/backend/functions.php new file mode 100644 index 0000000..f6a9625 --- /dev/null +++ b/backend/functions.php @@ -0,0 +1,165 @@ + + * Copyright (C) 2012-2014 Christoph Haas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* gets the data from a URL */ +function curl_get_data($url, $username = NULL, $password = NULL) { + $ch = curl_init(); + $timeout = 5; + + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); + + if($username != NULL && $password != NULL) { + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + curl_setopt($ch, CURLOPT_USERPWD, "$username:$password"); + } + + $data = curl_exec($ch); + $http_status = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE)); + curl_close($ch); + + if($http_status > 210 || $http_status < 200) + return NULL; + return $data; +} + +/* gets all zarafa users */ +function get_user_ics_list($userStore) { + // get settings + // first check if property exist and we can open that using mapi_openproperty + $storeProps = mapi_getprops($userStore, array(PR_EC_WEBACCESS_SETTINGS_JSON)); + + // Check if property exists, if it doesn not exist then we can continue with empty set of settings + if (isset($storeProps[PR_EC_WEBACCESS_SETTINGS_JSON]) || propIsError(PR_EC_WEBACCESS_SETTINGS_JSON, $storeProps) == MAPI_E_NOT_ENOUGH_MEMORY) { + // read the settings property + $stream = mapi_openproperty($userStore, PR_EC_WEBACCESS_SETTINGS_JSON, IID_IStream, 0, 0); + if ($stream == false) { + echo "Error opening settings property\n"; + } + + $settings_string = ""; + $stat = mapi_stream_stat($stream); + mapi_stream_seek($stream, 0, STREAM_SEEK_SET); + for ($i = 0; $i < $stat['cb']; $i += 1024) { + $settings_string .= mapi_stream_read($stream, 1024); + } + + if(empty($settings_string)) { + // property exists but without any content so ignore it and continue with + // empty set of settings + return; + } + + $settings = json_decode($settings_string, true); + if (empty($settings) || empty($settings['settings'])) { + echo "Error retrieving existing settings\n"; + } + + $calcontext = $settings["settings"]["zarafa"]["v1"]["contexts"]["calendar"]; + if(isset($calcontext["icssync"])) { + foreach($calcontext["icssync"] as $syncitem) { + echo "Found sync url: " . $syncitem["icsurl"] . " for calendar: " . $syncitem["calendar"] . "\n"; + } + + return $calcontext["icssync"]; + } + + return NULL; + } +} + +/* updates the webapp settings */ +function update_last_sync_date($userStore, $icsentry) { + // get settings + // first check if property exist and we can open that using mapi_openproperty + $storeProps = mapi_getprops($userStore, array(PR_EC_WEBACCESS_SETTINGS_JSON)); + + // Check if property exists, if it doesn not exist then we can continue with empty set of settings + if (isset($storeProps[PR_EC_WEBACCESS_SETTINGS_JSON]) || propIsError(PR_EC_WEBACCESS_SETTINGS_JSON, $storeProps) == MAPI_E_NOT_ENOUGH_MEMORY) { + // read the settings property + $stream = mapi_openpropertytostream($userStore, PR_EC_WEBACCESS_SETTINGS_JSON, MAPI_MODIFY); + if ($stream == false) { + echo "Error opening settings property\n"; + } + + $settings_string = ""; + $stat = mapi_stream_stat($stream); + mapi_stream_seek($stream, 0, STREAM_SEEK_SET); + for ($i = 0; $i < $stat['cb']; $i += 1024) { + $settings_string .= mapi_stream_read($stream, 1024); + } + + if(empty($settings_string)) { + // property exists but without any content so ignore it and continue with + // empty set of settings + return; + } + + $settings = json_decode($settings_string, true); + if (empty($settings) || empty($settings['settings'])) { + echo "Error retrieving existing settings\n"; + } + + $settings["settings"]["zarafa"]["v1"]["contexts"]["calendar"]["icssync"][$icsentry]["lastsync"] = date('Y-m-d H:i:s'); + + $newsettings = json_encode($settings); + mapi_stream_setsize($stream, strlen($newsettings)); + mapi_stream_seek($stream, 0, STREAM_SEEK_SET); + mapi_stream_write($stream, $newsettings); + $res = mapi_stream_commit ($stream); + return $res; + } + + return false; +} + +/* upload a file */ +function upload_ics_to_caldav($filename, $caldavurl, $username, $calendarname, $authuser = NULL, $authpass = NULL) { + $url = $caldavurl . $username . "/" . rawurlencode($calendarname) . "/"; + $post = array('file'=>'@'.$filename); + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL,$url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + + $fp = fopen($filename, 'r'); + curl_setopt($ch, CURLOPT_PUT, true); + curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); + curl_setopt($ch, CURLOPT_INFILE, $fp); + curl_setopt($ch, CURLOPT_INFILESIZE, filesize ($filename)); + + if($authuser != NULL && $authpass != NULL) { + curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + curl_setopt($ch, CURLOPT_USERPWD, "$authuser:$authpass"); + } + + $result=curl_exec($ch); + $http_status = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE)); + curl_close($ch); + + echo "uploading file to: " . $url . " (" . $http_status . ")\n"; + + return $http_status; +} +?> \ No newline at end of file diff --git a/backend/sync.php b/backend/sync.php new file mode 100644 index 0000000..647429b --- /dev/null +++ b/backend/sync.php @@ -0,0 +1,150 @@ +#!/usr/bin/php + + * Copyright (C) 2012-2014 Christoph Haas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +if(php_sapi_name() !== 'cli') { + die("Script must be run from commandline!"); +} + +/** + * Make sure that the zarafa mapi extension is enabled in cli mode: + * Add: /etc/php5/cli/conf.d/50-mapi.ini + * Content: extension=mapi.so + */ + +// MAPI includes +include('/usr/share/php/mapi/mapi.util.php'); +include('/usr/share/php/mapi/mapidefs.php'); +include('/usr/share/php/mapi/mapicode.php'); +include('/usr/share/php/mapi/mapitags.php'); +include('/usr/share/php/mapi/mapiguid.php'); +include('config.php'); +include('functions.php'); + +// log in to zarafa +$session = mapi_logon_zarafa($ADMINUSERNAME, $ADMINPASSWORD, $SERVER); +if($session === FALSE) { + exit("Logon failed with error " .mapi_last_hresult() . "\n"); +} + +// load all stores for the admin user +$storeTable = mapi_getmsgstorestable($session); +if($storeTable === FALSE) { + exit("Storetable could not be opened. Error " .mapi_last_hresult() . "\n"); +} +$storesList = mapi_table_queryallrows($storeTable, array(PR_ENTRYID, PR_DEFAULT_STORE)); + +// get admin users default store +foreach ($storesList as $row) { + if($row[PR_DEFAULT_STORE]) { + $storeEntryid = $row[PR_ENTRYID]; + } +} +if(!$storeEntryid) { + exit("Can't find default store\n"); +} + +// open default store +$store = mapi_openmsgstore($session, $storeEntryid); +if(!$store) { + exit("Unable to open system store\n"); +} + +// get a userlist +$userList = array(); +// for multi company setup +$companyList = mapi_zarafa_getcompanylist($store); +if(mapi_last_hresult() == NOERROR && is_array($companyList)) { + // multi company setup, get all users from all companies + foreach($companyList as $companyName => $companyData) { + $userList = array_merge($userList, mapi_zarafa_getuserlist($store, $companyData["companyid"])); + } +} else { + // single company setup, get list of all zarafa users + $userList = mapi_zarafa_getuserlist($store); +} +if(count($userList) <= 0) { + exit("Unable to get user list\n"); +} + +// loop over all users +foreach($userList as $userName => $userData) { + // check for valid users + if($userName == "SYSTEM" ||$userName == $ADMINUSERNAME) { + continue; + } + + echo "###Getting sync settings for user: " . $userName . "\n"; + + $userEntryId = mapi_msgstore_createentryid($store, $userName); + $userStore = mapi_openmsgstore($session, $userEntryId); + if(!$userStore) { + echo "Can't open user store\n"; + continue; + } + + $syncItems = get_user_ics_list($userStore); + + if($syncItems != NULL && count($syncItems) > 0) { + foreach($syncItems as $syncItemName => $syncItem) { + //check update intervall + $lastUpdate = strtotime($syncItem["lastsync"]); + $updateIntervall = intval($syncItem["intervall"]) * 60; // we need seconds + $currenttime = time(); + + if(($lastUpdate + $updateIntervall) <= $currenttime) { + echo "Update intervall OK ($currenttime): " . ($lastUpdate + $updateIntervall) . "\n"; + + $tmpFilename = $TEMPDIR . uniqid($userName . $syncItem["calendar"], true) . ".ics"; + + $user = NULL; + $pass= NULL; + + if($syncItem["user"] != NULL && !empty($syncItem["user"])) + $user = $syncItem["user"]; + if($syncItem["pass"] != NULL && !empty($syncItem["pass"])) + $pass= base64_decode($syncItem["pass"]); + + $icsData = curl_get_data($syncItem["icsurl"], $user, $pass); + + if($icsData != NULL) { + file_put_contents($tmpFilename, $icsData); + echo "Got valid data for " . $syncItem["icsurl"] . " stored in " . $tmpFilename . "\n"; + $result = upload_ics_to_caldav($tmpFilename, $CALDAVURL, $userName, $syncItem["calendar"], $ADMINUSERNAME, $ADMINPASSWORD); + if(intval($result) == 200) { + echo "Import completed: $result\n"; + $result = update_last_sync_date($userStore, $syncItemName); + $res = $result ? "true":"false"; + echo "Updated Zarafa settings: " . $res . "\n"; + } else { + echo "Uploading failed: " . $result . "\n"; + } + } + } else { + echo "Update intervall STOP ($currenttime): " . ($lastUpdate + $updateIntervall) . "\n"; + } + } + } + + echo "###Done sync for user: " . $userName . "\n\n"; +} +?> \ No newline at end of file diff --git a/build.xml b/build.xml index 3b1b606..47601f7 100644 --- a/build.xml +++ b/build.xml @@ -1,6 +1,6 @@ - + @@ -97,6 +97,7 @@ + diff --git a/changelog.txt b/changelog.txt index cae79da..3854a97 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,6 @@ +calendarimporter 2.1.0: + - ics sync is now implemented + calendarimporter 2.0.5: - added settings widget - compatible with webapp 1.5 and 1.6 diff --git a/js/ABOUT.js b/js/ABOUT.js index 244bd6b..3ee5b09 100644 --- a/js/ABOUT.js +++ b/js/ABOUT.js @@ -63,4 +63,4 @@ Zarafa.plugins.calendarimporter.ABOUT = "" + "

Licensed under the MIT License.

" - + "

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

" \ No newline at end of file + + "

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

"; \ No newline at end of file diff --git a/js/external/Ext.util.base64.js b/js/external/Ext.util.base64.js new file mode 100644 index 0000000..d6b9352 --- /dev/null +++ b/js/external/Ext.util.base64.js @@ -0,0 +1,47 @@ +Ext.util.base64 = { + base64s : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", + + encode: function(decStr){ + if (typeof btoa === 'function') { + return btoa(decStr); + } + var base64s = this.base64s; + var bits; + var dual; + var i = 0; + var encOut = ""; + while(decStr.length >= i + 3){ + bits = (decStr.charCodeAt(i++) & 0xff) <<16 | (decStr.charCodeAt(i++) & 0xff) <<8 | decStr.charCodeAt(i++) & 0xff; + encOut += base64s.charAt((bits & 0x00fc0000) >>18) + base64s.charAt((bits & 0x0003f000) >>12) + base64s.charAt((bits & 0x00000fc0) >> 6) + base64s.charAt((bits & 0x0000003f)); + } + if(decStr.length -i > 0 && decStr.length -i < 3){ + dual = Boolean(decStr.length -i -1); + bits = ((decStr.charCodeAt(i++) & 0xff) <<16) | (dual ? (decStr.charCodeAt(i) & 0xff) <<8 : 0); + encOut += base64s.charAt((bits & 0x00fc0000) >>18) + base64s.charAt((bits & 0x0003f000) >>12) + (dual ? base64s.charAt((bits & 0x00000fc0) >>6) : '=') + '='; + } + return(encOut); + }, + + decode: function(encStr){ + if (typeof atob === 'function') { + return atob(encStr); + } + var base64s = this.base64s; + var bits; + var decOut = ""; + var i = 0; + for(; i>16, (bits & 0xff00) >>8, bits & 0xff); + } + if(encStr.charCodeAt(i -2) == 61){ + return(decOut.substring(0, decOut.length -2)); + } + else if(encStr.charCodeAt(i -1) == 61){ + return(decOut.substring(0, decOut.length -1)); + } + else { + return(decOut); + } + } +} \ No newline at end of file diff --git a/js/settings/SettingsCalSyncWidget.js b/js/settings/SettingsCalSyncWidget.js index 35c9424..aacaed0 100644 --- a/js/settings/SettingsCalSyncWidget.js +++ b/js/settings/SettingsCalSyncWidget.js @@ -16,8 +16,7 @@ Zarafa.plugins.calendarimporter.settings.SettingsCalSyncWidget = Ext.extend(Zara * @constructor * @param {Object} config Configuration object */ - constructor : function(config) - { + constructor : function(config) { config = config || {}; var store = new Ext.data.JsonStore({ @@ -39,9 +38,8 @@ Zarafa.plugins.calendarimporter.settings.SettingsCalSyncWidget = Ext.extend(Zara Ext.applyIf(config, { height : 400, - title : _('Calendar Sync settings - Comming soon'), + title : _('Calendar Sync settings'), xtype : 'calendarimporter.settingscalsyncwidget', - disabled : true, layout : { // override from SettingsWidget type : 'fit' @@ -63,8 +61,7 @@ Zarafa.plugins.calendarimporter.settings.SettingsCalSyncWidget = Ext.extend(Zara * {@link Zarafa.settings.SettingsModel} into the UI of this category. * @param {Zarafa.settings.SettingsModel} settingsModel The settings to load */ - update : function(settingsModel) - { + update : function(settingsModel) { this.model = settingsModel; // Convert the signatures into Store data @@ -85,8 +82,7 @@ Zarafa.plugins.calendarimporter.settings.SettingsCalSyncWidget = Ext.extend(Zara * This is used to update the settings from the UI into the {@link Zarafa.settings.SettingsModel settings model}. * @param {Zarafa.settings.SettingsModel} settingsModel The settings to update */ - updateSettings : function(settingsModel) - { + updateSettings : function(settingsModel) { settingsModel.beginEdit(); // Start reading the Grid store and convert the contents back into @@ -111,4 +107,4 @@ Zarafa.plugins.calendarimporter.settings.SettingsCalSyncWidget = Ext.extend(Zara } }); -Ext.reg('calendarimporter.settingscalsyncwidget', Zarafa.plugins.calendarimporter.settings.SettingsCalSyncWidget); +Ext.reg('calendarimporter.settingscalsyncwidget', Zarafa.plugins.calendarimporter.settings.SettingsCalSyncWidget); \ No newline at end of file diff --git a/js/settings/dialogs/CalSyncEditContentPanel.js b/js/settings/dialogs/CalSyncEditContentPanel.js index 2da1cad..09a328f 100644 --- a/js/settings/dialogs/CalSyncEditContentPanel.js +++ b/js/settings/dialogs/CalSyncEditContentPanel.js @@ -12,20 +12,18 @@ Zarafa.plugins.calendarimporter.settings.dialogs.CalSyncEditContentPanel = Ext.e * @constructor * @param config Configuration structure */ - constructor : function(config) - { + constructor : function(config) { config = config || {}; // Add in some standard configuration data. Ext.applyIf(config, { // Override from Ext.Component xtype : 'calendarimporter.calsynceditcontentpanel', - // Override from Ext.Component layout : 'fit', model : true, autoSave : false, width : 400, - height : 100, + height : 350, title : _('ICAL Sync'), items : [{ xtype : 'calendarimporter.calsynceditpanel', diff --git a/js/settings/dialogs/CalSyncEditPanel.js b/js/settings/dialogs/CalSyncEditPanel.js index ebd7af4..1c664c9 100644 --- a/js/settings/dialogs/CalSyncEditPanel.js +++ b/js/settings/dialogs/CalSyncEditPanel.js @@ -18,8 +18,7 @@ Zarafa.plugins.calendarimporter.settings.dialogs.CalSyncEditPanel = Ext.extend(E * @constructor * @param config Configuration structure */ - constructor : function(config) - { + constructor : function(config) { config = config || {}; if(config.item) @@ -28,7 +27,7 @@ Zarafa.plugins.calendarimporter.settings.dialogs.CalSyncEditPanel = Ext.extend(E Ext.applyIf(config, { // Override from Ext.Component xtype : 'calendarimporter.calsynceditpanel', - labelAlign : 'left', + labelAlign : 'top', defaultType: 'textfield', items : this.createPanelItems(config), buttons: [{ @@ -68,9 +67,9 @@ Zarafa.plugins.calendarimporter.settings.dialogs.CalSyncEditPanel = Ext.extend(E icsurl: this.icsurl.getValue(), intervall: this.intervall.getValue(), user: this.user.getValue(), - pass: this.pass.getValue(), + pass: Ext.util.base64.encode(this.pass.getValue()), calendar: this.calendar.getValue(), - lastsync: 0 + lastsync: "never" }); } @@ -81,7 +80,7 @@ Zarafa.plugins.calendarimporter.settings.dialogs.CalSyncEditPanel = Ext.extend(E this.currentItem.set('icsurl', this.icsurl.getValue()); this.currentItem.set('intervall', this.intervall.getValue()); this.currentItem.set('user', this.user.getValue()); - this.currentItem.set('pass', this.pass.getValue()); + this.currentItem.set('pass', Ext.util.base64.encode(this.pass.getValue())); this.currentItem.set('calendar', this.calendar.getValue()); } this.dialog.close(); @@ -109,7 +108,7 @@ Zarafa.plugins.calendarimporter.settings.dialogs.CalSyncEditPanel = Ext.extend(E icsurl = config.item.get('icsurl'); intervall = config.item.get('intervall'); user = config.item.get('user'); - pass = config.item.get('pass'); + pass = Ext.util.base64.decode(config.item.get('pass')); calendar = config.item.get('calendar'); } @@ -144,16 +143,15 @@ Zarafa.plugins.calendarimporter.settings.dialogs.CalSyncEditPanel = Ext.extend(E return [{ xtype: 'fieldset', title: _('ICAL Information'), - defaultType: 'textfield', - layout: 'anchor', + defaultType: 'textfield', + layout: 'form', flex: 1, defaults: { anchor: '100%', - flex: 1, - labelWidth: 120 + flex: 1 }, items: [{ - fieldLabel: _('ICS Url'), + fieldLabel: 'ICS Url', name: 'icsurl', ref: '../icsurl', value: icsurl, @@ -176,7 +174,7 @@ Zarafa.plugins.calendarimporter.settings.dialogs.CalSyncEditPanel = Ext.extend(E }, { xtype:'numberfield', - fieldLabel: _('Sync Intervall'), + fieldLabel: _('Sync Intervall (minutes)'), name: 'intervall', ref: '../intervall', value: intervall, @@ -187,8 +185,7 @@ Zarafa.plugins.calendarimporter.settings.dialogs.CalSyncEditPanel = Ext.extend(E xtype: 'fieldset', title: _('Authentication (optional)'), defaultType: 'textfield', - labelWidth: 120, - layout: 'anchor', + layout: 'form', defaults: { anchor: '100%' }, diff --git a/js/settings/ui/CalSyncPanel.js b/js/settings/ui/CalSyncPanel.js index bf4eddc..c9e6cf8 100644 --- a/js/settings/ui/CalSyncPanel.js +++ b/js/settings/ui/CalSyncPanel.js @@ -45,7 +45,7 @@ Zarafa.plugins.calendarimporter.settings.ui.CalSyncPanel = Ext.extend(Ext.Panel, { return [{ xtype : 'displayfield', - value : _('Here you can enter .ics files that will be synchronised.'), + value : _('Setup calendars you want to subscribe to.'), fieldClass : 'x-form-display-field' }, { xtype : 'container', diff --git a/manifest.xml b/manifest.xml index be53fe0..d6303bc 100644 --- a/manifest.xml +++ b/manifest.xml @@ -24,11 +24,12 @@ js/calendarimporter-debug.js js/data/timezones.js + js/external/Ext.util.base64.js js/plugin.calendarimporter.js js/data/ResponseHandler.js js/dialogs/ImportContentPanel.js js/dialogs/ImportPanel.js - js/dialogs/settings/SettingsWidget.js + js/dialogs/settings/SettingsWidget.js js/dialogs/settings/SettingsCalSyncWidget.js js/dialogs/settings/ui/CalSyncGrid.js js/dialogs/settings/ui/CalSyncPanel.js diff --git a/php/download.php b/php/download.php index faa96c7..f94d39e 100644 --- a/php/download.php +++ b/php/download.php @@ -3,7 +3,7 @@ * download.php, zarafa calender to ics im/exporter * * Author: Christoph Haas - * Copyright (C) 2012-2013 Christoph Haas + * Copyright (C) 2012-2014 Christoph Haas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/php/ical/class.icalparser.php b/php/ical/class.icalparser.php index 58c4b54..a035847 100644 --- a/php/ical/class.icalparser.php +++ b/php/ical/class.icalparser.php @@ -4,7 +4,7 @@ * http://code.google.com/p/ics-parser/ * * Author: Martin Thoma , Christoph Haas - * Copyright (C) 2012-2013 Christoph Haas + * Copyright (C) 2012-2014 Christoph Haas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/php/module.calendar.php b/php/module.calendar.php index 0f65770..84b753e 100644 --- a/php/module.calendar.php +++ b/php/module.calendar.php @@ -1,9 +1,9 @@ - * Copyright (C) 2012-2013 Christoph Haas + * Copyright (C) 2012-2014 Christoph Haas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/php/plugin.calendarimporter.php b/php/plugin.calendarimporter.php index aae665e..ba28d83 100644 --- a/php/plugin.calendarimporter.php +++ b/php/plugin.calendarimporter.php @@ -1,5 +1,25 @@ + * Copyright (C) 2012-2014 Christoph Haas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * * calendarimporter Plugin * * With this plugin you can import a ics file to your zarafa calendar diff --git a/php/upload.php b/php/upload.php index 86f00c7..1410bcf 100644 --- a/php/upload.php +++ b/php/upload.php @@ -3,7 +3,7 @@ * upload.php, zarafa calender to ics exporter * * Author: Christoph Haas - * Copyright (C) 2012-2013 Christoph Haas + * Copyright (C) 2012-2014 Christoph Haas * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/test.php b/test.php deleted file mode 100644 index 7ae9649..0000000 --- a/test.php +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/php -getCode(); - return $e->getCode(); - } - break; - } - } -} - -// get settings -// first check if property exist and we can open that using mapi_openproperty -$storeProps = mapi_getprops($userstore, array(PR_EC_WEBACCESS_SETTINGS_JSON)); - -// Check if property exists, if it doesn not exist then we can continue with empty set of settings -if (isset($storeProps[PR_EC_WEBACCESS_SETTINGS_JSON]) || propIsError(PR_EC_WEBACCESS_SETTINGS_JSON, $storeProps) == MAPI_E_NOT_ENOUGH_MEMORY) { - // read the settings property - $stream = mapi_openproperty($userstore, PR_EC_WEBACCESS_SETTINGS_JSON, IID_IStream, 0, 0); - if ($stream == false) { - echo "Error opening settings property\n"; - } - - $settings_string = ""; - $stat = mapi_stream_stat($stream); - mapi_stream_seek($stream, 0, STREAM_SEEK_SET); - for ($i = 0; $i < $stat['cb']; $i += 1024) { - $settings_string .= mapi_stream_read($stream, 1024); - } - - if(empty($settings_string)) { - // property exists but without any content so ignore it and continue with - // empty set of settings - return; - } - - $settings = json_decode($settings_string, true); - if (empty($settings) || empty($settings['settings'])) { - echo "Error retrieving existing settings\n"; - } - - $calcontext = $settings["settings"]["zarafa"]["v1"]["contexts"]["calendar"]; - if(isset($calcontext["icssync"])) { - foreach($calcontext["icssync"] as $syncitem) { - echo $syncitem["icsurl"] . "
"; - } - } else { - echo "no sync items"; - } -} -?> \ No newline at end of file