def test_task_hashes(): essential_fields = ['content', 'tags'] t1 = task(content='A') t2 = task(content='B', tags=None) t3 = task(content='B', tags=[]) assert get_hash(t1, essential_fields) != get_hash(t2, essential_fields) assert get_hash(t2, essential_fields) == get_hash(t3, essential_fields)
def test_get_hash_essential_fields(): id2 = task(content='foo', indent=2) id3 = task(content='foo', indent=3) assert get_hash(id2, essential_fields=['content']) == get_hash( id3, essential_fields=['content']) assert get_hash(id2, essential_fields=['content', 'indent']) != get_hash( id3, essential_fields=['content', 'indent'])
def test_bridge_updates_tasks(td, gh, bridge): # add the task, and then update it bridge.push_task(td, 1, task(content='foo')) bridge.push_task(td, 1, task(content='bar')) # make sure "gh" has everything in sync gh_id = ItemMapping.objects.bridge_get(bridge, left_id=1).right_id obj = gh.storage[gh_id] assert obj.content == 'bar'
def test_bridge_passes_tasks_through(td, gh, bridge): # add a task to the adapter foo = task(content='foo') bridge.push_task(td, 1, foo) # check how id mapping works mapping = ItemMapping.objects.bridge_get(bridge, left_id=1) assert mapping.left_hash == get_hash(foo, essential_fields=TASK_FIELDS) assert mapping.left_id == '1' assert gh.storage[mapping.right_id] == foo
def task_from_data(self, data, extra): """ Take an evernote Note and return a new generic task. data is an evernote Note instance If evernote note doesn't have to be synchronized with Todoist, return None. """ if not data.attributes.reminderOrder: return None note_url = utils.get_note_url(data) content = "%s (%s)" % (note_url, data.title) item_order = REMINDER_BASE_TIME - data.attributes.reminderOrder if item_order < 1: item_order = 1 if data.attributes.reminderTime is None: due_date = None date_string = None else: user = self.bridge.integration.user user_timezone = user.get_timezone() due_date = datetime.datetime.fromtimestamp(data.attributes.reminderTime / 1000) local_due_date = user_timezone.normalize(pytz.utc.localize(due_date)) date_string = local_due_date.strftime("%d %b %Y at %H:%M") logger.debug( "Timezone dance. Convert %s from UTC to %s, get %s", data.attributes.reminderTime, user_timezone.zone, date_string, ) # we don't want to overwrite "Todoist rich date strings" original_due_date = extra.get("original_due_date") if due_date == original_due_date: logger.debug("Due date was not changed. Don't update the date") date_string = undefined due_date = undefined else: logger.debug("Due date changed from %s to %s. Update the date" % (original_due_date, due_date)) return task( checked=data.attributes.reminderDoneTime is not None, content=content, item_order=item_order, due_date=due_date, date_string=date_string, )
def task_from_data(self, data, extra): """ Take an evernote Note and return a new generic task. data is an evernote Note instance If evernote note doesn't have to be synchronized with Todoist, return None. """ if not data.attributes.reminderOrder: return None note_url = utils.get_note_url(data) content = '%s (%s)' % (note_url, data.title) item_order = REMINDER_BASE_TIME - data.attributes.reminderOrder if item_order < 1: item_order = 1 if data.attributes.reminderTime is None: due_date = None date_string = None else: user = self.bridge.integration.user user_timezone = user.get_timezone() due_date = datetime.datetime.fromtimestamp( data.attributes.reminderTime / 1000) local_due_date = user_timezone.normalize( pytz.utc.localize(due_date)) date_string = local_due_date.strftime('%d %b %Y at %H:%M') logger.debug('Timezone dance. Convert %s from UTC to %s, get %s', data.attributes.reminderTime, user_timezone.zone, date_string) # we don't want to overwrite "Todoist rich date strings" original_due_date = extra.get('original_due_date') if due_date == original_due_date: logger.debug( 'Due date was not changed. Don\'t update the date') date_string = undefined due_date = undefined else: logger.debug( 'Due date changed from %s to %s. Update the date' % (original_due_date, due_date)) return task(checked=data.attributes.reminderDoneTime is not None, content=content, item_order=item_order, due_date=due_date, date_string=date_string)
def test_bridge_deletes_tasks(td, gh, bridge): # add the task foo = task(content='foo') bridge.push_task(td, 1, foo) # make sure it's there assert ItemMapping.objects.bridge_get(bridge, left_id=1).right_id in gh.storage # delete the task bridge.delete_task(td, 1) # make sure the task isn't there anymore assert gh.storage == {}
def task_from_data(self, data, extra): """ Take a Todoist item (as data) and return a new generic task. "Extra" is not used. """ return task(checked=data['checked'], content=data['content'], date_string=data['date_string'], due_date=data['due_date'], in_history=data['in_history'], indent=data['indent'], item_order=data['item_order'], priority=data['priority'], tags=None)
def task_from_data(self, data, extra): """ We sync back only due_date and date_string. """ if isinstance(data, Task): # if it's a task object, we don't have to convert anything # we use it to delete the task return data try: gcal_due_date = parse_date(data['start']['dateTime']) except (KeyError, ValueError): # an event without a due date (whole day event maybe). Skip return # if the task is new, we should fill in the content if not extra: plaintext = data.get('summary') or 'Google Calendar event' backlink = data['htmlLink'] content = '%s (%s)' % (backlink, plaintext) else: content = undefined # sync due date and date string, but # don't overwrite "Todoist rich date strings" due_date_utc = gcal_due_date.astimezone(pytz.utc) user_timezone = self.bridge.integration.user.get_timezone() local_due_date = gcal_due_date.astimezone(user_timezone) date_string = local_due_date.strftime('%d %b %Y at %H:%M') original_due_date = extra.get('original_due_date') if due_date_utc.replace(tzinfo=None) == original_due_date: due_date_utc = undefined date_string = undefined return task(content=content, due_date=due_date_utc, date_string=date_string)
def test_get_hash_essential_fields(): id2 = task(content='foo', indent=2) id3 = task(content='foo', indent=3) assert get_hash(id2, essential_fields=['content']) == get_hash(id3, essential_fields=['content']) assert get_hash(id2, essential_fields=['content', 'indent']) != get_hash(id3, essential_fields=['content', 'indent'])
def on_gcal_event_deleted(sender, integration=None, event_id=None, **kwargs): bridge = sync_adapter.get_bridge_by_event_id(integration, event_id) # we don't delete task, but instead we mark the task as "checked" bridge.push_task(bridge.right, event_id, task(checked=True, in_history=True))
def test_essential_fields(td, dumb, dumb_bridge): dumb_bridge.push_task(td, 1, task(content='foo', indent=2)) mapping = ItemMapping.objects.bridge_get(dumb_bridge, left_id=1) assert mapping.left_hash != mapping.right_hash