From 0d408fe6f540161b9367d7b6abb93965139898a4 Mon Sep 17 00:00:00 2001
From: Robin Appelman <icewind1991@gmail.com>
Date: Thu, 28 Jul 2011 20:10:58 +0200
Subject: [PATCH] make use of the command line tools id3info and mp3info for
 scanning music if they are available

---
 apps/media/lib_scanner.php | 99 ++++++++++++++++++++++++++------------
 lib/filestorage.php        | 58 +---------------------
 lib/helper.php             | 45 +++++++++++++++++
 3 files changed, 115 insertions(+), 87 deletions(-)

diff --git a/apps/media/lib_scanner.php b/apps/media/lib_scanner.php
index aa0ca94a43..296acbdbaa 100644
--- a/apps/media/lib_scanner.php
+++ b/apps/media/lib_scanner.php
@@ -68,40 +68,79 @@ class OC_MEDIA_SCANNER{
 	 * @return boolean
 	 */
 	public static function scanFile($path){
-		if(!self::$getID3){
-			self::$getID3=@new getID3();
-		}
 		$file=OC_FILESYSTEM::getLocalFile($path);
-		$data=@self::$getID3->analyze($file);
-		getid3_lib::CopyTagsToComments($data);
-		if(!isset($data['comments'])){
-			error_log("error reading id3 tags in '$file'");
-			return;
-		}
-		if(!isset($data['comments']['artist'])){
-			error_log("error reading artist tag in '$file'");
-			$artist='unknown';
-		}else{
-			$artist=stripslashes($data['comments']['artist'][0]);
-			$artist=utf8_encode($artist);
-		}
-		if(!isset($data['comments']['album'])){
-			error_log("error reading album tag in '$file'");
-			$album='unknown';
-		}else{
-			$album=stripslashes($data['comments']['album'][0]);
-			$album=utf8_encode($album);
-		}
-		if(!isset($data['comments']['title'])){
-			error_log("error reading title tag in '$file'");
+		if(substr($path,-3)=='mp3' and OC_HELPER::canExecute("id3info") and OC_HELPER::canExecute("mp3info")){//use the command line tool id3info if possible
+			$output=array();
+			$size=filesize($file);
+			$length=0;
 			$title='unknown';
+			$album='unknown';
+			$artist='unknown';
+			$track=0;
+			exec('id3info "'.$file.'"',$output);
+			$data=array();
+			foreach($output as $line) {
+				switch(substr($line,0,3)){
+					case '***'://comments
+						break;
+					case '==='://tag information
+						$key=substr($line,4,4);
+						$value=substr($line,strpos($line,':')+2);
+						switch(strtolower($key)){
+							case 'tit1':
+							case 'tit2':
+								$title=$value;
+								break;
+							case 'tpe1':
+							case 'tpe2':
+								$artist=$value;
+								break;
+							case 'talb':
+								$album=$value;
+								break;
+							case 'trck':
+								$track=$value;
+								break;
+						}
+						break;
+				}
+			}
+			$length=exec('mp3info -p "%S" "'.$file.'"');
 		}else{
-			$title=stripslashes($data['comments']['title'][0]);
-			$title=utf8_encode($title);
+			if(!self::$getID3){
+				self::$getID3=@new getID3();
+			}
+			$data=@self::$getID3->analyze($file);
+			getid3_lib::CopyTagsToComments($data);
+			if(!isset($data['comments'])){
+				error_log("error reading id3 tags in '$file'");
+				return;
+			}
+			if(!isset($data['comments']['artist'])){
+				error_log("error reading artist tag in '$file'");
+				$artist='unknown';
+			}else{
+				$artist=stripslashes($data['comments']['artist'][0]);
+				$artist=utf8_encode($artist);
+			}
+			if(!isset($data['comments']['album'])){
+				error_log("error reading album tag in '$file'");
+				$album='unknown';
+			}else{
+				$album=stripslashes($data['comments']['album'][0]);
+				$album=utf8_encode($album);
+			}
+			if(!isset($data['comments']['title'])){
+				error_log("error reading title tag in '$file'");
+				$title='unknown';
+			}else{
+				$title=stripslashes($data['comments']['title'][0]);
+				$title=utf8_encode($title);
+			}
+			$size=$data['filesize'];
+			$track=(isset($data['comments']['track']))?$data['comments']['track'][0]:0;
+			$length=round($data['playtime_seconds']);
 		}
-		$size=$data['filesize'];
-		$track=(isset($data['comments']['track']))?$data['comments']['track'][0]:0;
-		$length=round($data['playtime_seconds']);
 		if(!isset(self::$artists[$artist])){
 			$artistId=OC_MEDIA_COLLECTION::addArtist($artist);
 			self::$artists[$artist]=$artistId;
diff --git a/lib/filestorage.php b/lib/filestorage.php
index 95e8c31eff..601cf6f37f 100644
--- a/lib/filestorage.php
+++ b/lib/filestorage.php
@@ -200,7 +200,7 @@ class OC_FILESTORAGE_LOCAL extends OC_FILESTORAGE{
 			} else if (function_exists("mime_content_type")) {
 				// use mime magic extension if available
 				$mime_type = mime_content_type($this->datadir.$fspath);
-			} else if (self::canExecute("file")) {
+			} else if (OC_HELPER::canExecute("file")) {
 				// it looks like we have a 'file' command,
 				// lets see it it does have mime support
 				$fp = popen("file -i -b '{$this->datadir}$fspath' 2>/dev/null", "r");
@@ -223,62 +223,6 @@ class OC_FILESTORAGE_LOCAL extends OC_FILESTORAGE{
 		}
 	}
 
-	/**
-	* detect if a given program is found in the search PATH
-	*
-	* helper function used by _mimetype() to detect if the
-	* external 'file' utility is available
-	*
-	* @param  string  program name
-	* @param  string  optional search path, defaults to $PATH
-	* @return bool    true if executable program found in path
-	*/
-	private function canExecute($name, $path = false)
-	{
-		// path defaults to PATH from environment if not set
-		if ($path === false) {
-			$path = getenv("PATH");
-		}
-
-		// check method depends on operating system
-		if (!strncmp(PHP_OS, "WIN", 3)) {
-			// on Windows an appropriate COM or EXE file needs to exist
-			$exts = array(".exe", ".com");
-			$check_fn = "file_exists";
-		} else {
-			// anywhere else we look for an executable file of that name
-			$exts = array("");
-			$check_fn = "is_executable";
-		}
-
-        // Default check will be done with $path directories :
-        $dirs = explode(PATH_SEPARATOR, $path);
-
-		// WARNING : We have to check if open_basedir is enabled :
-		$obd = ini_get('open_basedir');
-
-		if($obd != "none")
-            $obd_values = explode(PATH_SEPARATOR, $obd);
-
-		if(count($obd_values) > 0)
-		{
-            // open_basedir is in effect !
-            // We need to check if the program is in one of these dirs :
-            $dirs = $obd_values;
-        }
-
-        foreach($dirs as $dir)
-        {
-            foreach($exts as $ext)
-            {
-                if($check_fn("$dir/$name".$ext))
-                    return true;
-            }
-        }
-
-		return false;
-	}
-
 	public function toTmpFile($path){
 		$tmpFolder=sys_get_temp_dir();
 		$filename=tempnam($tmpFolder,'OC_TEMP_FILE_'.substr($path,strrpos($path,'.')));
diff --git a/lib/helper.php b/lib/helper.php
index 96d5bfad82..1fbcc589d1 100755
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -267,6 +267,51 @@ class OC_HELPER {
 		if((isset($_REQUEST[$s]) && $_REQUEST[$s]==$v) || $v == $d)
 			print "checked=\"checked\" ";
 	}
+
+	/**
+	* detect if a given program is found in the search PATH
+	*
+	* @param  string  program name
+	* @param  string  optional search path, defaults to $PATH
+	* @return bool    true if executable program found in path
+	*/
+	public static function canExecute($name, $path = false){
+		// path defaults to PATH from environment if not set
+		if ($path === false) {
+			$path = getenv("PATH");
+		}
+		// check method depends on operating system
+		if (!strncmp(PHP_OS, "WIN", 3)) {
+			// on Windows an appropriate COM or EXE file needs to exist
+			$exts = array(".exe", ".com");
+			$check_fn = "file_exists";
+		} else {
+			// anywhere else we look for an executable file of that name
+			$exts = array("");
+			$check_fn = "is_executable";
+		}
+		// Default check will be done with $path directories :
+		$dirs = explode(PATH_SEPARATOR, $path);
+		// WARNING : We have to check if open_basedir is enabled :
+		$obd = ini_get('open_basedir');
+		if($obd != "none")
+			$obd_values = explode(PATH_SEPARATOR, $obd);
+		if(count($obd_values) > 0 and $obd_values[0])
+		{
+			// open_basedir is in effect !
+			// We need to check if the program is in one of these dirs :
+			$dirs = $obd_values;
+		}
+		foreach($dirs as $dir)
+		{
+			foreach($exts as $ext)
+			{
+				if($check_fn("$dir/$name".$ext))
+					return true;
+			}
+		}
+		return false;
+	}
 }
 
 ?>
-- 
GitLab