<?php

require_once 'getid3/getid3.php';

$ini = parse_ini_file("/etc/homeaudio.ini");

define("MP3ROOTDIR", $ini['MP3DIR']);
define("ARTDIR", $ini['ARTDIR']);
define("SONGSTABLE", "songs");

$globaldbh = new PDO("mysql:host={$ini['DBHOST']};dbname={$ini['DBNAME']}", $ini['DBUSER'], $ini['DBPASS']);
$ignoredirs = array();
$ignoredirs[] = "Album Playlists";
$ignoredirs[] = "Alphabetical";
$ignoredirs[] = "Incoming2";
$ignoredirs[] = "Recent";
$ignoredirs[] = "Recent (1-2 Months)";
$ignoredirs[] = "Recent (2-3 Months)";
$ignoredirs[] = "playlists";

$extbymimetypes = array(
   'image/jpg' => 'jpg',
   'image/jpeg' => 'jpg',
   'image/png' => 'png',
   'image/gif' => 'gif'
);

function pruneDB() {
   global $globaldbh;
   $query = "SELECT id, path, song FROM " . SONGSTABLE . " ORDER BY path, song";
   $sth = $globaldbh->prepare($query);
   $sth->execute();
   $querydel = "DELETE FROM " . SONGSTABLE . " WHERE id=:id";
   $sthdel = $globaldbh->prepare($querydel);
   $count = 0;
   $prunecount = 0;
   while ( $row = $sth->fetch() ) {
      $count++;
      if ( ($count % 1000) == 0 ) echo ".";
      if ( !file_exists(MP3ROOTDIR . $row['path'] . $row['song']) ) {
         $fieldsdel = array();
         $fieldsdel[':id'] = $row['id'];
         $sthdel->execute($fieldsdel);
         $prunecount++;
      }
   }
   return $prunecount;
}

function addNewSongs($path = "") {
   global $ignoredirs, $sth_exists, $sth_addnew, $newcount;
   $fh = opendir(MP3ROOTDIR . $path);
   while ( false !== ($entry = readdir($fh)) ) {
      if ( in_array($entry, $ignoredirs) ) continue;
      if ( ($entry == ".") || ($entry == "..") ) continue;
      if ( is_dir(MP3ROOTDIR . $path . $entry) ) {
         addNewSongs($path . $entry . "/");
      } else {
         if ( substr($entry, -3) != "mp3" ) continue;
         $song = $path . $entry;
         $fields = array();
         $fields[':path'] = $path;
         $fields[':song'] = $entry;
         $sth_exists->execute($fields);
         if ( $sth_exists->fetchColumn() == 0 ) {
            $newcount++;
            if ( ($newcount % 1000) == 0 ) echo ".";
            $sth_addnew->execute($fields);
         }
      }
   }
   closedir($fh);
}

function parseSongs() {
   global $globaldbh, $extbymimetypes;
   $parsecount = 0;
   $query = "SELECT id, path, song FROM " . SONGSTABLE . " WHERE parsed='false'";
   $sth = $globaldbh->prepare($query);
   $sth->execute();
   $query_info = "UPDATE " . SONGSTABLE . " SET genre=:genre, title=:title, artist=:artist, album=:album, year=:year, length=:length, artfile=:artfile, parsed='true' WHERE id=:id";
   $sth_info = $globaldbh->prepare($query_info);
   while ( $row = $sth->fetch() ) {
      $fields = array();
      $fields[':id'] = $row['id'];
      list($fields[':genre'], $junk) = explode("/", $row['path'], 2);
      $getid3 = new getID3;
      $info = $getid3->analyze(MP3ROOTDIR . $row['path'] . $row['song']);
      if ( isset($info['id3v2']['comments']['title'][0]) ) {
         $fields[':title'] = $info['id3v2']['comments']['title'][0];
      }
      if ( !isset($fields[':title']) || ($fields[':title'] == "") ) {
         @list($junk, $fields[':title']) = explode(" - ", substr($row['song'], 0, -4), 2);
      }
      if ( isset($info['id3v2']['comments']['artist'][0]) ) {
         $fields[':artist'] = $info['id3v2']['comments']['artist'][0];
      }
      if ( !isset($fields[':artist']) || ($fields[':artist'] == "") ) {
         @list($fields[':artist'], $junk) = explode(" - ", basename($row['path']), 2);
      }
      if ( isset($info['id3v2']['comments']['album'][0]) ) {
         $fields[':album'] = $info['id3v2']['comments']['album'][0];
      }
      if ( !isset($fields[':album']) || ($fields[':album'] == "") ) {
         @list($junk, $fields[':album']) = explode(" - ", basename($row['path']), 2);
      }
      if ( isset($info['id3v2']['comments']['year'][0]) ) {
         $fields[':year'] = $info['id3v2']['comments']['year'][0];
      }
      if ( !isset($fields[':year']) ) $fields[':year'] = "";
      @list($min, $sec) = explode(":", $info['playtime_string'], 2);
      $fields[':length'] = (intval($min) * 60) + intval($sec);
      $fields[':artfile'] = "";
      if ( isset($info['comments']['picture'][0]['data']) && !is_null($info['comments']['picture'][0]['data']) ) {
         $artmd5 = md5($info['comments']['picture'][0]['data']);
         $mimetype = $info['comments']['picture'][0]['image_mime'];
         if ( array_key_exists($mimetype, $extbymimetypes) ) {
            $fields[':artfile'] = $artmd5 . "." . $extbymimetypes[$mimetype];
         }
      }
      if ( ($fields[':artfile'] != "") && !file_exists(ARTDIR . $fields[':artfile']) ) {
         file_put_contents(ARTDIR . $fields[':artfile'], $info['comments']['picture'][0]['data']);
      }
      $parsecount++;
      if ( ($parsecount % 1000) == 0 ) echo ".";
      $sth_info->execute($fields);
   }
   return $parsecount;
}

if ( !file_exists(ARTDIR) ) {
   echo "The album art folder doesn't exist. Let's try to creat it...";
   $didmake = mkdir(ARTDIR, 0775, true);
   if ( !$didmake ) {
      echo "Oops!! Failed. Check path and perms.\n";
      exit();
   } else {
      echo "success!\n";
   }
}

echo "Pruning DB of missing files...";
$prunecount = pruneDB();
echo " ", $prunecount, " songs pruned.\n";

//
// We are prepping the DB statements here since the addNewSongs() function
// is recursive. We don't want to make a TON of statements and be a hog.
//
$query = "SELECT COUNT(*) FROM " . SONGSTABLE . " WHERE path=:path AND song=:song";
$sth_exists = $globaldbh->prepare($query);
$query = "INSERT INTO " . SONGSTABLE . " (path, song) VALUES(:path, :song)";
$sth_addnew = $globaldbh->prepare($query);
$newcount = 0;
echo "Adding new songs to DB...";
addNewSongs();
echo " ", $newcount, " songs added.\n";

echo "Parsing ID3 tags...";
$parsecount = parseSongs();
echo " ", $parsecount, " tags parsed.\n";

?>
