0010080: caldav client / import caldav tasks/task lists via CLI
authorPhilipp Schüle <p.schuele@metaways.de>
Wed, 20 Aug 2014 17:29:44 +0000 (19:29 +0200)
committerPhilipp Schüle <p.schuele@metaways.de>
Thu, 4 Sep 2014 09:26:44 +0000 (11:26 +0200)
WORKS
* import task calendars
* import tasks

TODO
* implement updateAllCalendarData
* implement etag set/get

https://forge.tine20.org/mantisbt/view.php?id=10080

Change-Id: Ic2271a7ed88cc08b7a8b6b9f93b1cf59d2600e9b
Reviewed-on: http://gerrit.tine20.com/customers/1029
Tested-by: Jenkins CI (http://ci.tine20.com/)
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
Tested-by: Philipp Schüle <p.schuele@metaways.de>
tine20/Calendar/Frontend/CalDAV/Cli.php [new file with mode: 0644]
tine20/Calendar/Frontend/Cli.php
tine20/Calendar/Import/CalDav/Client.php
tine20/Tasks/Frontend/CalDAV/Cli.php [new file with mode: 0644]
tine20/Tasks/Frontend/Cli.php [new file with mode: 0644]
tine20/Tasks/Frontend/WebDAV/Task.php
tine20/Tasks/Import/CalDav/Client.php [new file with mode: 0644]

diff --git a/tine20/Calendar/Frontend/CalDAV/Cli.php b/tine20/Calendar/Frontend/CalDAV/Cli.php
new file mode 100644 (file)
index 0000000..2069e6e
--- /dev/null
@@ -0,0 +1,279 @@
+<?php
+/**
+ * Tine 2.0
+ * @package     Calendar
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Paul Mehrer <p.mehrer@metaways.de>
+ * @author      Philipp Schüle <p.schuele@metaways.de>
+ * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+
+/**
+ * CalDAV import helper functions for CLI
+ *
+ * @package     Calendar
+ */
+class Calendar_Frontend_CalDAV_Cli
+{
+    /**
+     * caldav users / single user data
+     * 
+     * @var array
+     */
+    protected $_users = array();
+    
+    /**
+     * @var Calendar_Import_CalDav_Client
+     */
+    protected $_caldavClient = null;
+    
+    /**
+     * CLI opts
+     * 
+     * @var Zend_Console_Getopt
+     */
+    protected $_opts;
+    
+    /**
+     * parsed CLI arguments
+     * 
+     * @var array
+     */
+    protected $_args;
+    
+    protected $_numberOfImportRuns = 2;
+    protected $_caldavClientClass = 'Calendar_Import_CalDav_Client';
+    protected $_appName = 'Calendar';
+    
+    /**
+     * the constructor
+     */
+    public function __construct(Zend_Console_Getopt $opts, $args)
+    {
+        $this->_opts = $opts;
+        $this->_args = $args;
+        
+        if (Tinebase_Core::isLogLevel(Zend_Log::INFO))
+            Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Init caldav cli helper with params: ' . print_r($args, true));
+        
+        $this->_readCalDavUserFile($args['caldavuserfile'], isset($args['line']) ? $args['line'] : 0);
+        
+        if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG))
+             Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' User(s): '
+                . (isset($this->_users['username']) ? $this->_users['username'] : count($this->_users)));
+        
+        $caldavClientOptions = array(
+            'baseUri' => $args['url']
+        );
+        if (isset($this->_users['username'])) {
+            $caldavClientOptions = array_merge($caldavClientOptions, array(
+                'userName' => $this->_users['username'],
+                'password' => $this->_users['password'],
+            ));
+        }
+        $this->_caldavClient = new $this->_caldavClientClass($caldavClientOptions, 'MacOSX');
+        $this->_caldavClient->setVerifyPeer(false);
+    }
+    
+    /**
+     * import all calendars
+     */
+    public function importAllCalendars()
+    {
+        $this->_caldavClient->importAllCalendarsForUsers($this->_users);
+    }
+    
+    /**
+     * import all data for users
+     */
+    public function importAllCalendarDataForUsers()
+    {
+        $this->_caldavClient->importAllCalendarDataForUsers($this->_users);
+    }
+
+    /**
+     * import all data for single user
+     */
+    public function importAllCalendarData()
+    {
+        $this->_caldavClient->importAllCalendarData($this->_args['run'] == 1 ? true : false);
+    }
+    
+    /**
+     * update all data for users
+     */
+    public function updateAllCalendarDataForUsers()
+    {
+        $this->_caldavClient->updateAllCalendarDataForUsers($this->_users);
+    }
+    
+    /**
+     * update all data for single user
+     */
+    public function updateAllCalendarData()
+    {
+        $this->_caldavClient->updateAllCalendarData($this->_args['run'] == 1 ? true : false);
+    }
+    
+    /**
+     * run import/update with multiple processes
+     * 
+     * @param string $mode
+     * @throws Exception
+     */
+    public function runImportUpdateMultiproc($mode)
+    {
+        $numProc = intval($this->_args['numProc']);
+        $this->_validateNumProc($numProc);
+        
+        if (empty($this->_opts->passwordfile)) {
+            throw new Exception('Passwordfile required for this method');
+        }
+        
+        if ($mode === 'import' && (empty($this->_args['dataonly']) || $this->_args['dataonly'] == false)) {
+            // first import the calendars, serial sadly
+            $this->importAllCalendars();
+        }
+        
+        $cliParams = '--username ' . $this->_opts->username . ' --passwordfile ' . $this->_opts->passwordfile
+        . ' --method ' . $this->_appName . '.' . $mode . 'CalDavDataForUser'
+                . ' url=' .  $this->_args['url'] . ' caldavuserfile=' . $this->_args['caldavuserfile'];
+        
+        for ($run = 1; $run <= $this->_numberOfImportRuns; ++$run) {
+            $this->_runMultiProcessImportUpdate($numProc, $cliParams, $run);
+        }
+    }
+    
+    /**
+     * validate num procs
+     * 
+     * @param string $numProc
+     * @throws Exception
+     */
+    protected function _validateNumProc($numProc)
+    {
+        if ($numProc < 1) {
+            throw new Exception('numProc: ' . $numProc . ' needs to be at least 1');
+        }
+        if ($numProc > 32) {
+            throw new Exception('numProc: ' . $numProc . ' needs to be lower than 33');
+        }
+    }
+    
+    /**
+     * run multi process command
+     * 
+     * do multiprocess part, no system resources may be used as of here, 
+     * like file handles, db resources... see pcntl_fork man page!
+     * 
+     * @todo add pids to processes array to allow better control 
+     * @todo generalize and move to Tinebase_CalDAV_Cli_Abstract
+     * 
+     * @param integer $numProc
+     * @param string $cliParams
+     * @param integer $run
+     */
+    protected function _runMultiProcessImportUpdate($numProc, $cliParams, $run = 1)
+    {
+        // $processes = array();
+        $processes = 0;
+        $line = 0;
+        foreach ($this->_users as $user => $pwd)
+        {
+            ++$line;
+            //if (count($processes) >= $numProc) {
+            if ($processes >= $numProc) {
+                $pid = pcntl_wait($status);
+    
+                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
+                        . ' pid: ' . $pid);
+    
+                // debug
+                //                     echo '1' . (int) pcntl_wexitstatus($status);
+                //                     echo '2' . (int) pcntl_wifexited($status);
+                //                     echo '3' . (int) pcntl_wifsignaled($status);
+                //                     echo '4' . (int) pcntl_wifstopped($status);
+                //                     echo '5' . (int) pcntl_wstopsig($status);
+                //                     echo '6' . (int) pcntl_wtermsig($status);
+    
+                if (pcntl_wifexited($status) === false ) {
+                    exit('pcntl_wait return value was not found in process list: ' . $pid . ' status: ' . $status . PHP_EOL);
+                }
+                
+                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
+                    . ' Child exited');
+                
+                // unset($processes[$pid]);
+                --$processes;
+            }
+    
+            $pid = pcntl_fork();
+            if ($pid == -1) {
+                exit('could not fork' . PHP_EOL);
+            } else if ($pid) {
+                // we are the parent
+                // $processes[$pid] = true;
+                ++$processes;
+            } else {
+                // we are the child
+                $command = './tine20.php ' . $cliParams . ' run=' . $run . ' line=' . $line;
+                
+                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
+                     . ' Spawning new child with command: ' . $command);
+                
+                exec($command);
+                exit();
+            }
+        }
+        // wait for childs to finish
+        // while (count($processes) > 0) {
+        while ($processes > 0) {
+            $pid = pcntl_wait($status);
+            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
+                    . ' pid: ' . $pid);
+    
+            if (pcntl_wifexited($status) === false) {
+                exit('pcntl_wait return value was not found in process list: ' . $pid . ' status: ' . $status . PHP_EOL);
+            }
+            // unset($processes[$pid]);
+            --$processes;
+        }
+    }
+    
+    /**
+     * read caldav user credentials file
+     * 
+     * - file should have the following format (CSV):
+     * USERNAME1;PASSWORD1
+     * USERNAME2;PASSWORD2
+     * 
+     * @param string $file
+     * @throws Exception
+     */
+    protected function _readCalDavUserFile($file, $line = 0)
+    {
+        if (!($fh = fopen($file, 'r'))) {
+            Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' Couldn\'t open file: '.$file);
+            throw new Exception('Couldn\'t open file: '.$file);
+        }
+        $this->_users = array();
+        $i = 0;
+        while ($row = fgetcsv($fh, 2048, ';'))
+        {
+            if ($line > 0 && ++$i == $line) {
+                // only fetch single user
+                $this->_users = array('username' => $row[0], 'password' => $row[1]);
+                return;
+            }
+            $this->_users[$row[0]] = $row[1];
+        }
+        if (count($this->_users) < 1) {
+            Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' No users found in: '.$file);
+            throw new Exception('No users found in: '.$file);
+        }
+        if ($line > 0) {
+            Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' Line: '.$line. ' out of bounds');
+            throw new Exception('No user found, line: '.$line. ' out of bounds');
+        }
+    }
+}
index 561d412..7c84b7a 100644 (file)
@@ -164,16 +164,8 @@ class Calendar_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
         
         $this->_addOutputLogWriter(4);
         
