Mime type support
Mime type support

--- a/config/gitphp.conf.php
+++ b/config/gitphp.conf.php
@@ -122,6 +122,29 @@
 $gitphp_conf['geshiroot'] = "geshi/";
 
 /*
+ * filemimetype
+ * Attempt to read the file's mimetype when displaying
+ * (for example, displaying an image as an actual image
+ *  in a browser)
+ * This requires either PHP >= 5.3.0, PECL fileinfo, or
+ * Linux
+ */
+$gitphp_conf['filemimetype'] = FALSE;
+
+/*
+ * magicdb
+ * Path to the libmagic db used to read mimetype
+ * You can leave this as null and let the system
+ * try to find the database for you, but that method
+ * is known to have issues
+ * If the path is correct but it's still not working,
+ * try removing the file extension if you have it on,
+ * or vice versa
+ */
+$gitphp_conf['magicdb'] = "/usr/share/misc/magic.mgc";
+//$gitphp_conf['magicdb'] = "C:\\wamp\\php\\extras\\magic";  // Windows
+
+/*
  * git_projects
  * Two-dimensional array list of projects
  * First array index is the name of the category the projects

--- a/include/display.git_blob.php
+++ b/include/display.git_blob.php
@@ -11,6 +11,7 @@
  include_once('gitutil.git_get_hash_by_path.php');
  include_once('gitutil.git_cat_file.php');
  include_once('gitutil.git_read_commit.php');
+ include_once('util.file_mime.php');
 
 function git_blob($projectroot, $project, $hash, $file, $hashbase)
 {
@@ -40,37 +41,51 @@
 		$tpl->assign("file",$file);
 	$tpl->display("blob_header.tpl");
 
-	$usedgeshi = $gitphp_conf['geshi'];
-	if ($usedgeshi) {
-		$usedgeshi = FALSE;
-		include_once($gitphp_conf['geshiroot'] . "geshi.php");
-		$geshi = new GeSHi("",'php');
-		if ($geshi) {
-			$lang = "";
-			if (isset($file))
-				$lang = $geshi->get_language_name_from_extension(substr(strrchr($file,'.'),1));
-			if (isset($lang) && (strlen($lang) > 0)) {
-				$geshi->set_source($catout);
-				$geshi->set_language($lang);
-				$geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS);
-				echo $geshi->parse_code();
-				$usedgeshi = TRUE;
+	if ($gitphp_conf['filemimetype']) {
+		$mime = file_mime($catout,$file);
+		if ($mime)
+			$mimetype = strtok($mime, "/");
+	}
+
+	if ($mimetype == "image") {
+		$tpl->clear_all_assign();
+		$tpl->assign("mime", $mime);
+		$tpl->assign("data", base64_encode($catout));
+		$tpl->display("blob_image.tpl");
+	} else {
+		$usedgeshi = $gitphp_conf['geshi'];
+		if ($usedgeshi) {
+			$usedgeshi = FALSE;
+			include_once($gitphp_conf['geshiroot'] . "geshi.php");
+			$geshi = new GeSHi("",'php');
+			if ($geshi) {
+				$lang = "";
+				if (isset($file))
+					$lang = $geshi->get_language_name_from_extension(substr(strrchr($file,'.'),1));
+				if (isset($lang) && (strlen($lang) > 0)) {
+					$geshi->set_source($catout);
+					$geshi->set_language($lang);
+					$geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS);
+					echo $geshi->parse_code();
+					$usedgeshi = TRUE;
+				}
+			}
+		}
+
+		if (!$usedgeshi) {
+			$lines = explode("\n",$catout);
+			foreach ($lines as $i => $line) {
+				/*
+				 * TODO: Convert tabs to spaces
+				 */
+				$tpl->clear_all_assign();
+				$tpl->assign("nr",$i+1);
+				$tpl->assign("line",htmlentities($line));
+				$tpl->display("blob_line.tpl");
 			}
 		}
 	}
 
-	if (!$usedgeshi) {
-		$lines = explode("\n",$catout);
-		foreach ($lines as $i => $line) {
-			/*
-			 * TODO: Convert tabs to spaces
-			 */
-			$tpl->clear_all_assign();
-			$tpl->assign("nr",$i+1);
-			$tpl->assign("line",htmlentities($line));
-			$tpl->display("blob_line.tpl");
-		}
-	}
 	$tpl->clear_all_assign();
 	$tpl->display("blob_footer.tpl");
 }

--- a/include/display.git_blob_plain.php
+++ b/include/display.git_blob_plain.php
@@ -8,16 +8,30 @@
  */
 
  include_once('gitutil.git_cat_file.php');
