X-Git-Url: https://git.madduck.net/etc/taskwarrior.git/blobdiff_plain/bdd4d32840e153c25649dcec4a692836fe7b4e75..9a7dac4599f198c52f268ae8bcc0267743ef934f:/tasklib/task.py?ds=sidebyside diff --git a/tasklib/task.py b/tasklib/task.py index f30cc61..20bff1f 100644 --- a/tasklib/task.py +++ b/tasklib/task.py @@ -13,6 +13,9 @@ DATE_FORMAT = '%Y%m%dT%H%M%SZ' REPR_OUTPUT_SIZE = 10 PENDING = 'pending' COMPLETED = 'completed' +DELETED = 'deleted' +WAITING = 'waiting' +RECURRING = 'recurring' logger = logging.getLogger(__name__) @@ -38,6 +41,11 @@ class ReadOnlyDictView(object): def __len__(self): return len(self.viewed_dict) + def __unicode__(self): + return six.u('ReadOnlyDictView: {0}'.format(repr(self.viewed_dict))) + + __repr__ = __unicode__ + def get(self, key, default=None): return copy.deepcopy(self.viewed_dict.get(key, default)) @@ -160,6 +168,9 @@ class TaskAnnotation(TaskResource): # their data dics are the same return self.task == other.task and self._data == other._data + def __ne__(self, other): + return not self.__eq__(other) + __repr__ = __unicode__ @@ -272,6 +283,9 @@ class Task(TaskResource): # If the tasks are not saved, compare the actual instances return id(self) == id(other) + def __ne__(self, other): + return not self.__eq__(other) + def __hash__(self): if self['uuid']: # For saved Tasks, just define equality by equality of uuids @@ -296,6 +310,10 @@ class Task(TaskResource): def pending(self): return self['status'] == six.text_type('pending') + @property + def recurring(self): + return self['status'] == six.text_type('recurring') + @property def active(self): return self['start'] is not None @@ -308,20 +326,24 @@ class Task(TaskResource): # Check that all the tasks are saved for task in (cur_dependencies or set()): if not task.saved: - raise Task.NotSaved('Task \'%s\' needs to be saved before ' - 'it can be set as dependency.' % task) + raise Task.NotSaved( + 'Task \'%s\' needs to be saved before ' + 'it can be set as dependency.' % task, + ) return super(Task, self).serialize_depends(cur_dependencies) def delete(self): if not self.saved: - raise Task.NotSaved("Task needs to be saved before it can be deleted") + raise Task.NotSaved( + 'Task needs to be saved before it can be deleted', + ) # Refresh the status, and raise exception if the task is deleted self.refresh(only_fields=['status']) if self.deleted: - raise Task.DeletedTask("Task was already deleted") + raise Task.DeletedTask('Task was already deleted') self.backend.delete_task(self) @@ -330,17 +352,19 @@ class Task(TaskResource): def start(self): if not self.saved: - raise Task.NotSaved("Task needs to be saved before it can be started") + raise Task.NotSaved( + 'Task needs to be saved before it can be started', + ) # Refresh, and raise exception if task is already completed/deleted self.refresh(only_fields=['status']) if self.completed: - raise Task.CompletedTask("Cannot start a completed task") + raise Task.CompletedTask('Cannot start a completed task') elif self.deleted: - raise Task.DeletedTask("Deleted task cannot be started") + raise Task.DeletedTask('Deleted task cannot be started') elif self.active: - raise Task.ActiveTask("Task is already active") + raise Task.ActiveTask('Task is already active') self.backend.start_task(self) @@ -349,13 +373,15 @@ class Task(TaskResource): def stop(self): if not self.saved: - raise Task.NotSaved("Task needs to be saved before it can be stopped") + 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") + raise Task.InactiveTask('Cannot stop an inactive task') self.backend.stop_task(self) @@ -364,15 +390,17 @@ class Task(TaskResource): def done(self): if not self.saved: - raise Task.NotSaved("Task needs to be saved before it can be completed") + raise Task.NotSaved( + 'Task needs to be saved before it can be completed', + ) # Refresh, and raise exception if task is already completed/deleted self.refresh(only_fields=['status']) if self.completed: - raise Task.CompletedTask("Cannot complete a completed task") + raise Task.CompletedTask('Cannot complete a completed task') elif self.deleted: - raise Task.DeletedTask("Deleted task cannot be completed") + raise Task.DeletedTask('Deleted task cannot be completed') self.backend.complete_task(self) @@ -388,14 +416,14 @@ class Task(TaskResource): def add_annotation(self, annotation): if not self.saved: - raise Task.NotSaved("Task needs to be saved to add annotation") + raise Task.NotSaved('Task needs to be saved to add annotation') self.backend.annotate_task(self, annotation) self.refresh(only_fields=['annotations']) def remove_annotation(self, annotation): if not self.saved: - raise Task.NotSaved("Task needs to be saved to remove annotation") + raise Task.NotSaved('Task needs to be saved to remove annotation') if isinstance(annotation, TaskAnnotation): annotation = annotation['description'] @@ -406,13 +434,14 @@ class Task(TaskResource): def refresh(self, only_fields=None, after_save=False): # Raise error when trying to refresh a task that has not been saved if not self.saved: - raise Task.NotSaved("Task needs to be saved to be refreshed") + raise Task.NotSaved('Task needs to be saved to be refreshed') new_data = self.backend.refresh_task(self, after_save=after_save) if only_fields: to_update = dict( - [(k, new_data.get(k)) for k in only_fields]) + [(k, new_data.get(k)) for k in only_fields], + ) self._update_data(to_update, update_original=True) else: self._load_data(new_data) @@ -443,7 +472,7 @@ class TaskQuerySet(object): def __repr__(self): data = list(self[:REPR_OUTPUT_SIZE + 1]) if len(data) > REPR_OUTPUT_SIZE: - data[-1] = "...(remaining elements truncated)..." + data[-1] = '...(remaining elements truncated)...' return repr(data) def __len__(self): @@ -499,6 +528,15 @@ class TaskQuerySet(object): def completed(self): return self.filter(status=COMPLETED) + def deleted(self): + return self.filter(status=DELETED) + + def waiting(self): + return self.filter(status=WAITING) + + def recurring(self): + return self.filter(status=RECURRING) + def filter(self, *args, **kwargs): """ Returns a new TaskQuerySet with the given filters added. @@ -522,7 +560,9 @@ class TaskQuerySet(object): if not num: raise Task.DoesNotExist( 'Task matching query does not exist. ' - 'Lookup parameters were {0}'.format(kwargs)) + 'Lookup parameters were {0}'.format(kwargs), + ) raise ValueError( 'get() returned more than one Task -- it returned {0}! ' - 'Lookup parameters were {1}'.format(num, kwargs)) + 'Lookup parameters were {1}'.format(num, kwargs), + )