############################################################################### # # itunes_remove_by_playlist.pl # # This script will remove all songs from your iTunes Library based on the # playlist you selected. It will also optionally remove those files from # your hard drive. # # Copyright (C) 2007 Robert Jacobson # written by: Robert Jacobson (http://mysite.verizon.net/teridon/itunesscripts) # Last Updated: 28 Jan 2007 # 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 = 2007; 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; # For fancy printing of structures $Data::Dumper::Sortkeys = 1; # Create a signal handler to destroy the iTunes object # in case our program quits before the end use sigtrap 'handler', \&quit, 'normal-signals'; # Script Info print <); } if ($delete eq "y") { print "*********** OK, will delete files!\n"; print "*********** Please NOTE: this script will not delete the\n"; print "*********** folders containing the files, even if they are\n"; print "*********** empty\n"; } elsif ($delete eq "n") { print "OK, will NOT delete files\n"; } #sleep 2; ## 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 = ''; my $library = $iTunes->LibraryPlaylist(); my %Library_IDs; # Retrieve Library information for all tracks $| = 1; print "Reading Library..."; my $tracks = $library->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 $track_kind = $track->Kind(); if ($track_kind == 1) { # Get the TrackDatabase ID, and store it for later my $id = $track->TrackDatabaseID; $Library_IDs{$id} = $track; } } print "Done.\n"; # Now allow user to choose a playlist my $n = 1; print "There are " . $sourcesCount . " sources currently available\n"; # For each source, figure out kind for ($n = 1; $n <= $sourcesCount; $n++) { $source = $sources->Item($n); $sourceKind = $source->Kind(); print "source no. " . $n . " is "; print $sourceKind . " -- "; if ($sourceKind == 0) { print "Unknown Source\n"; } if ($sourceKind == 1) { print "Library Source\n"; # Get the playlists in the Library my $playlists = $source->Playlists(); my $num_playlists = $playlists->Count(); print "There are $num_playlists playlists\n"; # 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); # Create a temporary Playlist to select while tracks are being deleted # This speeds up the operation #my $tmp_playlist = $iTunes->CreatePlaylist("Temporary Playlist $$"); # select the temporary playlist (I can't get this to work! :( #$iTunes->BrowserWindow()->{'SelectedPlaylist'} = "Temporary Playlist $$"; for my $i (@nums) { my $playlist = $playlists->Item($i); my $playlist_name = $playlist->Name(); print "You selected $playlist_name\n"; if ($playlist_name eq "Library") { print "You want to delete your entire Library?! I don't think so... Exiting!\n"; quit(); } my $tracks = $playlist->Tracks; my $num_tracks = $tracks->Count(); print "\t$num_tracks tracks\n"; my %seen; # Get all the tracks in the playlist for (my $k = 1 ; $k <= $tracks->Count ; $k++ ) { #print "num: " , $num_tracks , " Count: ", $tracks->Count , " k: ", $k , "\n"; my $track = $tracks->Item($k); #print Dumper $track; #my $foo = ; my $track_kind = $track->Kind(); if ($track_kind == 1) { my $id = $track->TrackDatabaseID; my $location = $track->Location(); #print Dumper $track; # Get the track info from the Library my $library_track = $Library_IDs{$id}; #print "Library Track:\n" . Dumper $library_track; # Now remove it from the Library $library_track->Delete(); $k -= 1; if ($delete eq "y") { unlink($location) or warn "could not remove file: $!"; } } } } } } # Destroy the object. Otherwise zombie object will come back # to haunt you quit(); sub quit { # This destroys the object undef $iTunes; exit; }