+ include_once('util.file_mime.php');
 
 function git_blob_plain($projectroot,$project,$hash,$file)
 {
+	global $gitphp_conf;
+
 	if ($file)
 		$saveas = $file;
 	else
 		$saveas = $hash . ".txt";
-	header("Content-type: text/plain; charset=UTF-8");
+
+	$buffer = git_cat_file($projectroot . $project, $hash);
+
+	if ($gitphp_conf['filemimetype'])
+		$mime = file_mime($buffer, $file);
+
+	if ($mime)
+		header("Content-type: " . $mime);
+	else
+		header("Content-type: text/plain; charset=UTF-8");
+
 	header("Content-disposition: inline; filename=\"" . $saveas . "\"");
-	echo git_cat_file($projectroot . $project, $hash);
+
+	echo $buffer;
 }
 
 ?>

--- /dev/null
+++ b/include/util.file_mime.php
@@ -1,1 +1,46 @@
+<?php
+/*
+ *  util.file_mime.php
+ *  gitphp: A PHP git repository browser
+ *  Component: Utility - file mimetype
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ */
 
+include_once('util.file_mime_fileinfo.php');
+include_once('util.file_mime_file.php');
+include_once('util.file_mime_ext.php');
+
+function file_mime($buffer, $file = NULL)
+{
+	global $gitphp_conf;
+
+	if (!$buffer)
+		return FALSE;
+
+	/*
+	 * Try finfo (PHP 5.3 / PECL fileinfo)
+	 */
+	$mime = file_mime_fileinfo($buffer);
+	if ($mime)
+		return $mime;
+
+	/*
+	 * Try file command
+	 */
+	$mime = file_mime_file($buffer);
+	if ($mime)
+		return $mime;
+
+	/*
+	 * Try file extension
+	 */
+	if ($file) {
+		$mime = file_mime_ext($file);
+		if ($mime)
+			return $mime;
+	}
+
+	return FALSE;
+}
+

--- /dev/null
+++ b/include/util.file_mime_ext.php
@@ -1,1 +1,35 @@
+<?php
+/*
+ *  util.file_mime_ext.php
+ *  gitphp: A PHP git repository browser
+ *  Component: Utility - file mimetype using file extension
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ */
 
+function file_mime_ext($filename)
+{
+	if ($filename) {
+		$dotpos = strrpos($filename, ".");
+		if ($dotpos !== FALSE)
+			$filename = substr($filename, $dotpos+1);
+		switch ($filename) {
+			case "jpg":
+			case "jpeg":
+			case "jpe":
+				return "image/jpeg";
+				break;
+			case "gif":
+				return "image/gif";
+				break;
+			case "png";
+				return "image/png";
+				break;
+		}
+	}
+
+	return FALSE;
+}
+
+?>
+

--- /dev/null
+++ b/include/util.file_mime_file.php
@@ -1,1 +1,40 @@
+<?php
+/*
+ *  util.file_mime_file.php
+ *  gitphp: A PHP git repository browser
+ *  Component: Utility - file mimetype using file command
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ *
+ *  Based on work by 3v1n0
+ */
 
+function file_mime_file($buffer)
+{
+	global $gitphp_conf;
+
+	if ($buffer && (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) {
+		$descspec = array(
+			0 => array("pipe", "r"),
+			1 => array("pipe", "w")
+		);
+		$proc = proc_open('file -b --mime -', $descspec, $pipes);
+		if (is_resource($proc)) {
+			fwrite($pipes[0], $buffer);
+			fclose($pipes[0]);
+			$mime = stream_get_contents($pipes[1]);
+			fclose($pipes[1]);
+			proc_close($proc);
+			if ($mime && strpos($mime,"/")) {
+				if (strpos($mime,";"))
+					$mime = strtok($mime,";");
+				return $mime;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+?>
+

--- /dev/null
+++ b/include/util.file_mime_fileinfo.php
@@ -1,1 +1,30 @@
+<?php
+/*
+ *  util.file_mime_fileinfo.php
+ *  gitphp: A PHP git repository browser
+ *  Component: Utility - file mimetype using fileinfo
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ */
 
+function file_mime_fileinfo($buffer)
+{
+	global $gitphp_conf;
+
+	if ($buffer && function_exists("finfo_buffer")) {
+		$finfo = finfo_open(FILEINFO_MIME, $gitphp_conf['magicdb']);
+		if ($finfo) {
+			$mime = finfo_buffer($finfo, $buffer, FILEINFO_MIME);
+			if ($mime && strpos($mime,"/")) {
+				if (strpos($mime,";"))
+					$mime = strtok($mime, ";");
+				return $mime;
+			}
+		}
+	}
+	
+	return FALSE;
+}
+
+?>
+

--- /dev/null
+++ b/templates/blob_image.tpl
@@ -1,1 +1,9 @@
+{*
+ *  blob_image.tpl
+ *  gitphp: A PHP git repository browser
+ *  Component: Blob image template
+ *
+ *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
+ *}
+ <div><img src="data:{$mime};base64,{$data}" /></div>
 

comments