#!/usr/bin/perl

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

# gdrefresh.pl: GiantDisc - recalculate genre / language table frequencies
# 

### Constants
my $albumgenre_percentage = 60;  # album genre must cover x% of track genres


### Libs
use lib '/home/music/bin';
use DBI;
use Getopt::Long;
use strict;
#package gdparams;

my ($help, $dbhost, $trkgenre, $trklanguage, $albgenre, $albcover, $verbose, $dbh);

$Getopt::Long::autoabbrev=1;
my $oret=GetOptions(
	"help" 		 => \$help, 
	"dbhost=s" 	 => \$dbhost,      # mandatory argument
	"trkgenre"       => \$trkgenre,
	"trklanguage"    => \$trklanguage,
	"albgenre:s"     => \$albgenre,   # optional string argument
	"albcover:s"     => \$albcover,   # optional string argument
	"verbose"        => \$verbose
	);

if (!$oret || $help || !defined $dbhost){
  print <<ENDOFTEXT;

gdrefresh.pl
GiantDisc update redundant db-fields that are stored in the db for efficiency reasons.

Options
--dbhost (string)  address or hostname of mysql database server

--trkgenre         update genre frequencies for tracks

--trklanguage      update language frequencies for tracks

--albgenre cddbid  update genre info for albums (calculated based
                   on track genres: The album is associated the most 
                   specific genre that covers at least 60% of the 
                   genres of its tracks). if cddbid is defined, then
                   only this album is updated. Otherwise, all album
                   records are updated

--albcover         Updates all album records, for which cover images
                   have not been registered yet. (writes the cover image
                   file name  'img<CDDB-ID>-00.jpg' to the field coverimg).
                   
--verbose          tell about what is happening

ENDOFTEXT
  exit 0;
}



### set termination handler
$SIG{TERM} = 
sub { 
  # Kill event handler
  print "gdrefresh.pl killed\n"; 
  $dbh->disconnect; 
  exit;
}; 


#my $base     = gdparams::gdbase();
my $base     = "/home/music";


### open DB connection
$dbh = DBI->connect("DBI:mysql:GiantDisc:".$dbhost, "music", undef)
    or die "unable to connect to GiantDisc db";



###### Track Languages
if(defined $trklanguage){
  my $sth = $dbh->prepare(
           'SELECT language.id, language.language, COUNT(*) AS freq '
          .'FROM tracks,language '
          .'WHERE tracks.lang=language.id '
          .'GROUP BY language.id '
          #.'ORDER BY freq DESC '
	);

  my $rv = $sth->execute;
  my (@row, $stop);

  $dbh->do("UPDATE language SET freq=0"); #initialize all records

  while(@row = $sth->fetchrow_array){
    if (defined $verbose) {print "set freq of language $row[0]\tto $row[2]\n";}
    #print("UPDATE language SET freq=".$row[2]." WHERE id='".$row[0]."'\n");
    $dbh->do("UPDATE language SET freq=".$row[2]." WHERE id='".$row[0]."'");
  }
  $sth->finish;
}


###### Track Genres
if(defined $trkgenre){
  my $sth = $dbh->prepare(
           'SELECT genre.id,genre.genre,COUNT(*) '
          .'FROM tracks,genre '
          .'WHERE tracks.genre1=genre.id OR tracks.genre2=genre.id '
          .'GROUP BY genre.id '
          #.'ORDER BY genre.genre '
	);

  my $rv = $sth->execute;
  my (@row, $stop);

  $dbh->do("UPDATE genre SET freq=0"); #initialize all records

  while(@row = $sth->fetchrow_array){
    if (defined $verbose) {print "set freq of genre $row[0]\tto $row[2]\n";}
    #print("UPDATE genre SET freq=".$row[2]." WHERE id='".$row[0]."'\n");
    $dbh->do("UPDATE genre SET freq=".$row[2]." WHERE id='".$row[0]."'");
  }
  $sth->finish;
}




###### Album Genres
if(defined $albgenre){
  if (length $albgenre >= 8){
    update_one_album_genre($dbh, $albgenre);
  }
  else{
    update_all_album_genre ($dbh);
  }
}





