Importing Tasks from .ics RTM Backup (with duplicate detection)
l.tulipan says:
Yesterday I deleted a ton of my tasks while configuring various sync-options.
Luckily I made an .ics backup as described in the help (https://www.rememberthemilk.com/help/answers/basics/backup.rtm)
Unfortunately there is no import function
In addition, not only did the .ics have some taks which were actually sitting fine and dandy inside my RTM, it also had completed tasks, which I didn't need to import. So I wrote an awk script to help me with email-import. AWK is a unix-tool, but you can install Cygwin (http://www.cygwin.com/) to get the tool in windows. You shouldn't be afraid of a command prompt and be careful: this worked for me and might not work properly for you, so always doublecheck and MAKE BACKUPS!
#### START OF SCRIPT ####
#
# Objective: restore missing RTM tasks that you have in an .ics backup
#
# Backup from webcal://www.rememberthemilk.com/icalendar/USERNAME/
# compare backup with a current .ics and extract only the tasks you inadvertently deleted
# add the tasks via email import with SmartAdd ( https://www.rememberthemilk.com/services/email/#import )
# Author: Leonard Tulipan a.k.a KnowHowBites ( know.how.bites (at) gmail . com ) http://twitter.com/khbites
#
# 2012-01-02 - Version 0.9
#
# Caveat: (1) The list (i.e. Category in Outlook) cannot be restored, as this info is not found in the current version of the ics file
# (2) Make sure there are no linebreaks in the .ics file, especially the line starting with "DESCRIPTION" for each tasks!
# I fixed this under Windows with "Notepadd++" - Search - Replace "\n " without hyphens replace with nothing - mark Extended search
# (3) For me there was a hard-limit of 50 task that I could import with one email so I did sent multiple mails
# To create the ics file:
#
#
# I had two backups: one with all the tasks, and one with some tasks missing (due to me hitting delete in RTM)
#
# sh$ sdiff -I "LAST-MODIFIED" -I DTSTAMP backup-without-the-tasks-you-want-to-add.ics the-full-backup.ics -s --strip-trailing-cr -w 500|grep ">"|cut -c 39- > missing_tasks.txt
# then call this awk file e.g.
#
# sh$ awk -f rtm-mail.awk < missing_tasks.txt > out.txt
#
# paste the output into an email body. Set the subject to a new list you created (i called mine "reimport", so I used reimport as subject to get everything into this list
# USERNAME+CODE+@rmilk.com mail address (find your personal mail address under www.rememberthemilk.com - Settings - Info - Import Email Address)
#
# do not do this from GMAIL or OUTLOOK (with GMAIL) - because of the text-wrap at 72 characters you will get a messed up import.
# yahoo mail works fine, as lines to not get wrapped there.
BEGIN { task=""; prio=""; tags=""; loc=""; due=""; est=""; url=""}
/BEGIN:VTODO/ { FS=":" }
/SUMMARY/ { task = $2 }
# Change FS for DESC FIELD
/SEQUENCE/ { FS="\\" }
/DESCRIPTION/ { cnt = split($0, arr, "\\")
note=0
for(i=1;i<=cnt;i++) {
# Find the Time Estimate Substring - put it in est, then if not none built part of Task-String with leading =
if(match(arr[i],/Time estimate: /) ){ est = sprintf( substr(arr[i],RSTART+RLENGTH)) }
if(est == "none" ) { est="" } else { if(est !~ /^ =/ && est != "") {est = sprintf (" =%s",est) }}
#Build Tags variable. Multiple Tas on different lines. Second line starts with "," - check if Tags: none
if(arr[i] !~ /Tags: none/ && match(arr[i],/Tags: /) ){ tags = sprintf( " #%s", substr(arr[i],RSTART+RLENGTH)) }
if(match(arr[i],/^, /) ){ tags = sprintf( "%s #%s", tags, substr(arr[i],RSTART+RLENGTH)) }
# Location
if(arr[i] !~ /Location: none/ && match(arr[i],/Location: /) ){ loc = sprintf( " @%s", substr(arr[i],RSTART+RLENGTH)) }
#Notes - add Text to Summary
if(match(arr[i],/---/) ) {
task = sprintf("%s -Note-",task)
note=1 }
if(note && arr[i] !~ /^n$/ && arr[i] !~ /---/) { task = sprintf("%s %s",task,substr(arr[i],2)) }
}
#printf " 1 %s\n2 %s\n3 %s\n4 %s\n5 %s\n\n6 %s\n7 %s\n8 %s\n\n", $1, $2, $3, $4, $5, $6, $7, $8;
FS=":" }
/PRIORITY:1/ { prio=" !1"}
/PRIORITY:5/ { prio=" !2"}
/PRIORITY:9/ { prio=" !3"}
/URL;VALUE=URI/ { url = sprintf(" http:%s", $3) }
/DUE;VALUE=/ { due = sprintf(" ^%s-%s-%s", substr($2,0,4), substr($2,5,2), substr($2,7,2)) }
/END:VTODO/ { FS=" "; # print task prio tags loc due est url;
print task prio tags loc due est url
task=""; prio=""; tags=""; loc=""; due=""; est=""; url=""}
#### END OF SCRIPT ####
Luckily I made an .ics backup as described in the help (https://www.rememberthemilk.com/help/answers/basics/backup.rtm)
Unfortunately there is no import function
In addition, not only did the .ics have some taks which were actually sitting fine and dandy inside my RTM, it also had completed tasks, which I didn't need to import. So I wrote an awk script to help me with email-import. AWK is a unix-tool, but you can install Cygwin (http://www.cygwin.com/) to get the tool in windows. You shouldn't be afraid of a command prompt and be careful: this worked for me and might not work properly for you, so always doublecheck and MAKE BACKUPS!
#### START OF SCRIPT ####
#
# Objective: restore missing RTM tasks that you have in an .ics backup
#
# Backup from webcal://www.rememberthemilk.com/icalendar/USERNAME/
# compare backup with a current .ics and extract only the tasks you inadvertently deleted
# add the tasks via email import with SmartAdd ( https://www.rememberthemilk.com/services/email/#import )
# Author: Leonard Tulipan a.k.a KnowHowBites ( know.how.bites (at) gmail . com ) http://twitter.com/khbites
#
# 2012-01-02 - Version 0.9
#
# Caveat: (1) The list (i.e. Category in Outlook) cannot be restored, as this info is not found in the current version of the ics file
# (2) Make sure there are no linebreaks in the .ics file, especially the line starting with "DESCRIPTION" for each tasks!
# I fixed this under Windows with "Notepadd++" - Search - Replace "\n " without hyphens replace with nothing - mark Extended search
# (3) For me there was a hard-limit of 50 task that I could import with one email so I did sent multiple mails
# To create the ics file:
#
#
# I had two backups: one with all the tasks, and one with some tasks missing (due to me hitting delete in RTM)
#
# sh$ sdiff -I "LAST-MODIFIED" -I DTSTAMP backup-without-the-tasks-you-want-to-add.ics the-full-backup.ics -s --strip-trailing-cr -w 500|grep ">"|cut -c 39- > missing_tasks.txt
# then call this awk file e.g.
#
# sh$ awk -f rtm-mail.awk < missing_tasks.txt > out.txt
#
# paste the output into an email body. Set the subject to a new list you created (i called mine "reimport", so I used reimport as subject to get everything into this list
# USERNAME+CODE+@rmilk.com mail address (find your personal mail address under www.rememberthemilk.com - Settings - Info - Import Email Address)
#
# do not do this from GMAIL or OUTLOOK (with GMAIL) - because of the text-wrap at 72 characters you will get a messed up import.
# yahoo mail works fine, as lines to not get wrapped there.
BEGIN { task=""; prio=""; tags=""; loc=""; due=""; est=""; url=""}
/BEGIN:VTODO/ { FS=":" }
/SUMMARY/ { task = $2 }
# Change FS for DESC FIELD
/SEQUENCE/ { FS="\\" }
/DESCRIPTION/ { cnt = split($0, arr, "\\")
note=0
for(i=1;i<=cnt;i++) {
# Find the Time Estimate Substring - put it in est, then if not none built part of Task-String with leading =
if(match(arr[i],/Time estimate: /) ){ est = sprintf( substr(arr[i],RSTART+RLENGTH)) }
if(est == "none" ) { est="" } else { if(est !~ /^ =/ && est != "") {est = sprintf (" =%s",est) }}
#Build Tags variable. Multiple Tas on different lines. Second line starts with "," - check if Tags: none
if(arr[i] !~ /Tags: none/ && match(arr[i],/Tags: /) ){ tags = sprintf( " #%s", substr(arr[i],RSTART+RLENGTH)) }
if(match(arr[i],/^, /) ){ tags = sprintf( "%s #%s", tags, substr(arr[i],RSTART+RLENGTH)) }
# Location
if(arr[i] !~ /Location: none/ && match(arr[i],/Location: /) ){ loc = sprintf( " @%s", substr(arr[i],RSTART+RLENGTH)) }
#Notes - add Text to Summary
if(match(arr[i],/---/) ) {
task = sprintf("%s -Note-",task)
note=1 }
if(note && arr[i] !~ /^n$/ && arr[i] !~ /---/) { task = sprintf("%s %s",task,substr(arr[i],2)) }
}
#printf " 1 %s\n2 %s\n3 %s\n4 %s\n5 %s\n\n6 %s\n7 %s\n8 %s\n\n", $1, $2, $3, $4, $5, $6, $7, $8;
FS=":" }
/PRIORITY:1/ { prio=" !1"}
/PRIORITY:5/ { prio=" !2"}
/PRIORITY:9/ { prio=" !3"}
/URL;VALUE=URI/ { url = sprintf(" http:%s", $3) }
/DUE;VALUE=/ { due = sprintf(" ^%s-%s-%s", substr($2,0,4), substr($2,5,2), substr($2,7,2)) }
/END:VTODO/ { FS=" "; # print task prio tags loc due est url;
print task prio tags loc due est url
task=""; prio=""; tags=""; loc=""; due=""; est=""; url=""}
#### END OF SCRIPT ####
Log in
to post a reply.