############################################################################### # # itunes_ipod_playlist_to_itunes.pl # # This script will will recreate selected playlists from your iPod in iTunes. # The songs must already be in your Library. # # written by: Robert Jacobson (http://mysite.verizon.net/teridon/itunesscripts) # Last Updated: 14 Dec 2006 # Version 1.0 # # This script is GPL v2. see http://www.gnu.org/copyleft/gpl.html # ############################################################################### use File::Basename; my $PROGNAME = basename($0); my $VERSION = "1.0"; my $AUTHOR = "Robert Jacobson"; my $HOMEPAGE = "http://mysite.verizon.net/teridon/"; my $YEAR = 2006; my $GNU_URL = "http://www.gnu.org/copyleft/gpl.html"; { print "**************************************************************\n" . "$PROGNAME version $VERSION, Copyright (C) $YEAR $AUTHOR\n" . "Visit $HOMEPAGE for updates\n" . "$PROGNAME comes with ABSOLUTELY NO WARRANTY;\n". "This is free software, and you are welcome\n" . "to redistribute it under certain conditions\n" . "for details see $GNU_URL.\n" . "**************************************************************\n" . "\n" ; } use strict; use Win32::OLE; use Data::Dumper; # Create a signal handler to destroy the iTunes object # in case our program quits before the end use sigtrap 'handler', \&quit, 'normal-signals'; ## Create the OLE Object my $iTunes = Win32::OLE->new('iTunes.Application') or die Win32::OLE->LastError(); # Get the possible sources my $sources = $iTunes->Sources(); my $sourcesCount = $sources->Count(); my $source = ''; my $sourceKind = ''; $| = 1; print "Getting Library info..."; # Get the iTunes Library playlist my $library = $iTunes->LibraryPlaylist(); my %tracks; # For every track in the Library list, generate the "key" my $tracks = $library->Tracks; my $num_tracks = $tracks->Count(); for (my $k = 1 ; $k <= $tracks->Count ; $k++ ) { print "."; my $track = $tracks->Item($k); my $artist = $track->Artist(); my $name = $track->Name(); my $duration = $track->Duration(); my $key = "${name} ${artist} ${duration}"; # Store the track for later use $tracks{$key} = $track; } print "\nDone\n"; my %seen; my %found; my $n = 1; my $foundipod = 0; # Get the "master" iPod playlist for ($n = 1; $n <= $sourcesCount; $n++) { $source = $sources->Item($n); $sourceKind = $source->Kind(); if ($sourceKind == 2) { $foundipod = 1; print "iPod Source\n"; my $playlists = $source->Playlists(); my $num_playlists = $playlists->Count(); # For each playlist, show the name and number of tracks for (my $j = 1 ; $j <= $num_playlists; $j++) { my $playlist = $playlists->Item($j); my $playlist_name = $playlist->Name(); print "\t$j : $playlist_name\n"; } print "Enter comma-separated playlist numbers: "; chomp (my $nums = ); my @nums = split(/,/ , $nums); for my $j (@nums) { # For each playlist, show the name and number of tracks # for (my $j = 1 ; $j <= $num_playlists; $j++) { my $playlist = $playlists->Item($j); my $playlist_name = $playlist->Name(); #Create a playlist my $new_playlist = $iTunes->CreatePlaylist($playlist_name); # Get all tracks on the iPod, and store the info in %seen with key "${name}${artist}${size}" my $tracks = $playlist->Tracks; my $num_tracks = $tracks->Count(); print "\t$num_tracks tracks\n"; # Get all the tracks in the playlist for (my $k = 1 ; $k <= $tracks->Count ; $k++ ) { my $track = $tracks->Item($k); my $artist = $track->Artist(); my $name = $track->Name(); my $duration = $track->Duration(); my $key = "${name} ${artist} ${duration}"; if (not defined $tracks{$key} ) { print "ERROR: could not find $key in Library\n"; } else { $found{$key} = 1; my $libtrack = $tracks{$key}; $new_playlist->AddTrack($libtrack); } } } } } if (not $foundipod) { print "ERROR: no iPod attached!\n"; quit; } # Find tracks that were on iPod but couldn't find in the Library for my $key (sort keys %seen) { if (not $found{$key}) { print "couldn't find $key\n"; } } # Destroy the object. Otherwise zombie object will come back # to haunt you quit(); sub quit { # This destroys the object undef $iTunes; exit; }