Skip to content

Instantly share code, notes, and snippets.

@imirzadeh
Created July 17, 2020 00:24
Show Gist options
  • Save imirzadeh/530811dca0fda4208bd8fbd937c850cc to your computer and use it in GitHub Desktop.
Save imirzadeh/530811dca0fda4208bd8fbd937c850cc to your computer and use it in GitHub Desktop.
Python Script to Import tasks from Asana to Todoist
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()
@imirzadeh
Copy link
Author

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

@vikingcc
Copy link

Thanks!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment