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