# are not propagated.
self._original_data = copy.deepcopy(self._data)
- def _update_data(self, data, update_original=False):
+ def _update_data(self, data, update_original=False, remove_missing=False):
"""
Low level update of the internal _data dict. Data which are coming as
updates should already be serialized. If update_original is True, the
self._data.update(dict((key, self._deserialize(key, value))
for key, value in data.items()))
+ # In certain situations, we want to treat missing keys as removals
+ if remove_missing:
+ for key in set(self._data.keys()) - set(data.keys()):
+ self._data[key] = None
+
if update_original:
self._original_data = copy.deepcopy(self._data)
"""
pass
+ class InactiveTask(Exception):
+ """
+ Raised when the operation cannot be performed on an inactive task.
+ """
+ pass
+
class NotSaved(Exception):
"""
Raised when the operation cannot be performed on the task, because
# If this is a on-modify event, we are provided with additional
# line of input, which provides updated data
if modify:
- task._update_data(json.loads(input_file.readline().strip()))
+ task._update_data(json.loads(input_file.readline().strip()),
+ remove_missing=True)
return task
# Refresh the status again, so that we have updated info stored
self.refresh(only_fields=['status', 'start'])
+ def stop(self):
+ if not self.saved:
+ raise Task.NotSaved("Task needs to be saved before it can be stopped")
+
+ # Refresh, and raise exception if task is already completed/deleted
+ self.refresh(only_fields=['status'])
+
+ if not self.active:
+ raise Task.InactiveTask("Cannot stop an inactive task")
+
+ self.warrior.execute_command([self['uuid'], 'stop'])
+
+ # Refresh the status again, so that we have updated info stored
+ self.refresh(only_fields=['status', 'start'])
+
def done(self):
if not self.saved:
raise Task.NotSaved("Task needs to be saved before it can be completed")
stdout, stderr = [x.decode('utf-8') for x in p.communicate()]
return stdout.strip('\n')
- def execute_command(self, args, config_override={}, allow_failure=True):
+ def execute_command(self, args, config_override={}, allow_failure=True,
+ return_all=False):
command_args = self._get_command_args(
args, config_override=config_override)
logger.debug(' '.join(command_args))
else:
error_msg = stdout.strip()
raise TaskWarriorException(error_msg)
- return stdout.rstrip().split('\n')
+
+ # Return all whole triplet only if explicitly asked for
+ if not return_all:
+ return stdout.rstrip().split('\n')
+ else:
+ return (stdout.rstrip().split('\n'),
+ stderr.rstrip().split('\n'),
+ p.returncode)
def enforce_recurrence(self):
# Run arbitrary report command which will trigger generation