#!/usr/bin/perl -w use strict; use Getopt::Long; my $debug=0; my $set=0; my $mixedauthors; my $swapauthors; my $authordashes=1; my $albumdashes=1; my $albumyear=0; my $notitle=0; my $genre; my $ucauthor; my $ucalbum; my $uctitle; my %opts; sub usage { die "$0 [--set] [--mixedauthors numtrailing] [--swapauthors] [--notitle] [--author numdashes] [--album numdashes] [--albumyear] --genre num\n"; } GetOptions("debug" => \$debug, "set" => \$set, "mixedauthors:i" => \$mixedauthors, "swapauthors" => \$swapauthors, "notitle" => \$notitle, "author=i" => \$authordashes, "album=i" => \$albumdashes, "albumyear" => \$albumyear, "genre=s" => \$genre, "ucauthor:i" => \$ucauthor, "ucalbum:i" => \$ucalbum, "uctitle:i" => \$uctitle) or usage; $albumdashes++ if ($albumyear); if (defined $ucauthor) { $ucauthor=2 if ($ucauthor == 0); } else { $ucauthor=0; } if (defined $ucalbum) { $ucalbum=3 if ($ucalbum == 0); } else { $ucalbum=0; } if (defined $uctitle) { $uctitle=3 if ($uctitle == 0); } else { $uctitle=0; } $genre or usage; if (system("id3 -g \"$genre\" /dev/null &>/dev/null")) { print STDERR "Genre $genre doesn't exist, please choose one from this list:\n"; system("id3 -L >&2"); usage; } $ARGV[0] or usage; foreach $_ (@ARGV) { my $dir; my $file; my $newfile; my $author; my $album; my $title; my $track=""; my $year=""; if ( ! -f $_ ) { print "Skipping non file $_\n"; next; } if ( -z $_ ) { print "Skipping empty file $_\n"; next; } m#^(.*?)/?([^/]+)$#; ($dir,$file) = ($1, $2); print "Dealing with $dir | $file\n" if $debug; $file =~ s/\$/\\\$/g; $file =~ s/"/\\"/g; $_=$file; s/.mp3/ - .mp3/ if ($notitle); # Here's some serious regex-fu (it only took 4H+ to write :-D) if (defined $mixedauthors) { my $initial=$albumdashes+$mixedauthors; if (not /^((?:(?:[^-]+(?:-(?! ))?)+ - ){$initial})((?:(?:[^-]+(?:-(?! ))?)+ - ){$authordashes})(.*).mp3$/) { warn ("Couldn't process $_\nwith $authordashes dash(es) in the author name and $albumdashes dash(es) in the album name, skipping...\n"); next; } print "Got al:|$1| au:|$2| t:|$3| (mixed author mode)\n" if $debug; ($album,$author,$title) = ($1, $2, $3); if ($ucauthor or $ucalbum or $uctitle) { $author =~ s/((?:\S+){$ucauthor,})/\u$1/g if $ucauthor; $album =~ s/((?:\S+){$ucalbum,})/\u$1/g if $ucalbum; $title =~ s/((?:\S+){$uctitle,})/\u$1/g if $uctitle; $newfile = "$album$author$title"; } $track = $1 if ($author =~ s/(\d\d) //); $author =~ s/ - $//; $album=~ s/^(?:(?:[^-]+(?:-(?! ))?)+ - ){$mixedauthors}//; $album=~ s/ - $//; } else { if (not $swapauthors) { if (not /^((?:(?:[^-]+(?:-(?! ))?)+ - ){$authordashes})((?:(?:[^-]+(?:-(?! ))?)+ - ){$albumdashes})(.*).mp3$/) { warn ("Couldn't process $_\nwith $authordashes dash(es) in the author name and $albumdashes dash(es) in the album name, skipping...\n"); next; } print "Got au:|$1| al:|$2| t:|$3| (normal author mode)\n" if $debug; ($author,$album,$title) = ($1, $2, $3); } else { if (not /^((?:(?:[^-]+(?:-(?! ))?)+ - ){$albumdashes})((?:(?:[^-]+(?:-(?! ))?)+ - ){$authordashes})(.*).mp3$/) { warn ("Couldn't process $_\nwith $authordashes dash(es) in the author name and $albumdashes dash(es) in the album name, skipping...\n"); next; } print "Got |$1| |$2| |$3| (normal inversed author mode)\n" if $debug; ($album,$author,$title) = ($1, $2, $3); } if ($ucauthor or $ucalbum or $uctitle) { $author =~ s/((?:\S+){$ucauthor,})/\u$1/g if $ucauthor; $album =~ s/((?:\S+){$ucalbum,})/\u$1/g if $ucalbum; $title =~ s/((?:\S+){$uctitle,})/\u$1/g if $uctitle; $newfile = "$author$album$title"; } $author=~ s/ - $//; $track = $1 if ($title =~ s/(\d\d) //); #$track = $1 if ($title =~ s/ - (\d\d)$//); $album=~ s/ - $//; } if ($albumyear) { $album =~ /(\d{4}) - (.+)/; ($year, $album) = ($1, $2); } if ($newfile) { $newfile.=".mp3"; if ($newfile ne $file) { print "Going from '$file'\nto '$newfile'\n"; if ($set) { my $file2; my $newfile2; ($file2=$file) =~ s/\\"/"/; ($newfile2=$newfile) =~ s/\\"/"/; rename("$dir$file2", "$dir$newfile2") or die "rename $dir$file2, $dir$newfile2 failed: $!"; } $file = $newfile; } else { print "Leaving $file unchanged\n" if $debug; } } # Those modifications are only made for the MP3 tags, no the full filenames on disk $album=~ s/^Single$//i; if ($title =~ m/^\d\d$/) { $track=$title; $title = "Track $title"; } if ($track) { print "Setting Author: $author | Album: $album | Track: $track | Title: $title"; } else { print "Setting Author: $author | Album: $album | Title: $title"; } print $year?" | Year: $year\n":"\n"; $year="-y $year" if ($year); $track="-T $track" if ($track); if ($set) { #system("id3v2 -D \"$dir$file\""); system("id3 -a \"$author\" -A \"$album\" -t \"$title\" -g \"$genre\" $track $year \"$dir$file\""); system("id3v2 -a \"$author\" -A \"$album\" -t \"$title\" -g \"$genre\" $track $year \"$dir$file\""); system("chmod 644 \"$dir$file\""); } }