-        $users = $this->_readCalDavUserFile($args['caldavuserfile']);
-        
-        $this->_importAllCalendars($users, $args['url']);
-    }
-    
-    protected function _importAllCalendars($users, $uri)
-    {
-        $client = new Calendar_Import_CalDav_Client(array('baseUri' => $uri), 'MacOSX');
-        $client->setVerifyPeer(false);
-        $client->importAllCalendarsForUsers($users);
+        $caldavCli = new Calendar_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->importAllCalendars();
     }
     
     /**
@@ -185,16 +177,10 @@ class Calendar_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
     {
         $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile'));
         
-        $writer = new Zend_Log_Writer_Stream('php://output');
-        $writer->addFilter(new Zend_Log_Filter_Priority(4));
-        Tinebase_Core::getLogger()->addWriter($writer);
-        
-        $users = $this->_readCalDavUserFile($args['caldavuserfile']);
-        
-        $client = new Calendar_Import_CalDav_Client(array('baseUri' => $args['url']), 'MacOSX');
-        $client->setVerifyPeer(false);
+        $this->_addOutputLogWriter(4);
         
-        $client->importAllCalendarDataForUsers($users);
+        $caldavCli = new Calendar_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->importAllCalendarDataForUsers();
     }
     
     /**
@@ -204,129 +190,12 @@ class Calendar_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
      */
     public function importCalDavMultiProc(Zend_Console_Getopt $_opts)
     {
-        $this->_runImportUpdateMultiproc($_opts, 'import');
-    }
-    
-    protected function _runImportUpdateMultiproc(Zend_Console_Getopt $_opts, $mode)
-    {
         $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile', 'numProc'));
         
-        $numProc = intval($args['numProc']);
-        $this->_validateNumProc($numProc);
-        
-        if (empty($_opts->passwordfile)) {
-            throw new Exception('Passwordfile required for this method');
-        }
-        
         $this->_addOutputLogWriter(4);
         
-        $users = $this->_readCalDavUserFile($args['caldavuserfile']);
-        
-        if ($mode === 'import' && (empty($args['dataonly']) || $args['dataonly'] == false)) {
-            // first import the calendars, serial sadly
-            $this->_importAllCalendars($users, $args['url']);
-        }
-        
-        $cliParams = '--username ' . $_opts->username . ' --passwordfile ' . $_opts->passwordfile
-        . ' --method Calendar.' . $mode . 'CalDavDataForUser'
-                . ' url=' .  $args['url'] . ' caldavuserfile=' . $args['caldavuserfile'];
-        
-        $numberOfRuns = 2;
-        for ($run = 1; $run <= $numberOfRuns; ++$run)
-        {
-            $this->_runMultiProcessImportUpdate($numProc, $cliParams, $users, $run);
-        }
-    }
-    
-    protected function _validateNumProc($numProc)
-    {
-        if ($numProc < 1) {
-            throw new Exception('numProc: ' . $numProc . ' needs to be at least 1');
-        }
-        if ($numProc > 32) {
-            throw new Exception('numProc: ' . $numProc . ' needs to be lower than 33');
-        }
-    }
-    
-    /**
-     * run multi process command
-     * 
-     * do multiprocess part, no system resources may be used as of here, 
-     * like file handles, db resources... see pcntl_fork man page!
-     * 
-     * @todo add pids to processes array to allow better control 
-     * @todo generalize and move to Tinebase_Frontend_Cli_Abstract
-     * 
-     * @param integer $numProc
-     * @param string $cliParams
-     * @param array $users
-     * @param integer $run
-     */
-    protected function _runMultiProcessImportUpdate($numProc, $cliParams, $users, $run = 1)
-    {
-        // $processes = array();
-        $processes = 0;
-        $line = 0;
-        foreach ($users as $user => $pwd)
-        {
-            ++$line;
-            //if (count($processes) >= $numProc) {
-            if ($processes >= $numProc) {
-                $pid = pcntl_wait($status);
-    
-                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
-                        . ' pid: ' . $pid);
-    
-                // debug
-                //                     echo '1' . (int) pcntl_wexitstatus($status);
-                //                     echo '2' . (int) pcntl_wifexited($status);
-                //                     echo '3' . (int) pcntl_wifsignaled($status);
-                //                     echo '4' . (int) pcntl_wifstopped($status);
-                //                     echo '5' . (int) pcntl_wstopsig($status);
-                //                     echo '6' . (int) pcntl_wtermsig($status);
-    
-                if (pcntl_wifexited($status) === false ) {
-                    exit('pcntl_wait return value was not found in process list: ' . $pid . ' status: ' . $status . PHP_EOL);
-                }
-                
-                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
-                    . ' Child exited');
-                
-                // unset($processes[$pid]);
-                --$processes;
-            }
-    
-            $pid = pcntl_fork();
-            if ($pid == -1) {
-                exit('could not fork' . PHP_EOL);
-            } else if ($pid) {
-                // we are the parent
-                // $processes[$pid] = true;
-                ++$processes;
-            } else {
-                // we are the child
-                $command = './tine20.php ' . $cliParams . ' run=' . $run . ' line=' . $line;
-                
-                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
-                     . ' Spawning new child with command: ' . $command);
-                
-                exec($command);
-                exit();
-            }
-        }
-        // wait for childs to finish
-        // while (count($processes) > 0) {
-        while ($processes > 0) {
-            $pid = pcntl_wait($status);
-            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
-                    . ' pid: ' . $pid);
-    
-            if (pcntl_wifexited($status) === false) {
-                exit('pcntl_wait return value was not found in process list: ' . $pid . ' status: ' . $status . PHP_EOL);
-            }
-            // unset($processes[$pid]);
-            --$processes;
-        }
+        $caldavCli = new Calendar_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->runImportUpdateMultiproc('import');
     }
     
     /**
@@ -336,7 +205,12 @@ class Calendar_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
      */
     public function updateCalDavMultiProc(Zend_Console_Getopt $_opts)
     {
-        $this->_runImportUpdateMultiproc($_opts, 'update');
+        $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile', 'numProc'));
+        
+        $this->_addOutputLogWriter(4);
+        
+        $caldavCli = new Calendar_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->runImportUpdateMultiproc('update');
     }
     
     /**
@@ -348,23 +222,10 @@ class Calendar_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
     {
         $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile', 'line', 'run'));
         
-        $writer = new Zend_Log_Writer_Stream('php://output');
-        $writer->addFilter(new Zend_Log_Filter_Priority(4));
-        Tinebase_Core::getLogger()->addWriter($writer);
-        
-        $user = $this->_readCalDavUserFile($args['caldavuserfile'], $args['line']);
-
-        if (Tinebase_Core::isLogLevel(Zend_Log::INFO))
-            Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' user: ' . $user['username']);
-        
-        $client = new Calendar_Import_CalDav_Client(array(
-                'baseUri' => $args['url'],
-                'userName' => $user['username'],
-                'password' => $user['password'],
-                ), 'MacOSX');
-        $client->setVerifyPeer(false);
+        $this->_addOutputLogWriter(4);
         
-        $client->importAllCalendarData($args['run']==1 ? true : false);
+        $caldavCli = new Calendar_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->importAllCalendarData();
     }
     
     /**
@@ -376,25 +237,12 @@ class Calendar_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
     {
         $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile', 'line', 'run'));
         
-        $writer = new Zend_Log_Writer_Stream('php://output');
-        $writer->addFilter(new Zend_Log_Filter_Priority(4));
-        Tinebase_Core::getLogger()->addWriter($writer);
-        
-        $user = $this->_readCalDavUserFile($args['caldavuserfile'], $args['line']);
-        
-        if (Tinebase_Core::isLogLevel(Zend_Log::INFO))
-            Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' user: ' . $user['username']);
-        
-        $client = new Calendar_Import_CalDav_Client(array(
-                'baseUri' => $args['url'],
-                'userName' => $user['username'],
-                'password' => $user['password'],
-                ), 'MacOSX');
-        $client->setVerifyPeer(false);
+        $this->_addOutputLogWriter(4);
         
-        $client->updateAllCalendarData($args['run']==1 ? true : false);
+        $caldavCli = new Calendar_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->updateAllCalendarData();
     }
-   
+    
     /**
      * update calendar/events from a CalDav source using etags
      * 
@@ -404,51 +252,9 @@ class Calendar_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
     {
         $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile'));
         
-        $writer = new Zend_Log_Writer_Stream('php://output');
-        $writer->addFilter(new Zend_Log_Filter_Priority(4));
-        Tinebase_Core::getLogger()->addWriter($writer);
-        
-        $users = $this->_readCalDavUserFile($args['caldavuserfile']);
-        
-        $client = new Calendar_Import_CalDav_Client(array('baseUri' => $args['url']), 'MacOSX');
-        $client->setVerifyPeer(false);
+        $this->_addOutputLogWriter(4);
         
-        $client->updateAllCalendarDataForUsers($users);
-    }
-    
-    /**
-     * read caldav user credentials file
-     * 
-     * - file should have the following format (CSV):
-     * USERNAME1;PASSWORD1
-     * USERNAME2;PASSWORD2
-     * 
-     * @param string $file
-     * @throws Exception
-     */
-    protected function _readCalDavUserFile($file, $line = 0)
-    {
-        if (!($fh = fopen($file, 'r'))) {
-            Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' Couldn\'t open file: '.$file);
-            throw new Exception('Couldn\'t open file: '.$file);
-        }
-        $users = array();
-        $i = 0;
-        while ($row = fgetcsv($fh, 2048, ';'))
-        {
-            if ($line > 0 && ++$i == $line) {
-                return array('username' => $row[0], 'password' => $row[1]);
-            }
-            $users[$row[0]] = $row[1];
-        }
-        if (count($users) < 1) {
-            Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' No users found in: '.$file);
-            throw new Exception('No users found in: '.$file);
-        }
-        if ($line > 0) {
-            Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' Line: '.$line. ' out of bounds');
-            throw new Exception('No user found, line: '.$line. ' out of bounds');
-        }
-        return $users;
+        $caldavCli = new Calendar_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->updateAllCalendarDataForUsers();
     }
 }
