Skip to content

Instantly share code, notes, and snippets.

@bryanph
Last active June 18, 2019 20:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryanph/fcddf602d60d7c6ecdaf6584f2db55a5 to your computer and use it in GitHub Desktop.
Save bryanph/fcddf602d60d7c6ecdaf6584f2db55a5 to your computer and use it in GitHub Desktop.
Wunderlist to Workflowy export. Go to Wunderlist web interface, backup data (JSON file), use this script and paste the output into Workflowy.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
usage:
python wunderlist2workflowy.py >> wunderlist.txt
Go to Wunderlist web interface, backup data (JSON file), use this script and paste the output into Workflowy.
"""
import json
import html
with open('wunderlist.json') as f:
wunderlist = json.load(f)['data']
print('<?xml version="1.0"?>')
print('<opml version="2.0">')
print('<body>')
for my_list in wunderlist['lists']:
print('\t<outline text="{}">'.format(html.escape(my_list['title'])))
for task_position in wunderlist['task_positions']:
if task_position['list_id'] == my_list['id']:
task_ids_list = task_position['values']
if len(task_ids_list) == 0:
for task in wunderlist['tasks']:
if task['list_id'] == my_list['id']:
task_ids_list.append(task['id'])
for task_id in task_ids_list:
for task in wunderlist['tasks']:
if task['id'] == task_id:
if 'due_date' in task:
workflowy_task = task['title'] + ' #d-' + task['due_date']
else:
workflowy_task = task['title']
node_content = None
for note in wunderlist['notes']:
if note['task_id'] == task_id:
if len(note['content']) != 0:
node_content = note['content'].strip()
if node_content:
print('\t\t<outline text="{}" _note="{}">'.format(html.escape(workflowy_task), html.escape(node_content)), end="")
else:
print('\t\t<outline text="{}" >'.format(html.escape(workflowy_task)), end="")
newline_done = False
for subtask_position in wunderlist['subtask_positions']:
if subtask_position['task_id'] == task['id']:
for subtask_id in subtask_position['values']:
for subtask in wunderlist['subtasks']:
if subtask['id'] == subtask_id:
if not newline_done:
print()
newline_done = True
print('\t\t\t<outline text="{}" />'.format(html.escape(subtask['title'])))
if newline_done:
print('\t\t</outline>')
else:
print('</outline>')
print('\t</outline>')
print('</body>')
print('</opml>')
@bryanph
Copy link
Author

bryanph commented May 17, 2017

Could be improved by also taking wunderlist list folders into account

@aenain
Copy link

aenain commented Jun 18, 2019

thanks @bryanph for sharing this :)
It was very useful! I did make a version that handles folders and maintains order of lists: https://gist.github.com/aenain/5a50e7f1c0177b35bf6afd3bf525145d
In addition it targets Dynalist as it has dynamic date labels that Workflowy lacks.

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