#!/usr/bin/perl

##################################################
#
# GiantDisc mp3 Jukebox
# 
# © 2000-2002, Rolf Brugger
#
##################################################

# Creates browsable directories with human readable links to mp3 tracks
#
# Thanks to Olav Wölfelschneider for his contributions
#

use lib '/home/music/bin';
use gdparams;
use gdgentools;
use DBI;
use strict;

### main
  ### Init constants
  my $dbh;
  my $mp3base = gdparams::gdbase();		# music files base
  my $dirbase = "$mp3base/browse";   #old: cwd();
  my $verbose=1;
  if ($ARGV[0] eq "-s"){$verbose=0;};

  ### Open database connection
  if($verbose){print ("### Open database connection\n");}
# $dbh = DBI->connect("DBI:mysql:GiantDisc", "music", undef)
  $dbh = DBI->connect("DBI:mysql:GiantDisc:".$gdparms::dbhost, "music", undef)
    or die "unable to connect to GiantDisc db at host $gdparms::dbhost";


  ### Tracks by Artist
  prepare_directory("$dirbase/tracks-by-artist");
  make_tracksbyartist_directory(
    "$dirbase/tracks-by-artist", $mp3base, "1");

  ### Tracks by Artist
  prepare_directory("$dirbase/tracks-by-artist-noalbum");
  make_tracksbyartist_directory(
    "$dirbase/tracks-by-artist-noalbum", $mp3base, "length(sourceid)<8");

  ### Albums by Artist
  prepare_directory("$dirbase/albums-by-artist");
  make_albumbyartist_directory("$dirbase/albums-by-artist", $mp3base);

  ### Tracks
  prepare_directory("$dirbase/tracks");
  make_tracks_directory("$dirbase/tracks", $mp3base);

  ### Albums by Genre
  prepare_directory("$dirbase/albums-by-genre");
  make_albumbygenre_directory("$dirbase/albums-by-genre", $mp3base);



  if($verbose){print("### close database connection\n");}
  $dbh->disconnect;

  exit;



###############################################################################

sub prepare_directory{
  my ($dirname) = @_;
  
  if ($dirname =~ /.*music\/browse.*/){ # this is for safety reasons (make sure that it's a browse directory)
    system ("rm -rf $dirname/");
  }
  if($verbose){print ("create dir: $dirname \n\n");}
  mkdir ("$dirname", 0755);	# does nothing if dir exists already!
}

###############################################################################

sub make_symlink{
  my ($filename, $linkdirname, $linkfname) = @_;
  my ($fullfilename, $linkfullname, $audioformat);
  
  if (!gdgentools::is_mp3stream($filename)){
    ### create link
    $audioformat = gdgentools::audio_filetype($filename);
    $fullfilename = `ls $mp3base/??/$filename`;  # get full filename and path
#    $fullfilename = " ../../../00/$filename";  # get full filename and path
    chop($fullfilename);
    $linkfullname = $linkdirname
      . gdgentools::ascii2filename(gdgentools::iso2ascii($linkfname))
      . ".".$audioformat;
    symlink ($fullfilename, $linkfullname);
    #print "symlink ($fullfilename, $linkfullname)\n";
  }
}

###############################################################################


### translate genre code to hierarchical genre directory string
#   Ex: "mdi"  ->  "Pop-Rock/Pop/Neue-Deutsche-Welle"
sub genre2dirstring{
  my ($dbh, $genre) = @_;
  my ($sth, $row, $dirstring);
  my $dirstring = "";
  my $genprefix = " - ";
  
  #print "$genre -> ";
  while (length($genre)>0){
    my $sth = $dbh->prepare("SELECT genre FROM genre WHERE id = '$genre'");
    $sth->execute;
    if($row = $sth->fetchrow_hashref){
      $dirstring = $genprefix.gdgentools::ascii2filename($row->{genre})."/".$dirstring;
    }
    else {
      print "internal error: cant find genre '$genre'\n";
      $dirstring = "error/".$dirstring;
    }
    $sth->finish;
    
    chop ($genre);
  }
  chop ($dirstring);  # chop of trailing "/"
  #print "$dirstring\n";
  return $dirstring;
}



###############################################################################

########################
### ARTIST directory ###
########################