index a8adaca..508c3ea 100644 (file)
@@ -26,6 +26,12 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
     protected $mapToDefaultContainer = 'calendar';
     protected $decorator = null;
     
+    protected $component = 'VEVENT';
+    protected $skipComonent = 'VTODO';
+    protected $modelName = 'Calendar_Model_Event';
+    protected $appName = 'Calendar';
+    protected $webdavFrontend = 'Calendar_Frontend_WebDAV_Event';
+    
     const findAllCalendarsRequest =
 '<?xml version="1.0"?>
 <d:propfind xmlns:d="DAV:">
@@ -66,7 +72,7 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
     {
         parent::__construct($a);
         
-        $flavor = 'Calendar_Import_CalDav_Decorator_'.$flavor;
+        $flavor = 'Calendar_Import_CalDav_Decorator_' . $flavor;
         $this->decorator = new $flavor($this);
     }
     
@@ -91,7 +97,7 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         foreach ($result as $uri => $response) {
             if (isset($response['{DAV:}resourcetype']) && isset($response['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']) && 
                     $response['{DAV:}resourcetype']->is('{urn:ietf:params:xml:ns:caldav}calendar') &&
-                    in_array('VEVENT', $response['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue())) {
+                    in_array($this->component, $response['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue())) {
                 $this->calendars[$uri]['acl'] = $response['{DAV:}acl'];
                 $this->calendars[$uri]['displayname'] = $response['{DAV:}displayname'];
                 $this->decorator->processAdditionalCalendarProperties($this->calendars[$uri], $response);
@@ -130,7 +136,7 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         }
     }
     
-    protected function findContainerForCalendar($calendarUri, $displayname, $defaultCalendarsName, $type, $application_id, $modelName)
+    protected function findContainerForCalendar($calendarUri, $displayname, $defaultCalendarsName, $type, $application_id)
     {
         // sha1() the whole calendar uri as it is very hard to separate a uuid string from the uri otherwise
         $uuid = sha1($calendarUri);
@@ -148,20 +154,20 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
             array(
                 'field' => 'model', 
                 'operator' => 'equals', 
-                'value' => 'Calendar_Model_Event'
+                'value' => $this->modelName
             ),
         ));
-        $existingCalendar = Tinebase_Container::getInstance()->search($filter, null, false, false, 'sync')->getFirstRecord();
+        $existingCalendar = Tinebase_Container::getInstance()->search($filter)->getFirstRecord();
         if ($existingCalendar) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
-                . ' Found existing calendar ' . $existingCalendar->name . ' (id: ' . $existingCalendar->getId() . ')');
+                . ' Found existing container ' . $existingCalendar->name . ' (id: ' . $existingCalendar->getId() . ')');
             return $existingCalendar;
         }
         
         $counter = '';
         
         if ($defaultCalendarsName == $displayname) {
-            $existingCalendar = Tinebase_Container::getInstance()->getDefaultContainer('Calendar_Model_Event');
+            $existingCalendar = Tinebase_Container::getInstance()->getDefaultContainer($this->modelName);
             if (! $existingCalendar->uuid) {
                 if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . ' ' . __LINE__
                     . ' Found existing calendar with the same name');
@@ -174,7 +180,7 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         
         try {
             while (true) {
-                $existingCalendar = Tinebase_Container::getInstance()->getContainerByName('Calendar', $displayname . $counter, $type, Tinebase_Core::getUser());
+                $existingCalendar = Tinebase_Container::getInstance()->getContainerByName($this->appName, $displayname . $counter, $type, Tinebase_Core::getUser());
                 
                 if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__
                     . ' Got calendar: ' . $existingCalendar->name . ' (id: ' . $existingCalendar->getId() . ')');
@@ -191,9 +197,13 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
                 'type'              => $type,
                 'backend'           => 'Sql',
                 'application_id'    => $application_id,
-                'model'             => $modelName,
+                'model'             => $this->modelName,
                 'uuid'              => $uuid
             ));
