X-Git-Url: https://git.madduck.net/etc/taskwarrior.git/blobdiff_plain/092349699c57d6b36346e44a80220e941033d1ca..80d39e1f7bea06adf9df0f4f6a7d12f355b3a1ad:/tasklib/serializing.py diff --git a/tasklib/serializing.py b/tasklib/serializing.py index 5d848ff..8cdeaf2 100644 --- a/tasklib/serializing.py +++ b/tasklib/serializing.py @@ -1,3 +1,17 @@ +import datetime +import importlib +import json +import pytz +import six +import tzlocal + + +from .lazy import LazyUUIDTaskSet, LazyUUIDTask + +DATE_FORMAT = '%Y%m%dT%H%M%SZ' +local_zone = tzlocal.get_localzone() + + class SerializingObject(object): """ Common ancestor for TaskResource & TaskWarriorFilter, since they both @@ -25,8 +39,8 @@ class SerializingObject(object): to raise ValueError. """ - def __init__(self, warrior): - self.warrior = warrior + def __init__(self, backend): + self.backend = backend def _deserialize(self, key, value): hydrate_func = getattr(self, 'deserialize_{0}'.format(key), @@ -155,6 +169,8 @@ class SerializingObject(object): return serialized_annotations if serialized_annotations else '' def deserialize_annotations(self, data): + task_module = importlib.import_module('tasklib.task') + TaskAnnotation = getattr(task_module, 'TaskAnnotation') return [TaskAnnotation(self, d) for d in data] if data else [] def serialize_tags(self, tags): @@ -162,17 +178,30 @@ class SerializingObject(object): def deserialize_tags(self, tags): if isinstance(tags, six.string_types): - return tags.split(',') if tags else [] - return tags or [] + return set(tags.split(',')) if tags else set() + return set(tags or []) + + def serialize_parent(self, parent): + return parent['uuid'] if parent else '' + + def deserialize_parent(self, uuid): + return LazyUUIDTask(self.backend, uuid) if uuid else None def serialize_depends(self, value): # Return the list of uuids value = value if value is not None else set() - return ','.join(task['uuid'] for task in value) + + if isinstance(value, LazyUUIDTaskSet): + return ','.join(value._uuids) + else: + return ','.join(task['uuid'] for task in value) def deserialize_depends(self, raw_uuids): raw_uuids = raw_uuids or [] # Convert None to empty list + if not raw_uuids: + return set() + # TW 2.4.4 encodes list of dependencies as a single string if type(raw_uuids) is not list: uuids = raw_uuids.split(',') @@ -180,7 +209,7 @@ class SerializingObject(object): else: uuids = raw_uuids - return set(self.warrior.tasks.get(uuid=uuid) for uuid in uuids if uuid) + return LazyUUIDTaskSet(self.backend, uuids) def datetime_normalizer(self, value): """ @@ -192,8 +221,10 @@ class SerializingObject(object): localized datetime -> localized datetime (no conversion) """ - if (isinstance(value, datetime.date) - and not isinstance(value, datetime.datetime)): + if ( + isinstance(value, datetime.date) + and not isinstance(value, datetime.datetime) + ): # Convert to local midnight value_full = datetime.datetime.combine(value, datetime.time.min) localized = local_zone.localize(value_full) @@ -205,14 +236,8 @@ class SerializingObject(object): # If the value is already localized, there is no need to change # time zone at this point. Also None is a valid value too. localized = value - elif (isinstance(value, six.string_types) - and self.warrior.version >= VERSION_2_4_0): - # For strings, use 'task calc' to evaluate the string to datetime - # available since TW 2.4.0 - args = value.split() - result = self.warrior.execute_command(['calc'] + args) - naive = datetime.datetime.strptime(result[0], DATE_FORMAT_CALC) - localized = local_zone.localize(naive) + elif isinstance(value, six.string_types): + localized = self.backend.convert_datetime_string(value) else: raise ValueError("Provided value could not be converted to " "datetime, its type is not supported: {}" @@ -227,5 +252,3 @@ class SerializingObject(object): "not: {}".format(value)) return value - -