Googletasks

De WikiMar
Dreceres ràpides: navegació, cerca

How to export from Google Tasks (.json) to (.opml) dynalist.io or checkvist.com or workflowy.com

Export tasks using:

https://tasks-backup.appspot.com/progress

Select:

Import/Export CSV   (CSV file containing just the data required to recreate tasks: #0"tasklist_name",1"title",2"notes",3"status",4"due",5"completed",6"deleted",7"hidden",8depth)

You will get a tasks_import_export_XXXX@XXXX_2019-xx-xx.csv


Export tasks using Google Takeout to get a Tasks.json file


Run script partone.py:

python3 partone.py > exportpartone.opml


Run script addemaillinks.py:

python3 addemaillinks.py > exportwithemaillinks.opml


Import exportwithemaillinks.opml to dynalist.io or checkvist.com or workflowy.com etc.


I tested the three and I at the moment I prefer Dynalist. You can use it free, but if you want to upgrade later better use already now the special link https://dynalist.io/invite/Ik35cw to create your account so that you get also at least one month free if you later wanted to get Premium.


Python scripts:


partone.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
usage:
    python3 partone.py > exportpartone.opml
    Use as input the 'Import/Export CSV' export from https://tasks-backup.appspot.com/progress

"""

import html

#import json
#with open('Tasks.json') as f:
#    wunderlist = json.load(f)['items']

print('<?xml version="1.0"?>')
print('<opml version="2.0">')
print('<body>')
#0"tasklist_name",1"title",2"notes",3"status",4"due",5"completed",6"deleted",7"hidden",8depth

lastdepth = 0
lastlist = ''
import csv 

with open('tasks_import_export_XXXX@XXX_2019-xx-xx.csv','rt', encoding='utf8') as csvfile: 
	reader = csv.reader(csvfile, delimiter=',', quotechar='"') 
	for row in reader:
		
		if row[0] == 'tasklist_name':
			continue
		
		if lastlist != row[0]:
			if lastlist != '':
				while 0 <= lastdepth:
					print(('\t' * lastdepth) + '</outline>')
					lastdepth -= 1
			print('<outline text="{}">'.format(html.escape(row[0])))
			lastlist = row[0]
			lastdepth = 0
			
		newdepth = 1
		try:
			newdepth = int(row[8]) + 1
		except ValueError:
			pass      # or whatever
		if newdepth < 1:  # a vegades hi ha num  negatius a depth
			newdepth = 1
			
		while newdepth <= lastdepth:
			print(('\t' * lastdepth) + '</outline>')
			lastdepth -= 1
		
		#if newdepth == lastdepth:
		#	print(('\t' * lastdepth) + '</outline>')
		
		#for i in range(newdepth):
		#	tabs = tabs + '\t'
		tabs = '\t' * newdepth
		
		notestrtmp = ''
		if row[2] != '':
			notestrtmp = html.escape(row[2]).replace('\\n','&#10;')
			
		completedstr = ''
		if row[3] == "completed":
			completedstr = ' complete="true"'
				
		duestr = ''
		if row[4] != '':
			duestr = ' !( ' + row[4] + ' )'
			
		if row[5] != '':
			if notestrtmp != '':
				 notestrtmp += ' &#10;'; # canvi linia
			notestrtmp += '#completed: ' + row[5]

		if row[6] != '':
			if notestrtmp != '':
				 notestrtmp += ' &#10;'; # canvi linia
			notestrtmp += '#deleted'
			completedstr = ' complete="true"'
		
		if row[7] != '':
			if notestrtmp != '':
				notestrtmp += ' &#10;'; # canvi linia
			notestrtmp += '#hidden'
			completedstr = ' complete="true"'
				
		notestr = ''
		if notestrtmp != '':
			notestr = ' _note="' + notestrtmp + '"'
		
		titlestr = html.escape(row[1]).replace('\\n','&#10;')
		if titlestr == '':
			titlestr = ' '
		print('{}<outline text="{}{}"{}{}>'.format(tabs, titlestr, duestr, notestr, completedstr))
		lastdepth = newdepth
		#add data to list or other data structure

	print('\t</outline>')
	print('</outline>')

print('</body>')
print('</opml>')

addemaillinks.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
usage:
    python3 addemaillinks.py > exportwithemaillinks.opml
    Use as input the output from partone.py to generate a OPML compatible with dynalist.io or checkvist.com or workflowy.com.
"""
import json
import html

with open('Tasks.json') as f:
    wunderlist = json.load(f)

with open("sortida11.txt.opml", "r") as ins:
    opmlcontent = []
    for line in ins:
        opmlcontent.append(line)	
	
	
#print('<?xml version="1.0"?>')
#print('<opml version="2.0">')
#print('<body>')

for my_list in wunderlist['items']:
	#print('\t<outline text="{}">'.format(html.escape(my_list['title'])))

	for task in my_list['items']:
		#print('\t\t<outline text="{}">'.format(html.escape(task['title'])))
		duemsg = ''
		if 'due' in task:
			duemsg = ' !("{}")'.format(html.escape(task['due']))

		if 'links' in task:
			for i in range(len(opmlcontent)):
				if html.escape(task['title']) in opmlcontent[i]:
					#print('1' + task['links'][0]['link'])
					#print('2' + opmlcontent[i])
					linkstr = ' [#LinkEmail](' + task['links'][0]['link'] + ')'
					if linkstr not in opmlcontent[i]: 
						opmlcontent[i]=opmlcontent[i].replace(html.escape(task['title']), html.escape(task['title']) + linkstr, 1)
					#print('3' + opmlcontent[i])			

for i in range(len(opmlcontent)):
	print(opmlcontent[i], end="")

#print('</body>')
#print('</opml>')