+            
+            if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__
+                    . ' Adding container: ' . $newContainer->name . ' for model ' . $this->modelName);
+            
             return Tinebase_Container::getInstance()->addContainer($newContainer);
         }
     }
@@ -207,14 +217,13 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__ 
             . ' Importing all calendars for user ' . $this->userName);
         
-        Calendar_Controller_Event::getInstance()->sendNotifications(false);
-        Calendar_Controller_Event::getInstance()->useNotes(false);
+        Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->sendNotifications(false);
+        Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->useNotes(false);
         Sabre\VObject\Component\VCalendar::$propertyMap['ATTACH'] = '\\Calendar_Import_CalDav_SabreAttachProperty';
         
         $this->decorator->initCalendarImport();
         
-        $modelName = Tinebase_Core::getApplicationInstance('Calendar')->getDefaultModel();
-        $application_id = Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId();
+        $application_id = Tinebase_Application::getInstance()->getApplicationByName($this->appName)->getId();
         $type = Tinebase_Model_Container::TYPE_PERSONAL;
         
         $defaultCalendarsName = $this->_getDefaultCalendarsName();
@@ -226,7 +235,7 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         
         foreach ($this->calendars as $calUri => $cal) {
             $container = $this->findContainerForCalendar($calUri, $cal['displayname'], $defaultCalendarsName,
-                    $type, $application_id, $modelName);
+                    $type, $application_id);
             
             $this->decorator->setCalendarProperties($container, $this->calendars[$calUri]);
             
