/** * Updates the cache using $this as the base node. * * @author Ben Dodson <*****@*****.**> * @version 11/12/04 * @since 5/13/04 */ function updateCacheHelper(&$be, &$link, $recursive, $root, $showStatus, $force = false, $readTags = true) { global $sql_usr, $sql_type, $sql_pw, $sql_socket, $sql_db, $audio_types, $video_types, $playlist_types, $ext_graphic, $default_art, $track_num_seperator, $hierarchy, $backend; // Make upgrades work. // This should be a more general routine, // like getSetting("playlist_types"); if (!isset($playlist_types)) { $playlist_types = "m3u"; } // The database adaptor builds itself based on the filesystem. if ($root !== false) { $media_dir = $root; } else { $media_dir = $this->getFilePath(); } if (!is_readable($media_dir)) { return false; } $mySlashedName = jz_db_escape($this->getName()); $pathArray = $this->getPath(); $nodePath = $this->getPath("String"); $slashedNodePath = jz_db_escape($nodePath); // SQL no likey the quotes. $fullSlashedNodePath = jz_db_escape($media_dir); $level = $this->getLevel(); $ptype = findPType($this); /* Echo out our current status, if they want it: */ if ($showStatus === true) { showStatus($media_dir); } else { if ($showStatus == "cli") { echo word("Scanning: ") . $media_dir . "\n"; } } // Now handle $this. $mdate = filemtime($media_dir); if ($mdate > ($curtime = time())) { if (@touch($media_dir) === false) { $mdate = $curtime - ($mdate - $curtime); } else { $mdate = filemtime($media_dir); } } $stamp = $be->getUpdated($media_dir); $sql = "INSERT INTO jz_nodes(name,path,filepath,ptype,level,date_added,my_id) "; $sql .= "VALUES('{$mySlashedName}','{$slashedNodePath}','{$fullSlashedNodePath}','{$ptype}',{$level},'{$mdate}','" . uniqid("T") . "')"; // ADD MORE INFO TO DB. if (!jz_db_query($link, $sql)) { // the node was already in the database. $sql = "UPDATE jz_nodes SET valid = 'true' "; $sql .= "WHERE path " . jz_db_case_sensitive() . " '{$slashedNodePath}'"; jz_db_query($link, $sql); } writeLogData('importer', "Importing node: " . $mySlashedName . " - " . $fullSlashedNodePath); // Now move inside $this's path. if (!($handle = opendir($media_dir))) { die("Could not access directory {$media_dir} in database::updateCacheHelper."); } // let's look for the best files to use while we are scanning this directory: $leafcount = 0; $nodecount = 0; $bestImage = ""; $bestDescription = ""; while ($file = readdir($handle)) { $nextPath = $nodePath == "" ? $file : $nodePath . "/" . $file; $nextFile = $media_dir . "/" . $file; $slashedNextFile = jz_db_escape($nextFile); $slashedFileName = jz_db_escape($file); $slashedFilePath = jz_db_escape($nextPath); if ($file == "." || $file == "..") { continue; } else { if (is_dir($nextFile)) { $next =& new jzMediaNode($nextPath); if ($recursive) { $next->updateCacheHelper($be, $link, true, $nextFile, $showStatus, $force, $readTags); } else { // NOT RECURSIVE, just mark as valid, or add if it wasn't there. $sdate = filemtime($nextFile); if ($sdate > ($curtime = time())) { if (@touch($nextFile) === false) { $sdate = $curtime - ($sdate - $curtime); } else { $sdate = filemtime($nextFile); } } $spt = findPType($next); if ($backend == "mysql") { $n1 = jz_db_query($link, "SELECT COUNT(*) FROM jz_nodes WHERE path LIKE '{$slashedFilePath}'"); $n2 = jz_db_query($link, "SELECT COUNT(*) FROM jz_nodes WHERE path LIKE BINARY '{$slashedFilePath}'"); if ($n1->data[0][0] - $n2->data[0][0] > 0) { // A folder was renamed. jz_db_query($link, "DELETE FROM jz_nodes WHERE path LIKE '{$slashedFilePath}%'"); } } $sqln = "INSERT INTO jz_nodes(name,path,filepath,ptype,level,date_added,my_id)"; $sqln .= " VALUES('{$slashedFileName}','{$slashedFilePath}','{$slashedNextFile}','{$spt}',{$level}+1,'{$sdate}','" . uniqid("T") . "')"; $sqlu = "UPDATE jz_nodes SET valid = 'true' "; $sqlu .= "WHERE path " . jz_db_case_sensitive() . " '{$slashedFilePath}'"; jz_db_query($link, $sqln) || jz_db_query($link, $sqlu); } $nodecount++; } else { // is a regular file. // That means check for media file (leaf), // or picture or text for $this. if (preg_match("/\\.(txt)\$/i", $file)) { // TODO: GET THE CORRECT DESCRIPTION IN $bestDescription // $bestDescription = $slashedNodePath . "/" . jz_db_escape($file); // This will need testing... $descFile = $media_dir . "/" . jz_db_escape($file); if (is_file($descFile)) { $bestDescription = jz_db_escape(nl2br(implode("\n", @file($descFile)))); } } if (preg_match("/\\.({$ext_graphic})\$/i", $file) && !stristr($file, ".thumb.")) { $fav_image_name = $default_art; // An image if (@preg_match("/({$fav_image_name})/i", $file)) { $bestImage = $slashedNextFile; } else { if ($bestImage == "") { $bestImage = $slashedNextFile; } } } else { if (preg_match("/\\.({$playlist_types})\$/i", $file)) { echo 'm3u: ' + $file; $ext = substr($file, strrpos($file, '.') + 1); if (0 == strcasecmp($ext, 'm3u')) { $m3u_lines = file($nextFile); $is_local_m3u = false; foreach ($m3u_lines as $line) { if ($lines[0] == '#') { // TODO: get metadata. continue; } else { if (false === strpos($lines[0], '://')) { $is_local_m3u = true; break; } $mediaref = $lines[0]; // add to DB $mdate = filemtime($nextFile); if ($mdate > ($curtime = time())) { if (@touch($nextFile) === false) { $mdate = $curtime - ($mdate - $curtime); } else { $mdate = filemtime($nextFile); } } $leafcount++; addWebTrack($mediaref, $nodePath, $mdate, $level, $link); } } } } else { if (preg_match("/\\.({$audio_types})\$/i", $file) || preg_match("/\\.({$video_types})\$/i", $file)) { // A media file // add it as an element. $leafcount++; $mdate = filemtime($nextFile); if ($mdate > ($curtime = time())) { if (@touch($nextFile) === false) { $mdate = $curtime - ($mdate - $curtime); } else { $mdate = filemtime($nextFile); } } // First, try putting me in the DB. $slashedFileName = jz_db_escape($file); $slashedFilePath = $slashedNodePath == "" ? $slashedFileName : $slashedNodePath . "/" . $slashedFileName; $fullSlashedFilePath = jz_db_escape($media_dir) . "/" . $slashedFileName; $mid = uniqid("T"); $sql = "INSERT INTO jz_nodes(name,path,filepath,ptype,level,date_added,leaf,my_id) "; $sql .= "VALUES('{$slashedFileName}','{$slashedFilePath}','{$fullSlashedFilePath}','track',{$level}+1,'{$mdate}','true','" . $mid . "') "; $updatesql = "UPDATE jz_nodes SET valid = 'true' WHERE path " . jz_db_case_sensitive() . " '{$slashedFilePath}'"; jz_db_query($link, $sql) || jz_db_query($link, $updatesql); // Now, did they want to force this? if ($stamp < $mdate or $force) { $track =& new jzMediaTrack($nextPath); $track->filepath = $track->getPath("String"); $track->playpath = $nextFile; if ($readTags === true) { $meta = $track->getMeta("file"); // read meta info from the file; } else { $meta = array(); $meta['bitrate'] = ""; $meta['length'] = ""; $meta['size'] = ""; $meta['title'] = ""; $meta['artist'] = ""; $meta['album'] = ""; $meta['year'] = ""; $meta['number'] = ""; $meta['genre'] = ""; $meta['frequency'] = ""; $meta['comment'] = ""; $meta['lyrics'] = ""; $meta['type'] = ""; } $pname = jz_db_escape($file); $bitrate = $meta['bitrate']; $length = $meta['length']; $filesize = $meta['size']; $name = jz_db_escape($meta['title']); $artist = jz_db_escape($meta['artist']); $album = jz_db_escape($meta['album']); $year = jz_db_escape($meta['year']); $track = $meta['number']; $genre = jz_db_escape($meta['genre']); $frequency = $meta['frequency']; $description = jz_db_escape($meta['comment']); $lyrics = jz_db_escape($meta['lyrics']); $fileExt = $meta['type']; // Now let's see if there is a description file... $desc_file = str_replace("." . $fileExt, "", $media_dir . "/" . $file) . ".txt"; $long_description = ""; if (@is_file($desc_file) and filesize($desc_file) != 0) { // Ok, let's read the description file $handle2 = fopen($desc_file, "rb"); $long_description = jz_db_escape(fread($handle2, filesize($desc_file))); fclose($handle2); } // Now let's see if there is a thumbnail for this track $thumb_file = jz_db_escape(searchThumbnail($media_dir . "/" . $file)); $sql = "INSERT INTO jz_tracks(path,level,my_id,filepath,name,trackname,bitrate,filesize,frequency,length,lyrics,genre,artist,album,year,number,extension)\n\t\t\t VALUES('{$slashedFilePath}',{$level}+1,'" . $mid . "','{$fullSlashedFilePath}','{$pname}','{$name}','{$bitrate}','{$filesize}','{$frequency}','{$length}','{$lyrics}','{$genre}','{$artist}','{$album}','{$year}','{$track}','{$fileExt}')"; // Now let's update status and log this if (isset($_SESSION['jz_import_full_progress'])) { $_SESSION['jz_import_full_progress']++; } else { $_SESSION['jz_import_full_progress'] = 1; } writeLogData('importer', "Importing track: " . $fullSlashedFilePath); $updatesql = "UPDATE jz_tracks SET valid = 'true',\n\t\t\t\t\tlevel = {$level}+1,\n\t\t\t\t\ttrackname = '{$name}',\n\t\t\t\t\tbitrate = '{$bitrate}',\n\t\t\t\t\tfilesize = '{$filesize}',\n\t\t\t\t\tfrequency = '{$frequency}',\n\t\t\t\t\tlength = '{$length}',"; if (!isNothing($lyrics)) { $updatesql .= "lyrics = '{$lyrics}',"; } $updatesql .= "year = '{$year}',\n\t\t\t\t\tgenre = '{$genre}',\n\t\t\t\t\tartist = '{$artist}',\n\t\t\t\t\talbum = '{$album}',\n\t\t\t\t\tnumber = '{$track}',\n\t\t\t\t\textension = '{$fileExt}'"; $updatesql .= " WHERE path " . jz_db_case_sensitive() . " '{$slashedFilePath}'"; jz_db_query($link, $sql) || jz_db_query($link, $updatesql); } else { $sql = "UPDATE jz_tracks SET valid = 'true' WHERE path " . jz_db_case_sensitive() . " '{$slashedFilePath}'"; jz_db_query($link, $sql); } // last thing: add thumb and/or descriptions. $sql = "valid = 'true'"; if (isset($thumb_file)) { $sql .= ", main_art = '{$thumb_file}'"; } if (isset($description)) { $sql .= ", descr = '{$description}'"; } if (isset($long_description)) { $sql .= ", longdesc = '{$long_description}'"; } jz_db_query($link, "UPDATE jz_nodes SET {$sql} WHERE path " . jz_db_case_sensitive() . " '{$slashedFilePath}'"); } } } } } } // Back to $this node: // add new info to $this's database entry. if ($readTags === true) { $be->setUpdated($media_dir); } else { $be->setUpdated($media_dir, 0); // pretend it hasn't been updated since 1979. } $sqlUpdate = "nodecount = {$nodecount}, leafcount = {$leafcount}"; if ($bestImage != "") { $sqlUpdate .= ", main_art = '{$bestImage}'"; } if ($bestDescription != "") { //$bestDescription = jz_db_escape(file_get_contents($bestDescription)); $sqlUpdate .= ", longdesc = '{$bestDescription}'"; } $sql = "UPDATE jz_nodes SET {$sqlUpdate} WHERE path LIKE '{$slashedNodePath}'"; if (false === jz_db_query($link, $sql)) { die(jz_db_error($link)); } $slash = $level == 0 ? "" : "/"; // all done; remove everything beyond $this's path that is still not valid. $sql = "DELETE FROM jz_nodes WHERE "; $sql .= "level > {$level} AND path LIKE '{$slashedNodePath}{$slash}%' AND valid = 'false'"; $sql .= " AND filepath LIKE '{$fullSlashedNodePath}%'"; jz_db_query($link, $sql); $sql = "DELETE FROM jz_tracks WHERE "; $sql .= "path LIKE '{$slashedNodePath}{$slash}%' AND valid = 'false'"; $sql .= " AND filepath LIKE '{$fullSlashedNodePath}%'"; jz_db_query($link, $sql); }
function updateCacheHelper($recursive, $levelsLeft, $root, $showStatus, $readID3) { global $audio_types, $video_types, $ext_graphic, $default_art, $backend, $track_num_seperator, $hierarchy, $protocols; if ($root !== false) { $mediapath = $root; } else { $mediapath = $this->getFilePath(); } if ($mediapath == "-") { // let's find it.. $parent = $this->getParent(); $mediapath = $parent->getFilePath() . "/" . $this->getName(); } $nodepath = $this->getPath("String"); /* Echo out our current status, if they want it: */ if ($showStatus === true) { showStatus($mediapath); } else { if ($showStatus == "cli") { echo word("Scanning: ") . $mediapath . "\n"; } } // First add $this. // Was I already cached? $cache = $this->readCache(); if ($cache[0] == "-") { $cache[0] = $nodepath; } if ($cache[13] == "-") { $cache[13] = $mediapath; } if ($cache[6] == "-") { $cache[6] = jz_filemtime($mediapath); } if ($cache[15] == "-") { $ptype = findPType($this); $cache[15] = $ptype; } $blankfilecache = blankCache("track"); // Recurse and add $this's media files. if (!($handle = opendir($mediapath))) { die("Could not access directory {$mediapath}"); } // scan for info while going through directory: $trackcount = 0; $new_nodes = $cache[7]; $new_tracks = $cache[8]; $bestImage = ""; $bestDescription = ""; while ($file = readdir($handle)) { $childpath = $nodepath == "" ? $file : $nodepath . "/" . $file; $fullchildpath = $mediapath . "/" . $file; if ($file == "." || $file == "..") { continue; } else { if (is_dir($fullchildpath)) { if ($recursive) { $next =& new jzMediaNode($childpath); $next->updateCacheHelper(true, $levelsLeft, $fullchildpath, $showStatus, $readID3); } else { if ($levelsLeft === false && $this->getNaturalDepth() > 1) { $next =& new jzMediaNode($childpath); $next->updateCacheHelper(false, $this->getNaturalDepth() - 2, $fullchildpath, $showStatus, $readID3); } else { if ($levelsLeft > 0) { $next =& new jzMediaNode($childpath); $next->updateCacheHelper(false, $levelsLeft - 1, $fullchildpath, $showStatus, $readID3); } } } if ($new_nodes != array()) { $key = array_search($file, $new_nodes); if (false === $key) { $new_nodes[] = $file; $next =& new jzMediaNode($childpath); } } else { $new_nodes[] = $file; $next =& new jzMediaNode($childpath); } } else { if (preg_match("/\\.(txt)\$/i", $file)) { // TODO: GET THE CORRECT DESCRIPTION IN $bestDescription // $bestDescription = $fullchildpath; } else { if (preg_match("/\\.({$ext_graphic})\$/i", $file) && !stristr($file, ".thumb.")) { // An image if (@preg_match("/({$default_art})/i", $file)) { $bestImage = $fullchildpath; } else { if ($bestImage == "") { $bestImage = $fullchildpath; } } } else { if (preg_match("/\\.({$audio_types})\$/i", $file) || preg_match("/\\.({$video_types})\$/i", $file)) { //* * * A track * * * *// // Add it to the track list. if ($new_tracks != array()) { $key = array_search($file, $new_tracks); if (false === $key) { $new_tracks[] = $file; } } else { $new_tracks[] = $file; } // And at it's details.. $childnode =& new jzMediaTrack($childpath); if ($cache[2] == "-" || $cache[2] < date("U", jz_filemtime($fullchildpath)) || !$childnode->readCache()) { // Add as a new/updated track. $filecache[$trackcount] = $childnode->readCache(); if ($filecache[$trackcount][0] == "-") { $filecache[$trackcount][0] = $fullchildpath; $filecache[$trackcount][6] = jz_filemtime($fullchildpath); $filecache[$trackcount][2] = $file; } ////////// // META // ////////// $track =& new jzMediaTrack($childpath); $track->playpath = $fullchildpath; if ($readID3 === true) { $meta = $track->getMeta("file"); // read meta info from the file; } else { $meta = array(); } $filecache[$trackcount][7] = $meta['title']; $filecache[$trackcount][8] = $meta['frequency']; $filecache[$trackcount][9] = $meta['comment']; $filecache[$trackcount][11] = $meta['year']; $filecache[$trackcount][13] = $meta['size']; $filecache[$trackcount][14] = $meta['length']; $filecache[$trackcount][15] = $meta['genre']; $filecache[$trackcount][16] = $meta['artist']; $filecache[$trackcount][17] = $meta['album']; $filecache[$trackcount][18] = $meta['type']; $filecache[$trackcount][19] = $meta['lyrics']; $filecache[$trackcount][20] = $meta['bitrate']; $filecache[$trackcount][21] = $meta['number']; // Now let's see if there is a description file... $desc_file = str_replace("." . $meta['type'], "", $fullchildpath) . ".txt"; $long_description = ""; if (is_file($desc_file) and filesize($desc_file) != 0) { // Ok, let's read the description file $handle2 = fopen($desc_file, "rb"); $filecache[$trackcount][10] = fread($handle2, filesize($desc_file)); fclose($handle2); } else { $filecache[$trackcount][10] = ""; } // Now let's see if there is a thumbnail for this track $filecache[$trackcount][1] = searchThumbnail($fullchildpath); } else { // slow but necessary.. //$filecache[$trackcount] = $childnode->readCache(); } $trackcount++; // Let's track this writeLogData('importer', "Importing track: " . $fullchildpath); $_SESSION['jz_import_full_progress']++; } } } } } } if ($new_nodes != array()) { foreach ($new_nodes as $i => $my_path) { $me =& new jzMediaNode($nodepath . "/" . $my_path); if ($me->getFilePath() == "-") { $arr = explode("/", $my_path); $mfp = $this->getFilePath() . "/" . $arr[sizeof($arr) - 1]; } else { $mfp = $me->getFilePath(); } if (!is_dir($mfp)) { // TODO: The commented out part should check to see if there are 'permanent' subnodes. // It is possible a directory was created to house links (and does not have // any data on the filesystem) $remove_me = true; $list = $me->getSubNodes("tracks", -1); foreach ($list as $el) { if (stristr($el->getFilePath(), "://")) { $remove_me = false; break; } } if ($remove_me) { $me->deleteCache(); unset($new_nodes[$i]); } } } } if ($new_tracks != array()) { foreach ($new_nodes as $i => $my_path) { $me =& new jzMediaTrack($nodepath . "/" . $my_path); if (!is_file($fpath = $me->getFilePath())) { $valid = false; $parr = explode("|", $protocols); if (strlen($fpath) > 2) { foreach ($parr as $p) { if (stristr($fpath, $p) !== false) { $valid = true; } } } if (!$valid) { $me->deleteCache(); unset($new_tracks[$i]); } } } } // Update $this if ($bestImage != "") { $cache[1] = $bestImage; } if ($bestDescription != "") { $cache[10] = file_get_contents($bestDescription); } $cache[2] = date("U"); natcasesort($new_nodes); $cache[7] = array_values($new_nodes); natcasesort($new_tracks); $cache[8] = array_values($new_tracks); // * * * * * * * * // Write the cache. $this->writeCache($cache, "nodes"); if ($filecache != array()) { $this->writeCache($filecache, "tracks"); } }