#!/usr/local/bin/php
<?

define
("MP3_DIR""/space/mp3/");
define("SYM_DIR""/space/mp3/# ID3-Genres/");

define("DIR_LEVEL"2);
define("GENRE_FILE_THRESHOLD"0.25);
define("SCR_UPD_LOOPS"4);

// MySQL Database Support

/* Use the following to create the mp3sym database, user and table :

CREATE DATABASE mp3sym;

GRANT ALL PRIVILEGES ON mp3sym.* TO mp3sym@localhost IDENTIFIED BY 'mp3sym';

CREATE TABLE mp3sym ( `mp3_hash` CHAR(32) NOT NULL, `mp3_genre` INT NOT NULL, PRIMARY KEY (`mp3_hash`) );

*/

define("USE_MYSQL"true);
define("MYSQL_HOST""localhost");
define("MYSQL_USER""mp3sym");
define("MYSQL_PASS""mp3sym");
define("MYSQL_DB""mp3sym");

// End of MySQL Database Support

include "/home/six/id3.class.php";

function 
ewait() {

    static 
$w;

    echo 
chr(8);
    
$w = ($w+1)%4;

    switch (
$w) {

        case 
0: echo "|"; break;
        case 
1: echo "/"; break;
        case 
2: echo "-"; break;
        case 
3: echo "\\"; break;

    }

}

echo 
"mp3 symlinks-by-id3-genre creator (c)2003 by sIX / aEGIS\n--------------------------------------------------------\n\n";

// Load id3 cache

$id3_cache = array();

if (
USE_MYSQL) {

    echo 
"loading ID3 cache         ... ";
    
    
mysql_connect(MYSQL_HOSTMYSQL_USERMYSQL_PASS);
    
mysql_select_db(MYSQL_DB);

    
$q mysql_query("select * from mp3sym");
    while (
$r mysql_fetch_row($q)) $id3_cache[$r[0]] = $r[1];
    
mysql_free_result($q);

    echo 
"OK (".count($id3_cache)." entries)\n";

}

// Get dir listing

echo "getting directory listing ... ";

$cmd "find ".MP3_DIR." -iname \"*.mp3\" -follow | grep -v \"".SYM_DIR."\" 2>/dev/null";
$files explode("\n"trim(`$cmd`));
$nfiles count($files);

echo 
"OK (".$nfiles." files)\n";

// Sort in "sets"

echo "building file sets        ... ";

$sets = array();

foreach (
$files as $fname) {

    
$sdir DIRECTORY_SEPARATOR.strtok($fnameDIRECTORY_SEPARATOR);
    for (
$a=0$a<=DIR_LEVEL$a++) $sdir .= DIRECTORY_SEPARATOR.strtok(DIRECTORY_SEPARATOR);
    
$sname strtok("");

    if (
is_array($sets[$sdir])) {

        
$sets[$sdir]["files"][] = $sname;

    } else {
    
        
$set = array();
        
$set["dir"] = $sdir;
        
$set["files"] = array($sname);
    
        
$sets[$sdir] = $set;

    }

}

echo 
"OK (".count($sets)." sets)\n";

// Read ID3 tags

$all_genres id3::genres();

echo 
"reading ID3 tags          ... ";

echo 
" ";
$ls "";

$used_genres = array();

foreach (
$sets as $k=>$set) {

    
$s_genres = array();
    
$tot_genres 0;

    foreach (
$set["files"] as $fname) {
    
        
$cfn $set["dir"].DIRECTORY_SEPARATOR.$fname;
        
$hash md5($cfn);
        
        if (isset(
$id3_cache[$hash])) {

            
$id3_genre $all_genres[$id3_cache[$hash]];
        
        } else {
        
            
$id3 = new id3($set["dir"].DIRECTORY_SEPARATOR.$fname);
            
mysql_query("REPLACE INTO mp3sym VALUES ('".$hash."', ".$id3->genreno.")");
            
$id3_genre $id3->genre;

        }
        
        if (
$id3_genre) {
            
            ++
$s_genres[$id3_genre];
            ++
$tot_genres;

        }

    }

    
$s_g = array();
    
    foreach (
$s_genres as $genre=>$nb) if (($nb/$tot_genres)>=GENRE_FILE_THRESHOLD) {
        
        if (
count($s_g)==0) {

            ++
$tot_sets_with_genre;
            
$tot_files_with_genre += count($set["files"]);
        
        }
        
        
$s_g[]=$genre;

        ++
$used_genres[$genre];
        
    }

    
$sets[$k]["genres"] = $s_g;

    
$g_fnum += count($set["files"]);
    
    if (
$l++%SCR_UPD_LOOPS==0) {

        for (
$a=0$a<strlen($ls); $a++) echo chr(8);
        
ewait();

        
$ls " (".(int)$g_fnum."/".$nfiles." ".sprintf("%.1f", ($g_fnum/$nfiles)*100)."%)";
        echo 
$ls;

    }

//    if ($g_fnum>1000) break;

}

unset(
$id3_cache);

for (
$a=0$a<=strlen($ls); $a++) echo chr(8);

echo 
"OK (".count($used_genres)." genres, ".$tot_sets_with_genre."/".count($sets)." sets, ".$tot_files_with_genre."/".count($files)." files)\n";

arsort($used_genres);

// (re)create direcotries

echo "recreating directories    ... ";

$cmd "ls -1 \"".SYM_DIR."\"";
$ex_dirs explode("\n"trim(`$cmd`));

$rem_dirs $cre_dirs 0;

foreach (
$ex_dirs as $ex) {

    
$cmd "rm -f \"".SYM_DIR.$ex."/\"*";
    
system($cmd);
    
$cmd "rm -rf \"".SYM_DIR.$ex."\"";
    
system($cmd);

    ++
$rem_dirs;

}

foreach (
$used_genres as $ug=>$fn) {

    
$cmd "mkdir -p \"".SYM_DIR.$ug."\"";
    
system($cmd);

    ++
$cre_dirs;

}

echo 
"OK (".(int)$rem_dirs." removed, ".(int)$cre_dirs." created)\n";

// create symlinks

echo "creating symbolic links   ... ";

echo 
" ";

foreach (
$sets as $set) {

    if (
is_array($set["genres"])) foreach ($set["genres"] as $sg) {

        
$cmd "ln -s \"".$set["dir"]."\" \"".SYM_DIR.$sg."/\"";
        
system($cmd);

        ++
$cre_sl;
    
    }

    if (
$l++%(SCR_UPD_LOOPS*10)==0ewait();    

}

echo 
chr(8);
echo 
"OK (".(int)$cre_sl." created)\n";

echo 
"\n";

system("chown -R six.six \"".SYM_DIR."\"");

echo 
"done\n";

?>