One strategy is to just let Apple do it, but I don't trust them.
The next idea is to manually copy all 500 songs to a backup disk. This would be easy, except that (i) I don't want the whole library, just a playlist, and (ii) iTunes uses nested folders to preserve the artist:album:songtitle information. I need to merge u/v/w with u/v/x to create a directory u/v containing both w and x. You can't do that just copying x.
The playlist info is contained in xml format, file: 'iTunes Music Library.xml' but I decided to export the playlist to disk from within iTunes ('File > Library > Export Playlist...'). Each entry in the exported text file ends with something like this as the last field (tab-separated, one entry per line):
HD:Users:Shared:iTunes Music:Bob Marley:Natty Dread:01 Lively Up Yourself.m4a
The following script finds each song on the playlist and copies it to a directory temp in the directory where the script is run. Simple. The result is 3.77 GB of .m4a files with the desired directory structure.
A detail that is (or should be) embarassing: iTunes (on OS X) uses '\r' (CR) as newline. Talk about the constraints of backward compatibility.
One last thing: please, please, please back-up and test before using this. YMMV. Caveat lector. No warranty express or implied. Don't blame me if your library vanishes.
import os, subprocess
name = 'playlist'
FH = open(name + '.txt', 'r')
data = FH.read().strip()
FH.close()
# iTunes uses '\r' (CR) as newline!
data = data.split('\r')
# data[0] is metadata (column names)
data.pop(0)
# file path is the last value
L = [item.split('\t')[-1] for item in data]
# ':' is path separator
L = [item.replace(':','/') for item in L]
for item in L:
# remove HD name from file path
item = item.split('/', 1)[1]
# file path has spaces
# must be quoted for shell command below
src = '"/' + item + '"'
artist, album, songfile = item.split('/')[-3:]
# construct directory tree if it doesn't exist
path = '/'.join(('temp', artist, album))
try:
os.stat(path)
except OSError:
os.makedirs(path)
dst = '"' + '/'.join((path, songfile)) + '"'
cmd = ' '.join(('cp', src, dst))
obj = subprocess.call(cmd,shell=True)
if obj != 0:
print 'e',
else:
print '*',
print dst
|