C# Itunes export file copying code

Ok, I use Itunes since I have an Iphone – for no other reason mind you, cos it’s crap with a capital C.

Anyway, recently I had occasion to need a tool that would copy everything in a given playlist into a specific directory, so I could burn it onto a CD. My car does have iPod integration, but since I have the cheapest of the cheap OEM stereo in there, actually using playlists sucks. So I resort to the CD full of MP3′s.

Anyway, since ITunes doesn’t have this functionality built in, I whipped up a small C# program to do it. As my friend Clint Hocking points out, “You are a programmer, aren’t you? Write an app to do it!”. It’s not particularly clever – very brute force, but it works.

So what you do is export from Itunes a playlist as XML (using the export functions), then feed that playlist as well as a destination directory into this little C# console app, and it’ll copy the files required to a specific directory.

One thing it doesn’t handle are filenames with non standard characters in it. I had some in my play lists, since I listen to a lot of trance and there’s a lot of German stuff that has umlets and the like in them. Since Itunes exports the XML with the filenames with %number values in them and I couldn’t find a decent bit of code that would reconvert them back into ‘real’ text, I gave up and just renamed the original files. Not very enterprising but I didn’t have days to fiddle with this.

Anyway, here it is, in case you might find it useful. I’m sure there’s a way to get the XPATH stuff finding nodes with specific entries in the tags, but I couldn’t get it to work after playing with it, so I went brute force. Not elegant, but good enough for government work.

Remember, it’s a console app, and it’s C#.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;

namespace ItunesExportMove
{
class Program
{
static void Main(string[] args)
{
if (args.Length < 2)
{
Console.WriteLine(“Usage – ItunesExportMove.exe [itunes exported xml file] [destination directory]“);
return;
}
string dest = args[1];
if (dest.Substring(dest.Length -1, 1) != “/”)
{
dest += “/”;
}

XmlDocument doc = new XmlDocument();
doc.Load(args[0]);

XmlNodeList matches = doc.SelectNodes(“/plist/dict/dict/dict”);
int counter = 1;
int errorCount = 0;
foreach (XmlNode node in matches)
{
XmlNode nextNode = node.FirstChild;
while(nextNode != null)
{
if (nextNode.InnerText == “Location”)
{
string fileName = nextNode.NextSibling.InnerText.Substring(17, nextNode.NextSibling.InnerText.Length – 17);
fileName = fileName.Replace(“%20″, ” “);
fileName = fileName.Replace(“%5B”, “[");
fileName = fileName.Replace("%5D", "]“);
fileName = fileName.Replace(“%5D”, “]”);
FileInfo fileInfo = new FileInfo(fileName);
if (fileInfo.Exists)
{
int lastSlash = fileName.LastIndexOf(“/”) + 1;
string destFileName = dest + fileName.Substring(lastSlash, fileName.Length – lastSlash);
fileInfo.CopyTo(destFileName, true);
Console.WriteLine(“copying ” + counter + ” of ” + matches.Count + ” – ” + fileName + ” to ” + destFileName);
}
else
{
Console.WriteLine(“\nError! Couldn’t find ” + counter + ” of ” + matches.Count + ” – ” + fileName + “\n”);
errorCount++;
}
counter++;
break;
}
nextNode = nextNode.NextSibling;
}
}
if (errorCount != 0)
{
Console.WriteLine(“\nFailed ” + errorCount + ” of ” + matches.Count);
}
}
}
}

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>