###### Album Booklets
if(defined $albcover){
  my ($pattern, $sth, $rec);
  my @flist;
  # not supported yet
  if (length $albcover >= 8){
    @flist = glob "$base/[0-9][0-9]/img*$albcover-00.jpg";
  }
  else{
    @flist = glob "$base/[0-9][0-9]/img*-00.jpg";
  }

  my $i=0;
  while ($i < scalar(@flist)){
    if (defined $verbose) {print "checking $flist[$i]\n";}
    
    if ($flist[$i] =~ /.*(img.x([a-f0-9]+)-..\.jpg).*/){

      $sth = $dbh->prepare("SELECT coverimg FROM album WHERE cddbid='$2'");
      $sth->execute;
      if ($rec = $sth->fetchrow_hashref){
        if ($rec->{coverimg} ne $1){
          #print "db '".$rec->{coverimg}."' not-equal fs '$1' \n";
          if (defined $verbose) {print "update album id $2 with image file name $1\n";}
          $dbh->do("UPDATE album SET coverimg='$1', modified=CURDATE() WHERE cddbid='$2'");
        }
      }
      $sth->finish;
    }
    $i++;
  }
  
}




#print ("Terminated: gdrefresh.pl (end reached)\n");
$dbh->disconnect;




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

sub update_one_album_genre{
# select count(*) as cnt,length(genre1) AS len,genre1 from tracks where sourceid='3d10e717' group by genre1 order by genre1;
  my ($dbh, $cddbid) = @_;
  
  $dbh->do("CREATE TEMPORARY TABLE tmpgenre(genre char(10))");
  update_album_genre($dbh, $cddbid, $albumgenre_percentage);
  $dbh->do("DROP TABLE tmpgenre");
}


sub update_all_album_genre{
# select count(*) as cnt,length(genre1) AS len,genre1 from tracks where sourceid='3d10e717' group by genre1 order by genre1;
  my ($dbh) = @_;
  my ($sth, $row, $rec);
  
  $dbh->do("CREATE TEMPORARY TABLE tmpgenre(genre char(10))");

  $sth = $dbh->prepare("SELECT cddbid FROM album");
  $sth->execute;
  while ($rec = $sth->fetchrow_hashref){
    update_album_genre($dbh, $rec->{cddbid}, $albumgenre_percentage);
  }
  $sth->finish;

  $dbh->do("DROP TABLE tmpgenre");
}



sub update_album_genre{
# select count(*) as cnt,length(genre1) AS len,genre1 from tracks where sourceid='3d10e717' group by genre1 order by genre1;
  my ($dbh, $albumid, $albumgenre_percentage) = @_;

  #$albumid = "e4090210";
  my ($sth, $nbgen, $rec);
  my ($curmaxlen, $curmaxfreq, $curmaxfreqgenre, $row);
  
  $dbh->do("DELETE FROM tmpgenre");

  $curmaxlen = 0;
  $curmaxfreq      = 0;
  $curmaxfreqgenre = "";
  if (length($albumid)>7){
    ### copy genre strings into temporary table
    $nbgen =  $dbh->do("INSERT INTO tmpgenre SELECT genre1 from tracks where sourceid='$albumid' and length(genre1)>0");
    $nbgen += $dbh->do("INSERT INTO tmpgenre SELECT genre2 from tracks where sourceid='$albumid' and length(genre2)>0");
    #print "nbgen: $nbgen \n";

    ### get length of longest genre string
    $sth = $dbh->prepare("SELECT MAX(GREATEST(LENGTH(genre1),LENGTH(genre2))) AS maxlen FROM tracks"
                        ." WHERE sourceid='$albumid' GROUP BY sourceid");
    $sth->execute;
    if ($rec = $sth->fetchrow_hashref){
      $curmaxlen = $rec->{maxlen}
    }
    $sth->finish;

    ### iteratively truncate and group genre strings
    while($curmaxfreq*100 < ($nbgen * $albumgenre_percentage)){
      $sth = $dbh->prepare("SELECT count(*) AS cnt, LEFT(genre,$curmaxlen) AS gen"
                          ." FROM tmpgenre GROUP BY gen ORDER BY cnt DESC");
      $sth->execute;
      last if !($row = $sth->fetchrow_hashref);
      $curmaxfreq = $row->{cnt};
      $curmaxfreqgenre = $row->{gen};
      $sth->finish;

      $curmaxlen--
    }

    if (length($curmaxfreqgenre)>0 || $albumgenre_percentage <30){
      ### write genre to album record
      if (defined $verbose) {print "set genre of $albumid to '$curmaxfreqgenre'\n";}
      $dbh->do("UPDATE album SET genre='$curmaxfreqgenre' WHERE cddbid='$albumid'");
    }
    else{
      if (defined $verbose) {print "no $albumgenre_percentage% genre found for albumid $albumid\n";}
      update_album_genre($dbh, $albumid, $albumgenre_percentage/2);
    }
  }

}
#


