#!/usr/bin/perl # Filename: mp3mv # Author: David Ljung Madison # See License: http://MarginalHacks.com/License # Description: Moves an mp3 file according to its id3 tag use strict; ################################################## # Setup the variables ################################################## my $PROGNAME = $0; $PROGNAME =~ s|.*/||; my $MODE = 0755; # Dir permissions my $ILL_CHARS = '\s~()!*?\"\''; ################################################## # Usage ################################################## sub usage { my $msg; foreach $msg (@_) { print "ERROR: $msg\n"; } print "\n"; print "Usage:\t$PROGNAME [-d] [-v] ..\n"; print "\tMoves an mp3 file according to its id3 tag\n"; print "\t-v\tSet verbose mode\n"; print "\t-d\tSet debug mode\n"; print "\n"; exit -1; } sub parse_args { my @mp3s; my $arg; while ($#ARGV>=0) { $arg=shift(@ARGV); if ($arg =~ /^-h$/) { usage(); } if ($arg =~ /^-d$/) { $MAIN::DEBUG=1; next; } if ($arg =~ /^-v$/) { $MAIN::VERBOSE=1; next; } if ($arg =~ /^-/) { usage("Unknown option: $arg"); } push(@mp3s,$arg); } usage("No mp3s defined") if (!@mp3s); @mp3s; } sub clean { my ($str) = @_; $str =~ s/\s+$//; $str =~ s|/|-|g; $str =~ s/[$ILL_CHARS]/_/g; $str =~ s/_+/_/g; $str =~ s/_+$//; $str =~ s/^_+//; $str =~ s/\-+/\-/g; $str =~ s/\-+$//; $str =~ s/^\-+//; $str; } ################################################## # Main code ################################################## sub main { my (@mp3s) = parse_args(); foreach my $mp3 ( @mp3s ) { if (! -f $mp3) { print STDERR "[$PROGNAME] Warning: Couldn't find mp3 [$mp3]\n"; next; } # Get id3 info open(ID3,"id3tool \Q$mp3\E |") || die("[$PROGNAME] Couldn't run id3tool [$mp3]\n"); my ($title,$artist,$album,$note) = ("unknown","unknown","unknown"); while() { s/\s+$//; $title=clean($1) if (/^Song Title:\s+(\S.*)/); $artist=clean($1) if (/^Artist:\s+(\S.*)/); $album=clean($1) if (/^Album:\s+(\S.*)/); $note=$1 if (/^Note:\s+(\S.*)/); } close(ID3); # Hack - save the track number if ripped by mp3c and filename is -.. if ($note =~ /gen by.*mp3c/i) { my $track = $mp3; $track =~ s|.*/||; system("id3tool \Q$mp3\E -n 'Track $1'") if ($track =~ /^(\d+)-/); } if ($artist eq "unknown" || ($title eq "unknown" && $album eq "unknown")) { print STDERR "[$PROGNAME] Error: No id3 information for mp3 [$mp3]\n"; next; } print STDERR "[$PROGNAME] Warning: Missing id3 information for mp3 [$mp3]\n" if ($title eq "unknown" || $artist eq "unknown" || $album eq "unkown"); # PATH: //.mp3 # Make the directories (-d $artist) || mkdir($artist,$MODE) || die("[$PROGNAME] Couldn't make directory [$artist]\n"); (-d "$artist/$album") || mkdir("$artist/$album",$MODE) || die("[$PROGNAME] Couldn't make directory [$artist/album]\n"); if (-f "$artist/$album/$title.mp3") { print STDERR "[$PROGNAME] ERROR: $artist/$album/$title.mp3 already exists.\n"; next; } # Move it system("/bin/mv \"$mp3\" \"$artist/$album/$title.mp3\""); if ($?) { print STDERR "[$PROGNAME] ERROR: $artist/$album/$title.mp3 already exists.\n"; } else { print "$mp3 -> $artist/$album/$title.mp3\n" if ($MAIN::VERBOSE); } } } main();