Prevent reimporting duplicate tasks using a Taskwarrior UDA

Taskwarrior's User Defined Attributes (see link below) allow us to define custom
data attributes for tasks. We can use this to store the ID from Todoist to
prevent reimporting a task in subsequent runs.

https://taskwarrior.org/docs/udas.html
This commit is contained in:
Matt Snider 2019-01-21 21:17:38 +01:00
parent a2cb6b7887
commit 9b9a310c0f
2 changed files with 32 additions and 12 deletions

View File

@ -1,6 +1,4 @@
# TODO: # TODO:
* [ ] Prevent duplicates using Todoist ID
* e.g. `taskwarrior.filter_tasks({'todoistid.not': '...'})`
* [ ] Support `start`, `until` and `for` * [ ] Support `start`, `until` and `for`
* Don't do within recur parsing, reparse whole string * Don't do within recur parsing, reparse whole string
* https://get.todoist.help/hc/en-us/articles/360000636289 * https://get.todoist.help/hc/en-us/articles/360000636289

View File

@ -9,7 +9,6 @@ from . import utils
todoist = None todoist = None
taskwarrior = None taskwarrior = None
""" CLI Commands """ """ CLI Commands """
@click.group() @click.group()
@ -30,8 +29,8 @@ def migrate(interactive, no_sync):
important(f'Starting migration of {len(tasks)}...\n') important(f'Starting migration of {len(tasks)}...\n')
for idx, task in enumerate(tasks): for idx, task in enumerate(tasks):
data = {} data = {}
data['tid'] = task['id'] tid = data['tid'] = task['id']
data['name'] = task['content'] name = data['name'] = task['content']
data['project'] = todoist.projects.get_by_id(task['project_id'])['name'] data['project'] = todoist.projects.get_by_id(task['project_id'])['name']
data['priority'] = utils.parse_priority(task['priority']) data['priority'] = utils.parse_priority(task['priority'])
data['tags'] = [ data['tags'] = [
@ -42,10 +41,20 @@ def migrate(interactive, no_sync):
data['due'] = utils.parse_date(task['due_date_utc']) data['due'] = utils.parse_date(task['due_date_utc'])
data['recur'] = utils.parse_recur(task['date_string']) data['recur'] = utils.parse_recur(task['date_string'])
if not interactive: important(f'Task {idx + 1} of {len(tasks)}: {name}\n')
if check_task_exists(tid):
info(f'Already exists (todoist_id={tid})\n')
elif not interactive:
add_task(**data) add_task(**data)
else: else:
task_prompt(idx + 1, len(tasks), **data) task_prompt(**data)
def check_task_exists(tid):
""" Given a Taskwarrior ID, check if the task exists """
taskwarrior_id, _ = taskwarrior.get_task(todoist_id=tid)
return taskwarrior_id is not None
def add_task(tid, name, project, tags, priority, entry, due, recur): def add_task(tid, name, project, tags, priority, entry, due, recur):
@ -55,8 +64,16 @@ def add_task(tid, name, project, tags, priority, entry, due, recur):
""" """
info(f"Importing '{name}' ({project}) - ", nl=False) info(f"Importing '{name}' ({project}) - ", nl=False)
try: try:
tw_task = taskwarrior.task_add(name, project=project, tags=tags, tw_task = taskwarrior.task_add(
priority=priority, entry=entry, due=due, recur=recur) name,
project=project,
tags=tags,
priority=priority,
entry=entry,
due=due,
recur=recur,
todoist_id=tid,
)
except: except:
error('FAILED') error('FAILED')
else: else:
@ -64,7 +81,7 @@ def add_task(tid, name, project, tags, priority, entry, due, recur):
return tw_task return tw_task
def task_prompt(task_num, tasks_total, **task_data): def task_prompt(**task_data):
"""Interactively add tasks """Interactively add tasks
y - add task y - add task
@ -102,7 +119,6 @@ def task_prompt(task_num, tasks_total, **task_data):
response = None response = None
while response not in ('y', 'n'): while response not in ('y', 'n'):
click.echo(important_msg(f'Task {task_num} of {tasks_total}'))
prompt_text = ( prompt_text = (
stringify_task(**task_data) stringify_task(**task_data)
+ important_msg(f"\nImport this task?") + important_msg(f"\nImport this task?")
@ -196,6 +212,12 @@ if __name__ == '__main__':
exit('TODOIST_API_KEY environment variable not specified. Exiting.') exit('TODOIST_API_KEY environment variable not specified. Exiting.')
todoist = TodoistAPI(todoist_api_key) todoist = TodoistAPI(todoist_api_key)
taskwarrior = TaskWarrior()
# Create the TaskWarrior client, overriding config to
# create a `todoist_id` field which we'll use to
# prevent duplicates
taskwarrior = TaskWarrior(config_overrides={
'uda.todoist_id.type': 'string',
})
cli() cli()