I had a lot of notes in Chandler, but I’ve started using Evernote for that kind of thing so I wanted to move them all so I only had to look in one place. Nice as they both are, getting data into and out of them is quite a pain. In the end I exported from Chandler to an ICS file (the only portable format it can export to, as far as I can tell). Then I converted that to RDF using ical2Rdf. Then I patched up the XML by hand to include the last edit date for the task (the closest I could get to the creation date). Then I wrote a program to add each ICS entry to Evernote using ENScript. It’s great that they provide that tool, but it fails silently if you give it an empty text file for the description field. (It fails not so silently if you give it a text file without the .txt extension, but as long as it gives an error I can deal with it.) So, here’s the source code for the program. It’s a nasty hack of a program, but I only had to get one successful run out of it so I’m not overly bothered. It might help someone else in the same boat. No, you can’t ask me for support for this. I’ve already spent too long at this and I never want to see it again. You’re on your own, take backups, and don’t come crying to me if this deletes anything or everything. Good luck! Code Snippet - namespace EvernoteIcalImport
- {
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Xml.Linq;
-
- class Program
- {
- private static readonly XNamespace IcalNamespace = "http://www.w3.org/2002/12/cal/ical#";
-
- private static int _counter = 0;
-
- static void Main ()
- {
- XDocument toImport = XDocument.Load (@"..\..\ToImport.xml");
- var document = toImport.Document;
- var events = document.Descendants (IcalNamespace + "Vevent");
- ProcessItem (events);
-
- var todo = document.Descendants (IcalNamespace + "Vtodo");
- ProcessItem (todo);
-
- Console.In.ReadLine ();
-
- return;
- }
-
- private static void ProcessItem (IEnumerable<XElement> items)
- {
- foreach (var element in items)
- {
- string summaryText = "";
- var summary = element.Element (IcalNamespace + "summary");
- if (summary != null)
- {
- summaryText = summary.Value;
- }
-
- string descriptionText = "";
- var description = element.Element (IcalNamespace + "description");
- if (description != null)
- {
- descriptionText = description.Value;
- }
-
- string statusText = "";
- var status = element.Element (IcalNamespace + "status");
- if (status != null)
- {
- statusText = status.Value;
- }
-
- var createdElement = element.Descendants (IcalNamespace + "date").First ();
- DateTimeOffset created = DateTimeOffset.Parse (createdElement.Value);
-
- Import (summaryText, descriptionText, created, statusText);
- }
- }
-
- private static void Import (string title, string description, DateTimeOffset created, string tag)
- {
- string arguments = string.Format ("createNote /n \"Chandler Import\" /t \"{0}\" /c \"{1}\" /i \"{2}\"", tag, created.ToString ("yyyy/MM/dd hh:mm:ss"), title);
- _counter++;
- Console.Out.WriteLine ("Arguments[{0}]: {1}", _counter, arguments);
-
- var startInfo = new ProcessStartInfo (@"C:\Program Files (x86)\Evernote\ENScript.exe", arguments)
- {
- UseShellExecute = false,
- RedirectStandardInput = true,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- CreateNoWindow = true
- };
-
- var process = Process.Start (startInfo);
-
- if (string.IsNullOrEmpty (description))
- {
- description = "Empty import";
- }
-
- process.StandardInput.Write (description);
- process.StandardInput.Flush ();
- process.StandardInput.Close ();
-
- process.WaitForExit ();
-
- string output = process.StandardOutput.ReadToEnd ();
- Console.Out.WriteLine ("Output:");
- Console.Out.WriteLine (output);
-
- string error = process.StandardError.ReadToEnd ();
- Console.Out.WriteLine ("Errors:");
- Console.Out.WriteLine (error);
- if (!string.IsNullOrEmpty (error))
- {
- Console.In.ReadLine ();
- }
-
- return;
- }
- }
- }
Categories: .NET Permalink #.Posted by 'geoff' on Wednesday, 30 December 2009 at 4:42PM
|