sub make_tracksbyartist_directory{ #
  my ($dirbase, $mp3base, $whereclause) = @_;
  my ($artist, $title, $artist_esc);
  my ($artrow, $artist, $nbtracks, $trkrow);
  
  ### Get all distinct artist names
#print          "SELECT DISTINCT artist FROM tracks WHERE $whereclause ORDER BY artist\n";
  my $artsth = $dbh->prepare(
          "SELECT DISTINCT artist FROM tracks WHERE $whereclause ORDER BY artist"
	);
  $artsth->execute;

  while($artrow = $artsth->fetchrow_hashref){
    ### make and change to directory
    $artist = gdgentools::ascii2filename(gdgentools::iso2ascii($artrow->{artist}));


    ### Get all tracks of artist
    $artist_esc = $artrow->{artist};	# escape double quotes (")
    $artist_esc =~ s/"/\\"/g;
    my $trksth = $dbh->prepare(
      "SELECT title, mp3file FROM tracks WHERE artist LIKE \"".$artist_esc."\" "
     ."AND $whereclause"
    );
    $nbtracks=$trksth->execute;
    if ($nbtracks > 0){
      if($verbose){print ("Artist: $artist");}
      mkdir ("$dirbase/$artist", 0755);	# does nothing if dir exists already!
    }
    if($verbose){print "  ($nbtracks tracks)\n";}

    while($trkrow = $trksth->fetchrow_hashref){
      make_symlink($trkrow->{mp3file}, "$dirbase/$artist/", $trkrow->{title});
    }
    $trksth->finish;

  }
  $artsth->finish;

}


###############################################################################

### ALBUM directory ###

sub fill_album_directory{ #
  my ($albumdir, $mp3base, $cddbid, $albartist, $albtitle) = @_;
  my ($artist, $fname, $tracknb);
  my ($trkrow);

  ### Get all tracks of album
  my $trksth = $dbh->prepare(
     "SELECT artist, title, tracknb, mp3file FROM tracks "
    ."WHERE sourceid = '".$cddbid."' ORDER BY tracknb"
  );
  $trksth->execute;

  while($trkrow = $trksth->fetchrow_hashref){
    $tracknb = sprintf "%02d", $trkrow->{tracknb};
    make_symlink($trkrow->{mp3file}, "$albumdir/",
        "$tracknb $trkrow->{artist} - $trkrow->{title}");
  }
  $trksth->finish;
}


#################################
### ALBUM by ARTIST directory ###
#################################

sub make_albumbyartist_directory{ #
  my ($dirbase, $mp3base) = @_;
  my ($dirname, $title, $artist_esc);
  my ($albrow);

  ### Get all distinct artist names
  my $albsth = $dbh->prepare("SELECT * FROM album");
  $albsth->execute;

  while($albrow = $albsth->fetchrow_hashref){
    ### make and change to directory
    $dirname = gdgentools::ascii2filename(gdgentools::iso2ascii(
        "$albrow->{artist} - $albrow->{title}"));
    if($verbose){print ("Album: $dirname\n");}
    mkdir ("$dirbase/$dirname", 0755);	# does nothing if dir exists already!

    fill_album_directory("$dirbase/$dirname", $mp3base, $albrow->{cddbid}, 
        $albrow->{artist}, $albrow->{title});

  }
  $albsth->finish;

}


#################################
### ALBUM by GENRE directory ###
#################################

sub make_albumbygenre_directory{ #
  my ($dirbase, $mp3base) = @_;
  my ($dirname, $title, $artist_esc);
  my ($row, $albrow, $genredir);
  
  ### Create all genre directories
  my $sth = $dbh->prepare("SELECT genre FROM album WHERE LENGTH(genre)>0 GROUP BY genre");
  $sth->execute;
  while($row = $sth->fetchrow_hashref){
    $genredir = genre2dirstring($dbh, $row->{genre});
    #print "mkdir -p \"$dirbase/$genredir\"\n";
    system "mkdir -p \"$dirbase/$genredir\"";   # -p: create all parents of directory too
  }
  $sth->finish;


  ### Get all albums
  my $albsth = $dbh->prepare("SELECT * FROM album");
  $albsth->execute;

  while($albrow = $albsth->fetchrow_hashref){
    if (length($albrow->{genre})>0){  # not sure if this check is really useful ...
      ### make and change to directory
      $genredir = genre2dirstring($dbh, $albrow->{genre});
      $dirname = gdgentools::ascii2filename(gdgentools::iso2ascii(
        "$albrow->{artist} - $albrow->{title}"));
      if($verbose){print ("Album: $genredir/$dirname\n");}
      mkdir ("$dirbase/$genredir/$dirname", 0755);	# does nothing if dir exists already!

      fill_album_directory("$dirbase/$genredir/$dirname", $mp3base, $albrow->{cddbid}, 
          $albrow->{artist}, $albrow->{title});
    }
  }
  $albsth->finish;

}


###############################################################################

########################
### TRACKS directory ###
########################

sub make_tracks_directory{ #
  my ($dirbase, $mp3base) = @_;
  my ($artist, $title, $artist_esc, $trkrow);
  
  ### Get all tracks
  my $trksth = $dbh->prepare(
    'SELECT artist, title, mp3file FROM tracks'
  );
  $trksth->execute;

  while($trkrow = $trksth->fetchrow_hashref){
    make_symlink($trkrow->{mp3file}, "$dirbase/",
        "$trkrow->{artist} - $trkrow->{title}");
  }
  $trksth->finish;
}




###############################################################################

###