@@ -271,7 +280,7 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         }
         
         $newICSs = array();
-        $calendarEventBackend = Calendar_Controller_Event::getInstance()->getBackend();
+        $calendarEventBackend = Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->getBackend();
         
         foreach ($this->calendarICSs as $calUri => $calICSs) {
             $start = 0;
@@ -357,17 +366,15 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . ' ' . __LINE__
             . ' Importing all calendar data for user ' . $this->userName . ' with ics uris: ' . print_r(array_keys($this->calendarICSs), true));
         
-        Calendar_Controller_Event::getInstance()->sendNotifications(false);
-        Calendar_Controller_Event::getInstance()->useNotes(false);
+        Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->sendNotifications(false);
+        Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->useNotes(false);
         Sabre\VObject\Component\VCalendar::$propertyMap['ATTACH'] = '\\Calendar_Import_CalDav_SabreAttachProperty';
         
         $this->decorator->initCalendarImport();
         
-        $modelName = Tinebase_Core::getApplicationInstance('Calendar')->getDefaultModel();
-        $application_id = Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId();
-        $type = Tinebase_Model_Container::TYPE_PERSONAL; //Tinebase_Model_Container::TYPE_SHARED;
-        $defaultContainer = Tinebase_Container::getInstance()->getDefaultContainer('Calendar_Model_Event');
-        $calendarEventBackend = Calendar_Controller_Event::getInstance()->getBackend();
+        $application_id = Tinebase_Application::getInstance()->getApplicationByName($this->appName)->getId();
+        $type = Tinebase_Model_Container::TYPE_PERSONAL;
+        $defaultContainer = Tinebase_Container::getInstance()->getDefaultContainer($this->modelName);
         
         $defaultCalendarsName = $this->_getDefaultCalendarsName();
         
@@ -376,7 +383,10 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
                 . ' Processing calendar ' . print_r($this->calendars[$calUri], true));
             
             $container = $this->findContainerForCalendar($calUri, $this->calendars[$calUri]['displayname'], $defaultCalendarsName,
-                    $type, $application_id, $modelName);
+                    $type, $application_id);
+            
+            if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . ' ' . __LINE__
+                    . ' User container: ' . print_r($container->toArray(), true));
             
             $this->decorator->setCalendarProperties($container, $this->calendars[$calUri]);
             
