#!/usr/bin/perl
use strict;
################################################################################
# fix_mp3.pl
#  Crappy little script for getting rid of irritating characters in mp3 file and
#  directory names.
#
# Copyright 2004 by dleonard@dleonard.net
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.  The author
# would appreciate it if any useful modifications performed were emailed
# to the maintainer as a unified dif in order to make the tool more useful
# to others.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
################################################################################

my $basedir = '.';

if (scalar @ARGV) {
 $basedir = shift @ARGV;
}

if (! -d $basedir) {
 print STDERR "MP3 directory $basedir not present.\n";
 exit 1;
}

opendir(BASE, $basedir) or die "Unable to open dir $basedir";
my @dirs = grep {!/^\.+$/} readdir(BASE);
closedir BASE;

foreach my $dir (@dirs) {
 chomp $dir;
 if (-d $dir) {
  subdir($dir);
 }
}

sub subdir {
 my $directory = shift;

 opendir(SUBDIR, $directory) or die "Unable to open dir $directory.\n";
 my @dirs = map {"$directory/$_"} grep {!/^\.+$/} readdir(SUBDIR);
 closedir SUBDIR;

 my @next_dirs = ();

 foreach my $entry (@dirs) {
  chomp $entry;
  if (-f $entry) {
   my $f_new = $entry;

   # Strip extra .mp3 off end
   $f_new =~ s/(.+\.mp3)\.mp3/$1/;

   # Replace spaces or | w/ _
   $f_new =~ s/[|\s]+/_/g;

   # Get rid of ' " \ [ ] ( )
   $f_new =~ s/[\'\"\\\[\]\(\)]//g;

   # Replace & with and
   $f_new =~ s/\&+/and/g; 

   # Escape the original file
   $entry =~ s#[\\\(\)\&\"\']#\\$&#g;

   if ($entry ne $f_new) {
    `mv $entry $f_new`;

    if ($?) {
     print "mv $entry $f_new\n$!\n";
     exit;
    }
   }

  } elsif (-d $entry) {
   my $d_new = $entry;

   # Replace spaces or | w/ _
   $d_new =~ s/[|\s]+/_/g;

   # Get rid of ' " \ [ ] ( )
   $d_new =~ s/[\'\"\\\[\]\(\)]//g;

   # Replace & with and
   $d_new =~ s/\&+/and/g;

   # Escape the original directory
   $entry =~ s#[\\\(\)\&\"\']#\\$&#g;

   if ($entry ne $d_new) {
    `mv $entry $d_new`;

    if ($?) {
     print "mv $entry $d_new\n$!\n";
     exit;
    }
   } 

   push @next_dirs, $d_new;
  }
 }

 foreach my $dir (@next_dirs) {
  subdir($dir);
 }
} #subdir
