#!/usr/bin/perl -w

# kenglish MP3 Playlist Generator
# (c) 2004 kevin@kenglish77.com
# This is free software, you can do with it whatever you like...

## original code by
# (c) 2003 J@hacked.it www.jannis.to
#  It was originally called LuFu.pl ...
#  I made it so the mp3 get sorted before they go into the file... -kevin


my $dir = shift ;
my $m3ufile = shift; 

## if you are like me and you run this all the time, you can hard code you directory and playlist file here 
## ($dir, $m3ufile) = ("/home/kenglish/mp3", "/home/kenglish/mp3/all.m3u");

if (!$dir || !$m3ufile) {
  &usage();
} 
if (!-d $dir ) {
  print "$dir is not a valid directory\n";
  exit ;
} 


use strict ; 
use MP3::Info;
$|=1;
sub lcsort {
 lc($a) cmp lc($b);
}

print "Deepsearching directories in$dir\n";
open(PL, ">".$m3ufile) || die "Fatal: Can't open " . $m3ufile . ": $!\n";
print PL "#EXTM3U\n";

# Init some varaibles
my $i = 0;
my @queue = ();
my @indexed = ();
my $q = 0;

# First one to check
push (@queue, $dir);

# Find all directories
while ($#queue >=0) {
    my $c = shift @queue;
    opendir(D, $c);
    push(@indexed, $c);
    while ($_ = readdir(D)) {
        next unless -d "$c/$_" && $_ ne '.' && $_ ne '..';
        push(@queue, "$c/$_");
        if ($#queue > $q) { $q = $#queue;}
    }
    print ".";
    closedir(D);
}

print "\nDone, I will now look for mp3s:\n";

# Find all mp3s in those directories
my %files; 
foreach $dir (@indexed) {
    opendir(D, $dir);
    next if ($dir =~ /corrupted$/); 
    while (my $mp3_file = readdir(D)) {
        next unless $mp3_file =~ /\.mp3$/i && -f "$dir/$mp3_file";
        my $mp3_file_path = "$dir/$mp3_file";
        $files{$mp3_file}=$mp3_file_path;
    }  
    closedir(D);
    print "-> got mp3s from $dir";
    print "\n";
}

# create the playlist file, 

print "Creating $m3ufile\n";
print "(This could take a few minutes, please be patient)\n";

# we sort first
my @mp3_files = sort lcsort keys %files ; 
foreach my $mp3_file (@mp3_files) { 
   my $mp3_file_path = $files{$mp3_file};  
   my $info = new MP3::Info "$mp3_file_path";
   my $out="$mp3_file_path\n"; 
   if (defined($info) && defined($info->secs) && defined($info->title)) {
      my $o = $info->secs;
      $o =~ s/([^\.]*)\.[^\.]*/$1/;
      $out = sprintf ("#EXTINF:%s,%s,\n%s", $o, "$mp3_file",  $out);
   } 
#   print "$out\n";
   print PL $out;
   $i++;
   if ($i%50 == 0){ 
   print  ".";
   } 
} 

print "\nDone. Indexed $i MP3s out of ".($#indexed+1)." directories ($q).\n";
close(PL);

sub usage(){

  print "Usage: AllMp3s.pl base_dir m3ufile\n"; 
  exit; 
}

