From 0a01e6e90582c3de1a661d7df7fea7f924d79d88 Mon Sep 17 00:00:00 2001 From: Aerex Date: Fri, 18 Sep 2020 22:15:12 -0500 Subject: [PATCH] feat: Added tasks with no projects to default calendar --- lib/Configs/TaskwarriorConfig.php | 4 ++++ lib/Plugin.php | 30 ++++++++++++++++--------- lib/StorageManager.php | 5 +++-- lib/Storages/IStorage.php | 3 ++- lib/Storages/Taskwarrior.php | 37 +++++++++++++++++++------------ 5 files changed, 52 insertions(+), 27 deletions(-) diff --git a/lib/Configs/TaskwarriorConfig.php b/lib/Configs/TaskwarriorConfig.php index ded3c86..81528aa 100644 --- a/lib/Configs/TaskwarriorConfig.php +++ b/lib/Configs/TaskwarriorConfig.php @@ -17,8 +17,12 @@ class TaskwarriorConfig { ->defaultValue('~/.taskrc') ->info('The enivronment variable overrides the default and the command line specification of the .taskrc file') ->end() + ->scalarNode('default_calendar') + ->info('The default calendar to send tasks if no task project is set. The value is the calendar\'s displayname') + ->end() ->end(); return $node; } } + diff --git a/lib/Plugin.php b/lib/Plugin.php index c9377f8..4d01e91 100644 --- a/lib/Plugin.php +++ b/lib/Plugin.php @@ -12,6 +12,7 @@ use Sabre\HTTP\RequestInterface; use Sabre\HTTP\ResponseInterface; use Sabre\DAV\ServerPlugin; use Sabre\DAV\Server; +use Sabre\DAV\PropFind; /** * The plugin to interact with Baikal and external storages @@ -49,6 +50,14 @@ class Plugin extends ServerPlugin { $this->initializeStorages($this->rawConfigs); } + private function getDisplayName($path) { + $node = $this->server->tree->getNodeForPath($path); + $propFind = new PropFind($path, []); + $properties = $this->server->getPropertiesByNode($propFind, $node); + return $properties['d:displayname'] ?? ''; + + } + public function buildConfigurations($configFile) { $this->config = new ConfigBuilder($configFile); $this->config->add(new TaskwarriorConfig()); @@ -114,7 +123,6 @@ class Plugin extends ServerPlugin { return; } } - @@ -128,14 +136,15 @@ class Plugin extends ServerPlugin { function httpPut(RequestInterface $request){ $body = $request->getBodyAsString(); $vCal = \Sabre\VObject\Reader::read($body); - if (!stristr($vCal->PRODID, 'taskwarrior')) { - try { - $this->storageManager->import($vCal); - } catch(BadRequest $e){ - throw new BadRequest($e->getMessage(), null, $e); - } catch(\Exception $e){ - throw new \Exception($e->getMessage(), null, $e); + $displayname = $this->getDisplayName($request->getPath()); + try { + if (!stristr($vCal->PRODID, 'taskwarrior')) { + $this->storageManager->import($vCal, $displayname); } + } catch(BadRequest $e){ + throw new BadRequest($e->getMessage(), null, $e); + } catch(\Exception $e){ + throw new \Exception($e->getMessage(), null, $e); } $request->setBody($body); @@ -188,9 +197,9 @@ class Plugin extends ServerPlugin { $body = $request->getBodyAsString(); $path = $request->getPath(); $paths = explode('/', $path); - if (isset($paths) && sizeof($paths) > 1) { + if (sizeof($paths) > 1) { $uid = str_replace('.ics', '', $paths[sizeof($paths)-1]); - // Check if deleting an ics file + // Attempt to delete if we are removing an ics file if ($uid != '') { $this->storageManager->remove($uid); } @@ -297,3 +306,4 @@ class Plugin extends ServerPlugin { } } + diff --git a/lib/StorageManager.php b/lib/StorageManager.php index cfc3116..7930276 100644 --- a/lib/StorageManager.php +++ b/lib/StorageManager.php @@ -34,7 +34,7 @@ class StorageManager { $this->storages[$name] = $storage; } - public function import(Calendar $calendar) { + public function import(Calendar $calendar, string $displayname) { if (!isset($this->configs)) { throw new \Exception('StorageManger was not initialize or configs are not defined'); } @@ -43,7 +43,7 @@ class StorageManager { if (!isset($storage)){ throw new \Exception(); } - $storage->save($calendar); + $storage->save($calendar, $displayname); } } @@ -60,3 +60,4 @@ class StorageManager { } } } + diff --git a/lib/Storages/IStorage.php b/lib/Storages/IStorage.php index 579397e..2f3911e 100644 --- a/lib/Storages/IStorage.php +++ b/lib/Storages/IStorage.php @@ -5,9 +5,10 @@ namespace Aerex\BaikalStorage\Storages; use Sabre\VObject\Component\VCalendar as Calendar; interface IStorage { - public function save(Calendar $c); + public function save(Calendar $c, string $displayname); public function remove($uid); public function refresh(); public function getConfigBrowser(); public function updateConfigs($postData); } + diff --git a/lib/Storages/Taskwarrior.php b/lib/Storages/Taskwarrior.php index 6a7237d..31a99aa 100644 --- a/lib/Storages/Taskwarrior.php +++ b/lib/Storages/Taskwarrior.php @@ -18,11 +18,6 @@ class Taskwarrior implements IStorage { } public function getConfigBrowser() { - $html = ''; - $html .= 'taskrc'; - $html .= 'The enivronment variable overrides the default and the command line specification of the .taskrc file'; - $html .= ''; - $html .= ''; $html = ''; $html .= 'taskrc'; $html .= 'The enivronment variable overrides the default and the command line specification of the .taskrc file'; @@ -33,6 +28,11 @@ class Taskwarrior implements IStorage { $html .= 'The environment variable overrides the default and the command line, and the "data.location" configuration setting of the task data directory'; $html .= ''; $html .= ''; + $html .= ''; + $html .= 'default_calendar'; + $html .= 'The default calendar to send tasks if no task project is set. The value is the calendar\'s displayname'; + $html .= ''; + $html .= ''; return $html; } @@ -44,13 +44,17 @@ class Taskwarrior implements IStorage { if (isset($postData['tw_taskdata'])){ $this->configs['taskdata'] = $postData['tw_taskdata']; } + if (isset($postData['tw_default_calendar'])){ + $this->configs['default_calendar'] = $postData['tw_default_calendar']; + } return $this->configs; } public function refresh() { - $output = $this->console->execute('task', ['sync'], null, + $this->logger->info('Syncing taskwarrior tasks...'); + $this->console->execute('task', ['sync'], null, ['TASKRC' => $this->configs['taskrc'],'TASKDATA' => $this->configs['taskdata']]); $this->tasks = json_decode($this->console->execute('task', ['export'], null, ['TASKRC' => $this->configs['taskrc'], 'TASKDATA' => $this->configs['taskdata']]), true); @@ -59,10 +63,9 @@ class Taskwarrior implements IStorage { $this->tasks[$task['uid']] = $task; } } - $this->logger->info($output); } - public function vObjectToTask($vtodo) { + public function vObjectToTask($vtodo, string $displayname) { if (isset($this->tasks[(string)$vtodo->UID])) { $task = $this->tasks[(string)$vtodo->UID]; } else { @@ -101,8 +104,8 @@ class Taskwarrior implements IStorage { $task['start'] = $vtodo->DTSTART->getDateTime()->format(\DateTime::ISO8601); } - if (isset($vtodo->COMPLETED)){ - $task['end'] = $vtodo->COMPLETED->getDateTime()->format(\DateTime::ISO8601); + if (isset($vtodo->DTEND)){ + $task['end'] = $vtodo->DTEND->getDateTime()->format(\DateTime::ISO8601); } if (isset($vtodo->{'LAST-MODIFIED'})) { @@ -156,29 +159,34 @@ class Taskwarrior implements IStorage { if (isset($vtodo->CATEGORIES)) { $task['tags'] = $vtodo->CATEGORIES->getJsonValue(); - } + } if (isset($vtodo->GEO)){ $task['geo'] = $vtodo->GEO->getRawMimeDirValue(); } + if ($this->configs['default_calendar'] != $displayname) { + $task['project'] = $displayname; + } + return $task; } - public function save(Calendar $c) { + public function save(Calendar $c, string $displayname) { try { if (!isset($c->VTODO)){ throw new \Exception('Calendar event does not contain VTODO'); } $this->logger->info(json_encode($c->jsonSerialize())); $this->refresh(); - $task = $this->vObjectToTask($c->VTODO); + $task = $this->vObjectToTask($c->VTODO, $displayname); $this->logger->info(json_encode($task)); $this->logger->info( sprintf('Executing TASKRC = %s TASKDATA = %s task import %s', $this->configs['taskrc'], $this->configs['taskdata'], json_encode($task)) ); $output = $this->console->execute('task', ['import'], $task, ['TASKRC' => $this->configs['taskrc'],'TASKDATA' => $this->configs['taskdata']]); + $this->refresh(); $this->logger->info($output); } catch (\Exception $e) { $this->logger->error($e->getTraceAsString()); @@ -191,7 +199,7 @@ class Taskwarrior implements IStorage { $this->logger->info(sprintf('Deleting iCal %s from taskwarrior', $uid)); $this->refresh(); if (!array_key_exists((string)$uid, $this->tasks)) { - $this->logger->warn(sprintf('Could not find task %s to delete. Skipping', (string)$uid)); + $this->logger->warn(sprintf('Could not find task %s to be remove. Skipping', (string)$uid)); return; } $task = $this->tasks[(string)$uid]; @@ -203,6 +211,7 @@ class Taskwarrior implements IStorage { $output = $this->console->execute('task', ['delete', (string)$uuid], null, ['TASKRC' => $this->configs['taskrc'],'TASKDATA' => $this->configs['taskdata']]); $this->logger->info($output); + $this->refresh(); } else if (isset($task) && $task['status'] === 'deleted') { $this->logger->warn(sprintf('Task %s has already been deleted', $task['uuid'])); } else {