Created
July 17, 2020 00:24
-
-
Save imirzadeh/530811dca0fda4208bd8fbd937c850cc to your computer and use it in GitHub Desktop.
Python Script to Import tasks from Asana to Todoist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd | |
from todoist.api import TodoistAPI | |
ASANA_TASKS_CSV_PATH = './asana.csv' | |
# creates this project and import all tasks from asana csv file to this project in todoist | |
TODOIST_PROJECT_NAME = 'Asana Imports' | |
TODOIST_TOKEN = 'REPLACE_YOUR_TODOIST_TOKEN' | |
# read asana tasks | |
asana_tasks = pd.read_csv(ASANA_TASKS_CSV_PATH) | |
# create todoist | |
todoist = TodoistAPI(TODOIST_TOKEN) | |
todoist.sync() | |
def should_import(task_info: dict) -> bool: | |
""" | |
Given a task info, should I filter the task? (i.e., not import the task?) | |
You can add your desired conditions here. | |
""" | |
# if task is completed or has empty name, don't import it | |
if pd.notnull(task_info['Completed At']) or pd.isnull(task_info['Name']) or not task_info['Name'].strip(): | |
return False | |
else: | |
return True | |
def import_asana_tasks(project_id): | |
cnt = 0 | |
for task in asana_tasks.iterrows(): | |
try: | |
task_info = dict(task[1]) | |
if should_import(task_info): | |
task_name = task_info['Name'].strip() | |
task_due = task_info['Due Date'] if pd.notnull(task_info['Due Date']) else None | |
task_notes = task_info['Notes'] if pd.notnull(task_info['Notes']) else '' | |
todoist_task = todoist.items.add(content=task_name, project_id=project_id) | |
comment = todoist.notes.add(todoist_task['id'], task_notes) | |
if cnt % 20 == 0 or cnt > 80: | |
todoist.commit() | |
cnt += 1 | |
except Exception as exp: | |
print("Exception occured for this task: {}".format(task_info)) | |
print("Exception details => {}".format(exp)) | |
print("**"*20) | |
def create_project_in_todoist(): | |
""" | |
Creates a project for you in todoist an import all tasks | |
From asana automatically | |
""" | |
todoist.projects.add(TODOIST_PROJECT_NAME) | |
project_id = todoist.commit()['projects'][0]['id'] | |
return project_id | |
target_project_id = create_project_in_todoist() | |
import_asana_tasks(target_project_id) | |
todoist.commit() |
In case you need to add by sections:
def should_import(task_info: dict) -> bool:
"""
Given a task info, should I filter the task? (i.e., not import the task?)
You can add your desired conditions here.
"""
# if task is completed or has empty name, don't import it
if pd.notnull(task_info['Completed At']) or pd.isnull(task_info['Section/Column'])\
or pd.isnull(task_info['Name']) or not task_info['Name'].strip():
return False
else:
return True
def import_asana_tasks(project_id):
cnt = 0
sections = {}
for task in asana_tasks.iterrows():
try:
task_info = dict(task[1])
if should_import(task_info):
task_name = task_info['Name'].strip()
task_due = task_info['Due Date'] if pd.notnull(task_info['Due Date']) else None
task_notes = task_info['Notes'] if pd.notnull(task_info['Notes']) else ''
task_section = task_info['Section/Column']
print("section >> {}".format(task_section))
if not task_section in sections:
section = todoist.sections.add(task_section, project_id=project_id)
todoist.commit()
sections[task_section] = section['id']
todoist_task = todoist.items.add(content=task_name, section_id=sections[task_section], project_id=project_id)
comment = todoist.notes.add(todoist_task['id'], task_notes)
todoist.commit()
print("Imported", task_info['Name'])
except Exception as exp:
print("Exception occured for this task: {}".format(task['Name']))
print("Exception details => {}".format(exp))
print("**"*20)
continue
Thanks!!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You need to export the Asana tasks to a CSV file.
Additionally, you'll need to install pandas and Todoist python client.
The result: