#!/usr/bin/perl
use strict; $|++;
no strict 'refs';
use warnings;
use Mac::Glue ':all';
use Getopt::Std;

getopts('vsp:nuqr:d:P:N:L:A:T:Y:he');
our($opt_s, $opt_p, $opt_n, $opt_u, $opt_q, $opt_r, $opt_d, $opt_v,
    $opt_P, $opt_N, $opt_A, $opt_T, $opt_Y, $opt_h, $opt_L, $opt_e);

my $helptxt = <<_ENDHELP;
usage: $0 [-s|-p <playlist] [-nuqh] [-r <regex>|-d <delimiter>] 

 -s : work with selection (default if no playlist specified)
 -p <playlist> : work with playlist.
 -n : just print info after processing without changing anything
 -u : do not remove underscores from any set value (not working yet)
 -q : suppress all output

 pick one of:
 -r <regex> : regular expression to use against current track name
 -d <delimiter> : delimeter to split current track name against

 -P <replacement>: change track name in place (provide replacement)
 -N # : track name to set
 -A # : track artist to set
 -T # : track number to set
 -L # : album name to set
 -Y # : track year to set
 where # is the backreference from your regex, or array number from the split.
 
 -h : print this help text
 -e : print out examples

 NOTE:  this will also strip any underscores 
        and remove leading or tailing whitespace
 WARNING:  I highly suggest against using this on your whole library.
_ENDHELP

if ( $opt_h ) {
   print $helptxt;
   exit;
}
if ( $opt_e ) {
   print "check out http://rexroof.com/code/imunge_examples.html\n";
   exit;
}
die "must pick one of -r or -d" unless ( $opt_r or $opt_d );
die "must pick one of -s or -p" unless ( $opt_s or $opt_p );

die "options -N -A -T -L -Y options must be numbers."  if (
   ( defined $opt_N and $opt_N =~ /\D/ )  or
   ( defined $opt_A and $opt_A =~ /\D/ )  or
   ( defined $opt_T and $opt_T =~ /\D/ )  or
   ( defined $opt_L and $opt_L =~ /\D/ )  or
   ( defined $opt_Y and $opt_Y =~ /\D/ )  
);

my $itunes = new Mac::Glue 'iTunes';
die "can't find itunes" unless ( $itunes );

my @tracks;
if ( $opt_s ) {
   @tracks = $itunes->prop('selection')->get;
} elsif ( $opt_p ) {
   @tracks = $itunes->obj(tracks => playlist => $opt_p)->get;
} else { 
  die "must specify either -p or -s\n";
}
die "no songs found\n" unless ( @tracks );

   
for my $track (@tracks) {

  my ( @new_data, $name_data );
  my ($name_obj, $artist_obj, $track_obj, $album_obj, $year_obj);
  my ($new_name, $new_artist, $new_num, $new_album, $new_year);

  $name_obj = $track->prop('name');
  $name_data = $name_obj->get;
  $artist_obj = $track->prop('artist') if (defined $opt_A);
  $track_obj = $track->prop('track number') if (defined $opt_T);
  $album_obj = $track->prop('album') if (defined $opt_L);
  $year_obj = $track->prop('year') if (defined $opt_Y);

  # my $dbid_obj = $track->prop('database ID');

  if ( $opt_d ) {
     @new_data = split /$opt_d/, $name_data;

     $new_name   = $new_data[$opt_N] if ( defined $opt_N );
     $new_artist = $new_data[$opt_A] if ( defined $opt_A );
     $new_num    = $new_data[$opt_T] if ( defined $opt_T );
     $new_album  = $new_data[$opt_L] if ( defined $opt_L );
     $new_year   = $new_data[$opt_Y] if ( defined $opt_Y );
  } elsif ( $opt_r ) {
     if ( defined $opt_P ) {
        my $regex_replace = '"'.$opt_P.'"';
	print "name data: $name_data\n" if ($opt_v);
	print "opt_r: $opt_r\n" if ($opt_v);
	print "regex_replace: $regex_replace\n" if ($opt_v);
	$name_data =~ s/$opt_r/$regex_replace/oee;
        $new_name   = $name_data;
        $new_artist = ${$opt_A} if ( defined $opt_A );
        $new_num    = ${$opt_T} if ( defined $opt_T );
        $new_album  = ${$opt_L} if ( defined $opt_L );
        $new_year   = ${$opt_Y} if ( defined $opt_Y );
     } else {
        $name_data =~ $opt_r;
        $new_name   = ${$opt_N} if ( defined $opt_N );
        $new_artist = ${$opt_A} if ( defined $opt_A );
        $new_num    = ${$opt_T} if ( defined $opt_T );
        $new_album  = ${$opt_L} if ( defined $opt_L );
        $new_year   = ${$opt_Y} if ( defined $opt_Y );
     }
  }

  # TRACK NAME
  if ( defined $new_name ) {
    $new_name =~ s/_/ /g;
    $new_name =~ s/^\s+//g;
    $new_name =~ s/\s+$//g;
    
    if ( $opt_n ) {
       print "N: \"$new_name\" ";
    } else { 
       $name_obj->set(to => $new_name);
    }
  }
  # TRACK ARTIST
  if ( defined $new_artist ) {
    $new_artist =~ s/_/ /g;
    $new_artist =~ s/^\s+//g;
    $new_artist =~ s/\s+$//g;
    
    if ( $opt_n ) {
       print "A: \"$new_artist\" ";
    } else { 
       $artist_obj->set(to => $new_artist);
    }
  }
  # TRACK NUMBER 
  if ( defined $new_num ) {
    $new_num =~ s/_/ /g;
    $new_num =~ s/^\s+//g;
    $new_num =~ s/\s+$//g;
    
    if ( $opt_n ) {
       print "T: \"$new_num\" ";
    } else { 
       $track_obj->set(to => $new_num);
    }
  }
  # TRACK ALBUM
  if ( defined $new_album ) {
    $new_album =~ s/_/ /g;
    $new_album =~ s/^\s+//g;
    $new_album =~ s/\s+$//g;
    
    if ( $opt_n ) {
       print "L: \"$new_album\" ";
    } else { 
       $album_obj->set(to => $new_album);
    }
  }
  # TRACK YEAR
  if ( defined $new_year ) {
    $new_year =~ s/_/ /g;
    $new_year =~ s/^\s+//g;
    $new_year =~ s/\s+$//g;
    
    if ( $opt_n ) {
       print "Y: \"$new_year\" ";
    } else { 
       $year_obj->set(to => $new_year);
    }
  }

  print $/ if ( $opt_n );

}



syntax highlighted by Code2HTML, v. 0.9.1