X-Git-Url: https://git.madduck.net/etc/taskwarrior.git/blobdiff_plain/7283e46db89585fc87bad242e97d81b9f9e0fc88..42baab3573bc84a4663c538afb0280787db952f1:/tasklib/task.py diff --git a/tasklib/task.py b/tasklib/task.py index fad13bd..ba95662 100644 --- a/tasklib/task.py +++ b/tasklib/task.py @@ -5,6 +5,7 @@ import json import logging import os import pytz +import re import six import sys import subprocess @@ -236,8 +237,15 @@ class SerializingObject(object): return ','.join(task['uuid'] for task in value) def deserialize_depends(self, raw_uuids): - raw_uuids = raw_uuids or '' # Convert None to empty string - uuids = raw_uuids.split(',') + raw_uuids = raw_uuids or [] # Convert None to empty list + + # TW 2.4.4 encodes list of dependencies as a single string + if type(raw_uuids) is not list: + uuids = raw_uuids.split(',') + # TW 2.4.5 and later exports them as a list, no conversion needed + else: + uuids = raw_uuids + return set(self.warrior.tasks.get(uuid=uuid) for uuid in uuids if uuid) def datetime_normalizer(self, value): @@ -421,6 +429,12 @@ class Task(TaskResource): """ pass + class ActiveTask(Exception): + """ + Raised when the operation cannot be performed on the active task. + """ + pass + class InactiveTask(Exception): """ Raised when the operation cannot be performed on an inactive task. @@ -600,6 +614,8 @@ class Task(TaskResource): raise Task.CompletedTask("Cannot start a completed task") elif self.deleted: raise Task.DeletedTask("Deleted task cannot be started") + elif self.active: + raise Task.ActiveTask("Task is already active") self.warrior.execute_command([self['uuid'], 'start']) @@ -633,6 +649,10 @@ class Task(TaskResource): elif self.deleted: raise Task.DeletedTask("Deleted task cannot be completed") + # Older versions of TW do not stop active task at completion + if self.warrior.version < VERSION_2_4_0 and self.active: + self.stop() + self.warrior.execute_command([self['uuid'], 'done']) # Refresh the status again, so that we have updated info stored @@ -906,6 +926,10 @@ class TaskWarrior(object): 'confirmation': 'no', 'dependency.confirmation': 'no', # See TW-1483 or taskrc man page 'recurrence.confirmation': 'no', # Necessary for modifying R tasks + + # Defaults to on since 2.4.5, we expect off during parsing + 'json.array': 'off', + # 2.4.3 onwards supports 0 as infite bulk, otherwise set just # arbitrary big number which is likely to be large enough 'bulk': 0 if self.version >= VERSION_2_4_3 else 100000, @@ -937,6 +961,22 @@ class TaskWarrior(object): stdout, stderr = [x.decode('utf-8') for x in p.communicate()] return stdout.strip('\n') + def get_config(self): + raw_output = self.execute_command( + ['show'], + config_override={'verbose': 'nothing'} + ) + + config = dict() + config_regex = re.compile(r'^(?P[^\s]+)\s+(?P[^\s].+$)') + + for line in raw_output: + match = config_regex.match(line) + if match: + config[match.group('key')] = match.group('value').strip() + + return config + def execute_command(self, args, config_override={}, allow_failure=True, return_all=False): command_args = self._get_command_args(