@@ -398,57 +408,67 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
                 $result = $this->calDavRequest('REPORT', $calUri, self::getAllCalendarDataRequest . $requestEnd, 1);
                 
                 foreach ($result as $key => $value) {
-                    if (isset($value['{urn:ietf:params:xml:ns:caldav}calendar-data'])) {
-                        $data = $value['{urn:ietf:params:xml:ns:caldav}calendar-data'];
-                        $name = explode('/', $key);
-                        $name = end($name);
-                        $id = $this->_getEventIdFromName($name);
-                        try {
-                            if ($update && in_array($id, $this->existingRecordIds[$calUri])) {
-                                $event = new Calendar_Frontend_WebDAV_Event($container, $id);
-                                if ($onlyCurrentUserOrganizer) {
-                                    // assert current user is organizer
-                                    if ($event->getRecord()->organizer && $event->getRecord()->organizer == Tinebase_Core::getUser()->contact_id) {
-                                        $event->put($data);
-                                    } else {
-                                        continue;
-                                    }
+                    if (! isset($value['{urn:ietf:params:xml:ns:caldav}calendar-data'])) {
+                        continue;
+                    }
+                    
+                    $data = $value['{urn:ietf:params:xml:ns:caldav}calendar-data'];
+                    
+                    if (strpos($data, 'BEGIN:' . $this->skipComonent) !== false) {
+                        if (Tinebase_Core::isLogLevel(Zend_Log::INFO))
+                            Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Skipping ' . $this->skipComonent);
+                        continue;
+                    }
+                    
+                    $name = explode('/', $key);
+                    $name = end($name);
+                    $id = $this->_getEventIdFromName($name);
+                    try {
+                        if ($update && in_array($id, $this->existingRecordIds[$calUri])) {
+                            $webdavFrontend = new $this->webdavFrontend($container, $id);
+                            // @todo move this to separate fn
+                            if ($onlyCurrentUserOrganizer && $this->modelName === 'Calendar_Model_Event') {
+                                // assert current user is organizer
+                                if ($webdavFrontend->getRecord()->organizer && $webdavFrontend->getRecord()->organizer == Tinebase_Core::getUser()->contact_id) {
+                                    $webdavFrontend->put($data);
                                 } else {
-                                    $event->put($data);
+                                    continue;
                                 }
-                                
                             } else {
-                                $event = Calendar_Frontend_WebDAV_Event::create(
-                                    $container,
-                                    $name,
-                                    $data,
-                                    $onlyCurrentUserOrganizer
-                                );
+                                $webdavFrontend->put($data);
                             }
                             
-                            if ($event) {
-                                $etags[$event->getRecord()->getId()] = $value['{DAV:}getetag'];
-                            }
-                        } catch (Exception $e) {
-                            // don't warn on VTODOs
-                            if (strpos($data, 'BEGIN:VTODO') !== false) {
-                                if (Tinebase_Core::isLogLevel(Zend_Log::INFO))
-                                    Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Skipping VTODO');
-                            } else {
-                                if (Tinebase_Core::isLogLevel(Zend_Log::WARN))
-                                    Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not create event from data: ' . $data);
-                                Tinebase_Exception::log($e);
-                            }
+                        } else {
+                            $webdavFrontend = call_user_func_array(array($this->webdavFrontend, 'create'), array(
+                                $container,
+                                $name,
+                                $data,
+                                $onlyCurrentUserOrganizer
+                            ));
+                        }
+                        
+                        if ($webdavFrontend) {
+                            $etags[$webdavFrontend->getRecord()->getId()] = $value['{DAV:}getetag'];
                         }
+                    } catch (Exception $e) {
+                        if (Tinebase_Core::isLogLevel(Zend_Log::WARN))
+                            Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not create event from data: ' . $data);
+                        Tinebase_Exception::log($e);
                     }
                 }
                 
-                $calendarEventBackend->setETags($etags);
+                $this->_setEtags($etags);
             } while($start < $max);
         }
         return true;
     }
     
+    protected function _setEtags($etags)
+    {
+        $calendarEventBackend = Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->getBackend();
+        $calendarEventBackend->setETags($etags);
+    }
+    
     /**
      * get Tine 2.0 group for given principal (by display name)
      * - result is cached for 1 week
@@ -469,7 +489,7 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         $group = null;
         
         $result = $this->calDavRequest('PROPFIND', $principal, self::resolvePrincipalRequest);
-        if (isset($result['{DAV:}group-member-set']) && isset($result['{DAV:}displayname'])) {
+        if (count($result['{DAV:}group-member-set']->getPrincipals()) > 0 && isset($result['{DAV:}displayname'])) {
             $groupDescription = $result['{DAV:}displayname'];
             try {
                 $group = Tinebase_Group::getInstance()->getGroupByPropertyFromSqlBackend('description',$groupDescription);
@@ -478,7 +498,7 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
                 Tinebase_Core::getCache()->save($group, $cacheId, array(), /* 1 week */ 24*3600*7);
             } catch (Tinebase_Exception_Record_NotDefined $ternd) {
                 if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) Tinebase_Core::getLogger()->notice(__METHOD__ . ' ' . __LINE__
-                        . ' Group not found: ' . $groupDescription);
+                        . ' Group not found: ' . $groupDescription . ' ' . print_r($result, true));
             }
         }
         
@@ -538,29 +558,16 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         for ($i=0; $i<count($user); ++$i) {
             switch ($privilege[$i]) {
                 case '{DAV:}all':
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_READ ] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_ADD] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_EDIT] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_DELETE] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_EXPORT] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_SYNC] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_ADMIN] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_FREEBUSY] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_PRIVATE] = true;
+                    $grants[$user[$i]] = $this->_getAllGrants();
                     break;
                 case '{urn:ietf:params:xml:ns:caldav}read-free-busy':
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_FREEBUSY] = true;
+                    $grants[$user[$i]] = $this->_getFreeBusyGrants();
                     break;
                 case '{DAV:}read':
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_READ] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_EXPORT] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_SYNC] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_FREEBUSY] = true;
+                    $grants[$user[$i]] = $this->_getReadGrants();
                     break;
                 case '{DAV:}write':
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_ADD] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_EDIT] = true;
-                    $grants[$user[$i]][Tinebase_Model_Grants::GRANT_DELETE] = true;
+                    $grants[$user[$i]] = $this->_getWriteGrants();
                     break;
                 case '{DAV:}read-current-user-privilege-set':
                     continue;
@@ -581,6 +588,48 @@ class Calendar_Import_CalDav_Client extends Tinebase_Import_CalDav_Client
         return new Tinebase_Record_RecordSet('Tinebase_Model_Grants', $grants, TRUE);
     }
     
