#!/usr/bin/php $name\n"; echo "
\n";
reset( $array );
while( list($k,$v) = each( $array ) )
{
echo "$k = $v\n";
}
echo "\n";
}
function str_to_sql( $str )
{
if( $str == "" )
{
return "null";
}
else
{
return "'" . pg_escape_string( $str ) . "'";
}
}
function number_to_sql( $number )
{
if( $number == "" )
{
return "null";
}
else
{
return $number;
}
}
function epoch_to_sql( $epoch )
{
if( $epoch == "" )
{
return "null";
}
else
{
return "to_timestamp( '" . strftime( $GLOBALS["strftimefmt"], $epoch ) .
"', " . $GLOBALS["datefmt"] . " )";
}
}
function db_remove( $conn, $reldir, $name, $type )
{
// echo "db_remove $type '$reldir/$name'\n";
if( $name == "" )
{
return;
}
$sql = "delete from " .
"ices2_oggfiles " .
" where " .
"iof_directory = " . str_to_sql( $reldir ) . " and " .
"iof_name = " . str_to_sql( $name );
// echo "SQL <$sql>\n";
pg_exec( $conn, $sql );
if( $type == "dir" )
{
if( $reldir == "/" )
{
$dir = $name;
}
else
{
$dir = $reldir . "/" . $name;
}
$dirlen = strlen($dir) + 1;
$dir = pg_escape_string( $dir );
$sql = "delete from " .
"ices2_oggfiles " .
"where " .
"iof_directory = '$dir' or " .
"substr( iof_directory, 1, $dirlen ) = '$dir/'";
// echo "SQL <$sql>\n";
pg_exec( $conn, $sql );
}
}
function db_insert( $conn, $reldir, $name, $props )
{
$type = $props["type"];
// echo "db_insert $type '$reldir/$name'\n";
if( $type == "file" )
{
$sql = "insert into ices2_oggfiles ( " .
"iof_directory, " .
"iof_name, " .
"iof_is_file, " .
"iof_title, " .
"iof_artist, " .
"iof_album, " .
"iof_track_nr, " .
"iof_genre, " .
"iof_length, " .
"iof_bitrate, " .
"iof_filesize, " .
"iof_date_mod " .
") values ( " .
str_to_sql( $reldir ) . ", " .
str_to_sql( $name ) . ", " .
"true, " .
str_to_sql( $props["title"] ) . ", " .
str_to_sql( $props["artist"] ) . ", " .
str_to_sql( $props["album"] ) . ", " .
str_to_sql( $props["track"] ) . ", " .
str_to_sql( $props["genre"] ) . ", " .
number_to_sql( $props["length"] ) . ", " .
number_to_sql( $props["bitrate"] ) . ", " .
number_to_sql( $props["filesize"] ) . ", " .
epoch_to_sql( $props["date_mod"] ) .
" )";
}
else
{
$sql = "insert into ices2_oggfiles ( " .
"iof_directory, " .
"iof_name, " .
"iof_is_file " .
") values ( " .
str_to_sql( $reldir ) . ", " .
str_to_sql( $name ) . ", " .
"false " .
" )";
}
pg_exec( $conn, $sql );
}
function db_update_file( $conn, $reldir, $name, $props )
{
$type = $props["type"];
// echo "db_update_file $type '$reldir/$name'\n";
if( $type != "file" )
{
return;
}
$sql = "update " .
"ices2_oggfiles " .
"set" .
" iof_title = " . str_to_sql( $props["title"] ) .
", iof_artist = " . str_to_sql( $props["artist"] ) .
", iof_album = " . str_to_sql( $props["album"] ) .
", iof_track_nr = " . str_to_sql( $props["track"] ) .
", iof_genre = " . str_to_sql( $props["genre"] ) .
", iof_length = " . number_to_sql( $props["length"] ) .
", iof_bitrate = " . number_to_sql( $props["bitrate"] ) .
", iof_filesize = " . number_to_sql( $props["filesize"] ) .
", iof_date_mod = " . epoch_to_sql( $props["date_mod"] ) .
" where " .
"iof_directory = " . str_to_sql( $reldir ) . " and " .
"iof_name = " . str_to_sql( $name );
// echo "SQL <$sql>\n";
pg_exec( $conn, $sql );
}
function get_db_dir( $conn, $reldir )
{
$dir = array();
$sql = "select " .
"iof_name, " .
"iof_is_file, " .
"iof_title, iof_artist, iof_album, iof_track_nr, " .
"iof_genre, iof_length, iof_bitrate, iof_filesize, " .
"extract(epoch from iof_date_mod) as iof_date_mod " .
"from " .
"ices2_oggfiles " .
"where ".
"iof_directory = '" . pg_escape_string($reldir) . "'";
$rs = pg_exec( $conn, $sql );
if( $rs )
{
while( $row = pg_fetch_array( $rs ) )
{
$node = array();
if( $row["iof_is_file"]== "t" )
{
$node["type"] = "file";
// echo "db file '$name'\n";
}
else
{
$node["type"] = "dir";
// echo "db dir '$name'\n";
}
$node["title"] = $row["iof_title"];
$node["artist"] = $row["iof_artist"];
$node["album"] = $row["iof_album"];
$node["track"] = $row["iof_track_nr"];
$node["genre"] = $row["iof_genre"];
$node["length"] = $row["iof_length"];
$node["bitrate"] = $row["iof_bitrate"];
$node["filesize"] = $row["iof_filesize"];
$node["date_mod"] = $row["iof_date_mod"];
$dir[$row["iof_name"]] = $node;
}
}
return $dir;
}
function get_ogg_info( $absfile, &$props )
{
$lines = array();
exec( "ogginfo " . escapeshellarg( $absfile ), $lines, $rc );
if( $rc != 0 )
{
return;
}
$n = count($lines);
$i = 0;
while( $i < $n && !ereg( "^Nominal bitrate: ", $lines[$i] ) )
{
$i++;
}
if( $i >= $n ) return;
$tmp = split( " *", $lines[$i] );
$props["bitrate"] = ereg_replace( "[.].*\$", "", $tmp[2] );
while( $i < $n && !ereg( "^User comments section follows", $lines[$i] ) )
{
$i++;
}
$i++;
if( $i >= $n ) return;
while( $i < $n && ereg( "^\t[a-z][a-z]*=", $lines[$i] ) )
{
$tmp = split( "=", trim( $lines[$i] ), 2 );
switch( $tmp[0] )
{
case "genre":
$props["genre"] = $tmp[1];
break;
case "title":
$props["title"] = $tmp[1];
break;
case "artist":
$props["artist"] = $tmp[1];
break;
case "album":
$props["album"] = $tmp[1];
break;
// tracknum ???
}
$i++;
}
while( $i < $n && !ereg( "^\tPlayback length: ", $lines[$i] ) )
{
$i++;
}
if( $i >= $n ) return;
$tmp = split( " *", $lines[$i] );
$tmp = split( ":", $tmp[2] );
$tn = count($tmp);
$i = 0;
$secs = 0;
while( $i < $tn )
{
switch( substr( $tmp[$i], strlen($tmp[$i])-1 ) )
{
case "h":
$secs += 3600 * substr( $tmp[$i], 0, strlen($tmp[$i])-1 );
break;
case "m":
$secs += 60 * substr( $tmp[$i], 0, strlen($tmp[$i])-1 );
break;
case "s":
$secs += ereg_replace( "[.m].*\$", "", $tmp[$i] );
break;
}
$i++;
}
$props["length"] = $secs;
}
function get_fs_dir( $reldir, $music_dir )
{
$absdir = $music_dir . "/" . $reldir;
$dir = array();
if( is_dir( $absdir ) )
{
$dh = opendir( $absdir );
if( $dh )
{
while( $name = readdir( $dh ) )
{
if( substr( $name, 0, 1 ) != "." )
{
$node = array( "indb" => false );
if( is_dir( $absdir . "/" . $name ) )
{
$node["type"] = "dir";
// echo "fs dir '$name'\n";
}
else if( is_file( $absdir . "/" . $name ) &&
ereg( "[.]ogg\$", $name ) )
{
$abspath = $absdir . "/" . $name;
$node["type"] = "file";
$node["filesize"] = filesize( $abspath );
$node["date_mod"] = filemtime( $abspath );
// echo "fs file '$name'\n";
}
if( isset( $node["type"] ) )
{
$dir[$name] = $node;
}
}
}
closedir( $dh );
}
}
return $dir;
}
function scan_files( $conn, $reldir, $music_dir )
{
echo "*** directory '$reldir' ***\n";
$dbfiles = get_db_dir( $conn, $reldir );
$fsfiles = get_fs_dir( $reldir, $music_dir );
reset( $dbfiles );
while( list( $name, $props ) = each( $dbfiles ) )
{
if( !isset( $fsfiles[$name] ) )
{
echo " removed '$name'\n";
db_remove( $conn, $reldir, $name, $props["type"] );
}
else if( $fsfiles[$name]["type"] != $props["type"] )
{
echo " mismatch '$name'\n";
db_remove( $conn, $reldir, $name, $props["type"] );
}
else
{
if( $props["type"] == "file" &&
( $fsfiles[$name]["date_mod"] != $props["date_mod"] ||
$fsfiles[$name]["filesize"] != $props["filesize"] ) )
{
echo " modified '$name'\n";
// echo " " . $props["date_mod"] . "\n";
// echo " " . $fsfiles[$name]["date_mod"] . "\n";
$props["date_mod"] = $fsfiles[$name]["date_mod"];
$props["filesize"] = $fsfiles[$name]["filesize"];
if( $reldir == "/" )
{
$abspath = $music_dir . "/" . $name;
}
else
{
$abspath = $music_dir . "/" . $reldir . "/" . $name;
}
get_ogg_info( $abspath, $props );
db_update_file( $conn, $reldir, $name, $props );
}
$fsfiles[$name]["indb"] = true;
}
}
reset( $fsfiles );
while( list( $name, $props ) = each( $fsfiles ) )
{
if( $reldir == "/" )
{
$newreldir = $name;
$abspath = $music_dir . "/" . $name;
}
else
{
$newreldir = $reldir . "/" . $name;
$abspath = $music_dir . "/" . $reldir . "/" . $name;
}
if( !$props["indb"] )
{
echo " added '$name'\n";
if( $props["type"] == "file" )
{
get_ogg_info( $abspath, $props );
}
db_insert( $conn, $reldir, $name, $props );
}
if( $props["type"] == "dir" )
{
scan_files( $conn, $newreldir, $music_dir );
}
}
}
// printarray( "_SERVER", $_SERVER );
if( !isset( $_SERVER["SERVER_SOFTWARE"] ) )
{
$conn = db_connect();
scan_files( $conn, "/", $music_dir );
}
?>