1<?php 2///////////////////////////////////////////////////////////////// 3/// getID3() by James Heinrich <info@getid3.org> // 4// available at https://github.com/JamesHeinrich/getID3 // 5// or https://www.getid3.org // 6// or http://getid3.sourceforge.net // 7// // 8// /demo/demo.dirscan.php - part of getID3() // 9// Directory Scanning and Caching CLI tool for batch media // 10// file processing with getID3() // 11// by Karl G. Holz <newaeonØmac*com> // 12// /// 13///////////////////////////////////////////////////////////////// 14 15die('For security reasons, this demo has been disabled. It can be enabled by removing line '.__LINE__.' in demos/'.basename(__FILE__)); 16 17 18/** 19* This is a directory scanning and caching cli tool for getID3(). 20* 21* use like so for the default sqlite3 database, which is hidden: 22* 23* cd <path you want to start scanning from> 24* php <path to getid3 files>/demo.dirscan.php 25* 26* or 27* 28* php <path to getid3 files>/demo.dirscan.php <dir to scan> <file ext in csv list> 29* 30* Supported Cache Types (this extension) 31* 32* SQL Databases: 33* 34* cache_type 35* ------------------------------------------------------------------- 36* mysql 37 38$cache='mysql'; 39$database['host']=''; 40$database['database']=''; 41$database['username']=''; 42$database['password']=''; 43$database['table']=''; 44 45* sqlite3 46 47$cache='sqlite3'; 48$database['table']='getid3_cache'; 49$database['hide']=true; 50 51*/ 52$dir = $_SERVER['PWD']; 53$media = array('mp4', 'm4v', 'mov', 'mp3', 'm4a', 'jpg', 'png', 'gif'); 54$database = array(); 55/** 56* configure the database bellow 57*/ 58// sqlite3 59$cache = 'sqlite3'; 60$database['table'] = 'getid3_cache'; 61$database['hide'] = true; 62/** 63 * mysql 64$cache = 'mysql'; 65$database['host'] = ''; 66$database['database'] = ''; 67$database['username'] = ''; 68$database['password'] = ''; 69$database['table'] = ''; 70*/ 71 72/** 73* id3 tags class file 74*/ 75require_once(dirname(__FILE__).'/getid3.php'); 76/** 77* dirscan scans all directories for files that match your selected filetypes into the cache database 78* this is useful for a lot of media files 79* 80* 81* @package dirscan 82* @author Karl Holz 83* 84*/ 85 86class dirscan { 87 /** 88 * type_brace() * Might not work on Solaris and other non GNU systems * 89 * 90 * Configures a filetype list for use with glob searches, 91 * will match uppercase or lowercase extensions only, no mixing 92 * @param string $dir directory to use 93 * @param mixed $search cvs list of extentions or an array 94 * @return string or null if checks fail 95 */ 96 private function type_brace($dir, $search=array()) { 97 $dir = str_replace(array('///', '//'), array('/', '/'), $dir); 98 if (!is_dir($dir)) { 99 return null; 100 } 101 if (!is_array($search)) { 102 $e = explode(',', $search); 103 } elseif (count($search) < 1) { 104 return null; 105 } else { 106 $e = $search; 107 } 108 $ext = array(); 109 foreach ($e as $new) { 110 $ext[] = strtolower(trim($new)); 111 $ext[] = strtoupper(trim($new)); 112 } 113 $b = $dir.'/*.{'.implode(',', $ext).'}'; 114 return $b; 115 } 116 117 /** 118 * this function will search 4 levels deep for directories 119 * will return null on failure 120 * @param string $root 121 * @return array return an array of dirs under root 122 * @todo figure out how to block tabo directories with ease 123 */ 124 private function getDirs($root) { 125 switch ($root) { // return null on tabo directories, add as needed -> case {dir to block }: this is not perfect yet 126 case '/': 127 case '/var': 128 case '/etc': 129 case '/home': 130 case '/usr': 131 case '/root': 132 case '/private/etc': 133 case '/private/var': 134 case '/etc/apache2': 135 case '/home': 136 case '/tmp': 137 case '/var/log': 138 return null; 139 break; 140 default: // scan 4 directories deep 141 if (!is_dir($root)) { 142 return null; 143 } 144 $dirs = array_merge(glob($root.'/*', GLOB_ONLYDIR), glob($root.'/*/*', GLOB_ONLYDIR), glob($root.'/*/*/*', GLOB_ONLYDIR), glob($root.'/*/*/*/*', GLOB_ONLYDIR), glob($root.'/*/*/*/*/*', GLOB_ONLYDIR), glob($root.'/*/*/*/*/*/*', GLOB_ONLYDIR), glob($root.'/*/*/*/*/*/*/*', GLOB_ONLYDIR)); 145 break; 146 } 147 if (count($dirs) < 1) { 148 $dirs = array($root); 149 } 150 return $dirs; 151 } 152 153 /** 154 * file_check() check the number of file that are found that match the brace search 155 * 156 * @param string $search 157 * @return mixed 158 */ 159 private function file_check($search) { 160 $t = array(); 161 $s = glob($search, GLOB_BRACE); 162 foreach ($s as $file) { 163 $t[] = str_replace(array('///', '//'), array('/', '/'), $file); 164 } 165 if (count($t) > 0) { 166 return $t; 167 } 168 return null; 169 } 170 171 function getTime() { 172 return microtime(true); 173 // old method for PHP < 5 174 //$a = explode(' ', microtime()); 175 //return (double) $a[0] + $a[1]; 176 } 177 178 179 /** 180 * 181 * @param string $dir 182 * @param mixed $match search type name extentions, can be an array or csv list 183 * @param string $cache caching extention, select one of sqlite3, mysql, dbm 184 * @param array $opt database options, 185 */ 186 function scan_files($dir, $match, $cache='sqlite3', $opt=array('table'=>'getid3_cache', 'hide'=>true)) { 187 $Start = self::getTime(); 188 switch ($cache) { // load the caching module 189 case 'sqlite3': 190 if (!class_exists('getID3_cached_sqlite3')) { 191 require_once(dirname(__FILE__)).'/extension.cache.sqlite3.php'; 192 } 193 $id3 = new getID3_cached_sqlite3($opt['table'], $opt['hide']); 194 break; 195 case 'mysql': 196 if (!class_exists('getID3_cached_mysql')) { 197 require_once(dirname(__FILE__)).'/extension.cache.mysql.php'; 198 } 199 $id3 = new getID3_cached_mysql($opt['host'], $opt['database'], $opt['username'], $opt['password'], $opt['table']); 200 break; 201 // I'll leave this for some one else 202 //case 'dbm': 203 // if (!class_exists('getID3_cached_dbm')) { 204 // require_once(dirname(__FILE__)).'/extension.cache.dbm.php'; 205 // } 206 // die(' This has not be implemented, sorry for the inconvenience'); 207 // break; 208 default: 209 die(' You have selected an Invalid cache type, only "sqlite3" and "mysql" are valid'."\n"); 210 break; 211 } 212 $count = array('dir'=>0, 'file'=>0); 213 $dirs = self::getDirs($dir); 214 if ($dirs !== null) { 215 foreach ($dirs as $d) { 216 echo ' Scanning: '.$d."\n"; 217 $search = self::type_brace($d, $match); 218 if ($search !== null) { 219 $files = self::file_check($search); 220 if ($files !== null) { 221 foreach ($files as $f) { 222 echo ' * Analyzing '.$f.' '."\n"; 223 $id3->analyze($f); 224 $count['file']++; 225 } 226 $count['dir']++; 227 } else { 228 echo 'Failed to get files '."\n"; 229 } 230 } else { 231 echo 'Failed to create match string '."\n"; 232 } 233 } 234 echo '**************************************'."\n"; 235 echo '* Finished Scanning your directories '."\n*\n"; 236 echo '* Directories '.$count['dir']."\n"; 237 echo '* Files '.$count['file']."\n"; 238 $End = self::getTime(); 239 $t = number_format(($End - $Start) / 60, 2); 240 echo '* Time taken to scan '.$dir.' '.$t.' min '."\n"; 241 echo '**************************************'."\n"; 242 } else { 243 echo ' failed to get directories '."\n"; 244 } 245 } 246} 247 248if (PHP_SAPI === 'cli') { 249 if (count($argv) == 2) { 250 if (is_dir($argv[1])) { 251 $dir = $argv[1]; 252 } 253 if (count(explode(',', $argv[2])) > 0) { 254 $media = $arg[2]; 255 } 256 } 257 echo ' * Starting to scan directory: '.$dir."\n"; 258 echo ' * Using default media types: '.implode(',', $media)."\n"; 259 dirscan::scan_files($dir, $media, $cache, $database); 260} 261