+    protected function _getAllGrants()
+    {
+        return array(
+            Tinebase_Model_Grants::GRANT_READ => true,
+            Tinebase_Model_Grants::GRANT_ADD=> true,
+            Tinebase_Model_Grants::GRANT_EDIT=> true,
+            Tinebase_Model_Grants::GRANT_DELETE=> true,
+            Tinebase_Model_Grants::GRANT_EXPORT=> true,
+            Tinebase_Model_Grants::GRANT_SYNC=> true,
+            Tinebase_Model_Grants::GRANT_ADMIN=> true,
+            Tinebase_Model_Grants::GRANT_FREEBUSY=> true,
+            Tinebase_Model_Grants::GRANT_PRIVATE=> true,
+        );
+    }
+
+    protected function _getFreeBusyGrants()
+    {
+        return array(
+            Tinebase_Model_Grants::GRANT_FREEBUSY=> true,
+        );
+    }
+
+    protected function _getReadGrants()
+    {
+        return array(
+            Tinebase_Model_Grants::GRANT_READ=> true,
+            Tinebase_Model_Grants::GRANT_EXPORT=> true,
+            Tinebase_Model_Grants::GRANT_SYNC=> true,
+            Tinebase_Model_Grants::GRANT_FREEBUSY=> true,
+        );
+    }
+
+    protected function _getWriteGrants()
+    {
+        return array(
+            Tinebase_Model_Grants::GRANT_READ=> true,
+            Tinebase_Model_Grants::GRANT_ADD=> true,
+            Tinebase_Model_Grants::GRANT_EDIT=> true,
+            Tinebase_Model_Grants::GRANT_DELETE=> true,
+        );
+    }
+    
     public function updateAllCalendarDataForUsers(array $users)
     {
         $result = true;
diff --git a/tine20/Tasks/Frontend/CalDAV/Cli.php b/tine20/Tasks/Frontend/CalDAV/Cli.php
new file mode 100644 (file)
index 0000000..15e9a1f
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Tine 2.0
+ * @package     Tasks
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Philipp Schüle <p.schuele@metaways.de>
+ * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+
+/**
+ * CalDAV import helper functions for CLI
+ *
+ * @package     Tasks
+ */
+class Tasks_Frontend_CalDAV_Cli extends Calendar_Frontend_CalDAV_Cli
+{
+    protected $_caldavClientClass = 'Tasks_Import_CalDav_Client';
+    protected $_numberOfImportRuns = 1;
+    protected $_appName = 'Tasks';
+}
diff --git a/tine20/Tasks/Frontend/Cli.php b/tine20/Tasks/Frontend/Cli.php
new file mode 100644 (file)
index 0000000..933eb09
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Tine 2.0
+ * @package     Tasks
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Philipp Schüle <p.schuele@metaways.de>
+ * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+
+/**
+ * Cli frontend for Tasks
+ *
+ * This class handles cli requests for the Tasks
+ *
+ * @package     Tasks
+ */
+class Tasks_Frontend_Cli extends Tinebase_Frontend_Cli_Abstract
+{
+    /**
+     * the internal name of the application
+     * 
+     * @var string
+     */
+    protected $_applicationName = 'Tasks';
+    
+    /**
+     * import calendars from a CalDav source
+     *
+     * param Zend_Console_Getopt $_opts
+     */
+    public function importCalDavCalendars(Zend_Console_Getopt $_opts)
+    {
+        $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile'));
+        
+        $this->_addOutputLogWriter(4);
+        
+        $caldavCli = new Tasks_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->importAllCalendars();
+    }
+    
+    /**
+     * import calendars and calendar events from a CalDav source using multiple parallel processes
+     *
+     * param Zend_Console_Getopt $_opts
+     */
+    public function importCalDavMultiProc(Zend_Console_Getopt $_opts)
+    {
+        $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile', 'numProc'));
+        
+        $this->_addOutputLogWriter(4);
+        
+        $caldavCli = new Tasks_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->runImportUpdateMultiproc('import');
+    }
+    
+    /**
+     * update calendar events from a CalDav source using multiple parallel processes
+     *
+     * param Zend_Console_Getopt $_opts
+     */
+    public function updateCalDavMultiProc(Zend_Console_Getopt $_opts)
+    {
+        $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile', 'numProc'));
+        
+        $this->_addOutputLogWriter(4);
+        
+        $caldavCli = new Tasks_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->runImportUpdateMultiproc('update');
+    }
+    
+    /**
+     * import calendar events from a CalDav source for one user
+     *
+     * param Zend_Console_Getopt $_opts
+     */
+    public function importCalDavDataForUser(Zend_Console_Getopt $_opts)
+    {
+        $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile', 'line', 'run'));
+        
+        $this->_addOutputLogWriter(4);
+        
+        $caldavCli = new Tasks_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->importAllCalendarData();
+    }
+    
+    /**
+     * update calendar/events from a CalDav source using etags for one user
+     *
+     * @param Zend_Console_Getopt $_opts
+     */
+    public function updateCalDavDataForUser(Zend_Console_Getopt $_opts)
+    {
+        $args = $this->_parseArgs($_opts, array('url', 'caldavuserfile', 'line', 'run'));
+        
+        $this->_addOutputLogWriter(4);
+        
+        $caldavCli = new Tasks_Frontend_CalDAV_Cli($_opts, $args);
+        $caldavCli->updateAllCalendarData();
+    }
+}
index b049318..69d0e11 100644 (file)
@@ -70,7 +70,7 @@ class Tasks_Frontend_WebDAV_Task extends Sabre\DAV\File implements Sabre\CalDAV\
      * @param  Tinebase_Model_Container  $container
      * @param  stream|string             $vobjectData
      */
-    public static function create(Tinebase_Model_Container $container, $name, $vobjectData)
+    public static function create(Tinebase_Model_Container $container, $name, $vobjectData, $onlyCurrentUserOrganizer = 'unused')
     {
         if (is_resource($vobjectData)) {
             $vobjectData = stream_get_contents($vobjectData);
diff --git a/tine20/Tasks/Import/CalDav/Client.php b/tine20/Tasks/Import/CalDav/Client.php
new file mode 100644 (file)
index 0000000..823e109
--- /dev/null
@@ -0,0 +1,155 @@
+<?php
+//./tine20.php --username unittest --method Tasks.importCalDav url="https://ical.metaways.de:8443" caldavuserfile=caldavuserfile.csv
+
+/**
+ * Tine 2.0
+ * 
+ * @package     Tasks
+ * @subpackage  Import
+ * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
+ * @author      Philipp Schüle <p.schuele@metaways.de>
+ * @copyright   Copyright (c) 2014 Metaways Infosystems GmbH (http://www.metaways.de)
+ */
+
+/**
+ * Tasks_Import_CalDAV
+ * 
+ * @package     Tasks
+ * @subpackage  Import
+ * 
+ * @todo        move generic parts from Calendar_Import_CalDav_Client to Tinebase and extend Tinebase_Import_CalDav_Client
+ * @todo        finish update
+ */
+class Tasks_Import_CalDav_Client extends Calendar_Import_CalDav_Client
+{
+    protected $component = 'VTODO';
+    protected $skipComonent = 'VEVENT';
+    protected $modelName = 'Tasks_Model_Task';
+    protected $appName = 'Tasks';
+    protected $webdavFrontend = 'Tasks_Frontend_WebDAV_Task';
+    
+    /**
+     * 
+     * @param string $onlyCurrentUserOrganizer
+     * @return boolean
+     * 
+     * @todo generalize
+     * @todo implement for tasks
+     */
+    public function updateAllCalendarData($onlyCurrentUserOrganizer = false)
+    {
+//         if (count($this->calendarICSs) < 1 && ! $this->findAllCalendarICSs()) {
+//             if (Tinebase_Core::isLogLevel(Zend_Log::INFO))
+//                 Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' no calendars found for: ' . $this->userName);
+//             return false;
+//         }
+        
+//         $newICSs = array();
+//         $calendarEventBackend = Tasks_Controller_Task::getInstance()->getBackend();
+        
+//         foreach ($this->calendarICSs as $calUri => $calICSs) {
+//             $start = 0;
+//             $max = count($calICSs);
+//             $etags = array();
+//             do {
+//                 $requestEnd = '';
+//                 for ($i = $start; $i < $max && $i < ($this->maxBulkRequest+$start); ++$i) {
+//                     $requestEnd .= '  <a:href>' . $calICSs[$i] . "</a:href>\n";
+//                 }
+//                 $start = $i;
+//                 $requestEnd .= '</b:calendar-multiget>';
+//                 $result = $this->calDavRequest('REPORT', $calUri, self::getEventETagsRequest . $requestEnd, 1);
+                
+//                 foreach ($result as $key => $value) {
+//                     if (isset($value['{DAV:}getetag'])) {
+//                         $name = explode('/', $key);
+//                         $name = end($name);
+//                         $id = $this->_getEventIdFromName($name);
+//                         $etags[$key] = array( 'id' => $id, 'etag' => $value['{DAV:}getetag']);
+//                     }
+//                 }
+//             } while($start < $max);
+            
+//             //check etags
+//             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' '
+//                 . ' Got ' . count($etags) . ' etags');
+//             if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' '
+//                 . ' etags: ' . print_r($etags, true));
+            
+//             // @todo find out deleted events
+//             foreach ($etags as $ics => $data) {
+//                 try {
+//                     $etagCheck = $calendarEventBackend->checkETag($data['id'], $data['etag']);
+//                     if ($etagCheck) {
+//                         continue; // same
+//                     } else {
+//                         $eventExists = true; // different
+//                     }
+//                 } catch (Tinebase_Exception_NotFound $tenf) {
+//                     $eventExists = false;
+//                 }
+                
+//                 if (!isset($newICSs[$calUri])) {
+//                     $newICSs[$calUri] = array();
+//                     $this->existingRecordIds[$calUri] = array();
+//                 }
+//                 $newICSs[$calUri][] = $ics;
+//                 if ($eventExists) {
+//                     $this->existingRecordIds[$calUri][] = $data['id'];
+//                 }
+//             }
+//         }
+        
+//         if (($count = count($newICSs)) > 0) {
+//             if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' ' 
+//                     . $count . ' calendar(s) changed for: ' . $this->userName);
+//             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' ' 
+//                     . ' events changed: ' . print_r($newICSs, true));
+//             $this->calendarICSs = $newICSs;
+//             $this->importAllCalendarData($onlyCurrentUserOrganizer, /* $update = */ true);
+//         } else {
+//             if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE))
+//                 Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' no changes found for: ' . $this->userName);
+//         }
+    }
+    
+    /**
+     * (non-PHPdoc)
+     * @see Calendar_Import_CalDav_Client::_setEtags()
+     * 
+     * @todo implement
+     */
+    protected function _setEtags($etags)
+    {
+//         $calendarEventBackend = Tinebase_Core::getApplicationInstance($this->appName, $this->modelName)->getBackend();
+//         $calendarEventBackend->setETags($etags);
+    }
+
+    protected function _getAllGrants()
+    {
+        return array(
+            Tinebase_Model_Grants::GRANT_READ => true,
+            Tinebase_Model_Grants::GRANT_ADD=> true,
+            Tinebase_Model_Grants::GRANT_EDIT=> true,
+            Tinebase_Model_Grants::GRANT_DELETE=> true,
+            Tinebase_Model_Grants::GRANT_EXPORT=> true,
+            Tinebase_Model_Grants::GRANT_SYNC=> true,
+            Tinebase_Model_Grants::GRANT_ADMIN=> true,
+        );
+    }
+    
+    protected function _getFreeBusyGrants()
+    {
+        return array(
+        );
+    }
+    
+    protected function _getReadGrants()
+    {
+        return array(
+            Tinebase_Model_Grants::GRANT_READ=> true,
+            Tinebase_Model_Grants::GRANT_EXPORT=> true,
+            Tinebase_Model_Grants::GRANT_SYNC=> true,
+        );
+    }
+}