View Issue Details

IDProjectCategoryView StatusLast Update
0003490mantisbtfeaturepublic2014-11-07 15:16
Reporterchipux Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
Status newResolutionopen 
Summary0003490: Expand Archive Files on Server.
Description

Patch To:

  • Show Contents of Archive Files in the View Bug Page
  • Dynamicaly Show/Collapse the File List and Previewed Images
  • Allow Files from within Archives to be downloaded Individually
Additional Information

Requires PEAR's Archive_Tar and Archive_Zip to work.

I would recommend including these with Mantis.

It could use hooks for when JavaScript is disabled.

Tagspatch
Attached Files
archive-expand.patch (17,379 bytes)   
Index: config_defaults_inc.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/config_defaults_inc.php,v
retrieving revision 1.130
diff -u -r1.130 config_defaults_inc.php
--- config_defaults_inc.php	1 Sep 2003 14:06:57 -0000	1.130
+++ config_defaults_inc.php	7 Jan 2004 05:47:22 -0000
@@ -529,6 +529,11 @@
 	# This feature applies to: bmp, png, gif, jpg
 	$g_preview_attachments_inline_max_size = 0;
 
+        # Specifies if Mantis should expand Archive Type Files (Currently Zip or Tar) 
+        # and allow users to download from within the Archive without downloading the Entire Archive
+        $g_file_archive_expand   = ON;
+        $g_file_archive_expand_temp   = '/tmp/mantis-expand';
+
 	############################
 	# Mantis HTML Settings
 	############################
Index: file_download.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/file_download.php,v
retrieving revision 1.24
diff -u -r1.24 file_download.php
--- file_download.php	27 Feb 2003 08:14:49 -0000	1.24
+++ file_download.php	7 Jan 2004 05:47:22 -0000
@@ -24,6 +24,20 @@
 	$f_file_id	= gpc_get_int( 'file_id' );
 	$f_type		= gpc_get_string( 'type' );
 
+        function temp_deldir($p_dir){
+            $t_current_dir = @opendir($p_dir);
+            while($t_entryname = @readdir($t_current_dir)){
+                if(is_dir("$p_dir/$t_entryname") && ($t_entryname != "." && $t_entryname!="..")){
+                    @deldir("${p_dir}/${t_entryname}");
+                }
+                elseif($t_entryname != "." and $t_entryname!=".."){
+                    @unlink("${p_dir}/${t_entryname}");
+                }
+            }
+            @closedir($t_current_dir);
+            @rmdir($p_dir);
+        }
+
 	$c_file_id = (integer)$f_file_id;
 	#access_ensure_project_level( config_get( 'handle_bug_threshold' ) );
 	# @@@ We need a security check here but we need the API to
@@ -49,10 +63,76 @@
 	$row = db_fetch_array( $result );
 	extract( $row, EXTR_PREFIX_ALL, 'v' );
 
-	header( 'Content-type: ' . $v_file_type );
-	header( 'Content-Length: ' . $v_filesize );
-	header( 'Content-Disposition: filename=' . file_get_display_name( $v_filename ) );
-	header( 'Content-Description: Download Data' );
+        if( ON == config_get( 'file_archive_expand' ) && isset($_GET['subfile']) && (
+                substr($v_filename,-7) == '.tar.gz'
+             || substr($v_filename, -8) == '.tar.bz2'
+             || substr($v_filename, -4) == '.zip' )) {
+
+                $t_extract_dir = config_get( 'file_archive_expand_temp' );
+
+                $f_subfile      = base64_decode($_GET['subfile']);
+                $t_tmpdir       = $t_extract_dir .'/' . $c_file_id;
+                $t_lockfile     = $t_extract_dir."/lock-".$c_file_id;
+
+                // We Must Set This because some webserver configurations set the umask to where we
+                // couldn't delete our own extracted files.
+                @umask('0011');
+
+                $t_full_file =  $t_tmpdir.'/'.$f_subfile;
+                if(!@is_readable($t_full_file)){
+                        die("The Requested File could not be extracted. Please download the entire Archive.");
+                }
+
+                if( substr($v_diskfile,-7) == '.tar.gz'
+                    || substr($v_diskfile, -8) == '.tar.bz2' ) {
+                        @include_once('Archive/Tar.php') or die("Should Not Make Links to this if Archive_Tar isn't Available.");
+                        $t_cfile = new Archive_Tar($v_diskfile);
+                        $t_cfile->extract($t_tmpdir);
+                }
+                elseif( substr($v_diskfile, -4) == '.zip' ) {
+                        @include_once('core/Archive/Zip.php') or die("Should Not Make Links to this if Archive_Zip isn't Available.");
+                        $t_cfile = new Archive_Zip($v_diskfile);
+                        $t_cfile->extract(array('add_path' => $t_tmpdir));
+                }
+
+
+                if(function_exists('mime_content_type')) {
+                        $t_file_type = mime_content_type($t_full_file);
+                }
+                else {
+                        $t_file_type = "application/force-download";
+                }
+
+                $fp = @fopen($t_lockfile, "w+");
+                @chmod($t_lockfile, 777);
+
+                $f_subfile = str_replace('/','-',$f_subfile);
+                header("Content-type: ". $t_file_type ."; name=\"" .  $f_subfile . "\"");
+                header("Content-Transfer-Encoding: binary");
+                header("Content-Description: Download Data");
+                header("Content-length: " . filesize( $t_full_file ));
+                header("Expires: 0");
+                header("Cache-Control: no-cache, must-revalidate");
+                header("Pragma: no-cache");
+
+                readfile(  $t_full_file );
+                temp_deldir($t_tmpdir);
+                @flock($fp, LOCK_UN); // release the lock
+                @fclose($fp);
+                @unlink($t_lockfile);
+                exit();
+        }
+
+        $t_filename = file_get_display_name( $v_filename );
+
+        header("Content-type: ". $v_file_type ."; name=\"" .  $t_filename . "\"");
+        header("Content-Transfer-Encoding: binary");
+        header("Content-Disposition: filename=\"" . $t_filename . "\"");
+        header("Content-length: " . $v_filesize);
+        header("Content-Description: Download Data");
+        header("Expires: 0");
+        header("Cache-Control: no-cache, must-revalidate");
+        header("Pragma: no-cache");
 
 	# dump file content to the connection.
 	switch ( config_get( 'file_upload_method' ) ) {
Index: core/file_api.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/file_api.php,v
retrieving revision 1.39
diff -u -r1.39 file_api.php
--- core/file_api.php	21 Aug 2003 14:31:42 -0000	1.39
+++ core/file_api.php	7 Jan 2004 05:47:22 -0000
@@ -54,6 +54,10 @@
 		$c_bug_id = db_prepare_int( $p_bug_id );
 
 		$t_bug_file_table = config_get( 'mantis_bug_file_table' );
+                $t_project_id = bug_get_field( $p_bug_id, 'project_id' );
+                $t_file_path = project_get_field( $t_project_id, 'file_path' );
+                $t_upload_method = config_get( 'file_upload_method' );
+                $t_expand_archives = config_get( 'file_archive_expand' );
 
 		$query = "SELECT id, title, diskfile, filename, filesize, UNIX_TIMESTAMP(date_added) as date_added
 				FROM $t_bug_file_table
@@ -66,7 +70,7 @@
 				access_has_project_level( config_get( 'handle_bug_threshold' ) );
 
 		$num_files = db_num_rows( $result );
-		$image_previewed = false;
+
 		for ( $i = 0 ; $i < $num_files ; $i++ ) {
 			$row = db_fetch_array( $result );
 			extract( $row, EXTR_PREFIX_ALL, 'v' );
@@ -74,17 +78,14 @@
 			$t_filesize = number_format( $v_filesize );
 			$t_date_added = date( config_get( 'normal_date_format' ), ( $v_date_added ) );
 
-			if ( $image_previewed ) {
-				$image_previewed = false;
-				echo '<br />';
-			}
-
 			$t_href = "<a href=\"file_download.php?file_id=$v_id&amp;type=bug\" target=\"_blank\">";
 
 			echo $t_href;
 			print_file_icon ( file_get_display_name( $v_filename ) );
 			echo '</a>&nbsp;' . $t_href . file_get_display_name( $v_filename ) . 
-				"</a> ($t_filesize bytes) <span class=\"italic\">$t_date_added</span>";
+				"</a> (";
+                        print_file_size($t_filesize); 
+                        echo")  <span class=\"italic\">$t_date_added</span>";
 
 			if ( $t_can_delete ) {
 				echo " [<a class=\"small\" href=\"bug_file_delete.php?file_id=$v_id\">" . lang_get('delete_link') . '</a>]';
@@ -97,15 +98,136 @@
 			if ( ( $v_filesize <= config_get( 'preview_attachments_inline_max_size' ) ) &&
 				( $v_filesize != 0 ) && 
 				( in_array( strtolower( file_get_extension( $v_diskfile ) ), array( 'png', 'jpg', 'gif', 'bmp' ), true ) ) ) {
-				echo "<br /><img src=\"file_download.php?file_id=$v_id&amp;type=bug\" />";
-				$image_previewed = true;
+
+                                echo " <span id='pex_".$v_id."'>[<a class=\"small\"
+                                        style='cursor: hand; color: blue; text-decoration: underline;'
+                                        onClick=\"show('pic_".$v_id."');hide('pex_".$v_id."');show('phi_".$v_id."')\">Expand Picture</a>]</span>";
+                                echo " <span id='phi_".$v_id."' style='display: none;'>[<a class=\"small\"
+                                        style='cursor: hand; color: blue; text-decoration: underline;'
+                                        onClick=\"hide('pic_".$v_id."');show('pex_".$v_id."');hide('phi_".$v_id."')\">Collapse Picture</a>]</span>";
+                                echo " <span  id='pic_".$v_id."' style='display: none;'><br /><img
+                                                src=\"file_download.php?file_id=$v_id&amp;type=bug\" /><br/></span>";
 			}
 
+                        if( ON == $t_expand_archives && DISK == $t_upload_method && ( 
+                               substr($v_filename,-7) == '.tar.gz'
+                            || substr($v_filename, -8) == '.tar.bz2'
+                            || substr($v_filename, -4) == '.zip' ) ) {
+
+                                echo " <span id='ex_".$v_id."'>[<a class=\"small\"
+                                        style='cursor: hand; color: blue; text-decoration: underline;'
+                                        onClick=\"show('arch_".$v_id."');hide('ex_".$v_id."');show('hi_".$v_id."')\">Expand Archive</a>]</span>";
+
+                                echo " <span id='hi_".$v_id."' style='display: none;'>[<a class=\"small\"
+                                        style='cursor: hand; color: blue; text-decoration: underline;'
+                                        onClick=\"hide('arch_".$v_id."');show('ex_".$v_id."');hide('hi_".$v_id."')\">Collapse Archive</a>]</span>";
+
+                                print_file_archive_list($p_bug_id, $v_id, $t_file_path.$v_filename);
+                        }
+
 			if ( $i != ($num_files - 1) ) {
 				echo '<br />';
 			}
 		}
 	}
+
+        # --------------------
+        # prints the contents of arhcive files
+        function print_file_archive_list($p_bug_id, $p_attach_id, $p_file) {
+                $t_cfile = false;
+                $t_ret = 0;
+
+                echo "<div id='arch_$p_attach_id' style='display: none;'>";
+
+                if(!is_readable($p_file)) {
+                        echo "Error Reading Uploaded Archive: $p_file</div>";
+                        return false;
+                }
+
+                if( substr($p_file,-7) == '.tar.gz'
+                    || substr($p_file, -8) == '.tar.bz2' ) {
+                        $t_ret = @include_once('Archive/Tar.php');
+                        if($t_ret != 1) {
+                            // Archive_Tar is part of the Core PEAR Distro. Should be Available Most Places
+                            echo "Could not Read this type of Archive. Please Install Archive_Tar from PEAR</div>";
+                            return false;
+                        }
+                        $t_cfile = new Archive_Tar($p_file);
+                }
+                elseif( substr($p_file, -4) == '.zip' ) {
+                        $t_ret = @include_once('Archive/Zip.php');
+			if($t_ret != 1) {
+                            echo "Could not Read this type of Archive. Please Install Archive_Zip from PEAR</div>";
+                            return false;
+                        }
+                        $t_cfile = new Archive_Zip($p_file);
+                }
+
+
+                $t_file_list = $t_cfile->listContent();
+                if(!is_array($t_file_list)){
+                        echo "Error Reading Archive: ".
+                               $p_file. "<br />Perhaps it is Damaged?</div>";
+                        return false;
+                }
+
+                echo"   <table width='100%'>
+                        <tr valign='top' style='padding-left: 20px; background: #F5FFFF;'>
+                        <td width='50%'>";
+
+                $i = 0;
+                $t_non_dir_count = 0;
+
+                foreach($t_file_list as $t_lfile_name) {
+                        // fix Archive_Tar Directories
+                        if($t_lfile_name['typeflag'] == 5) {
+                                $t_lfile_name['folder'] = true;
+                        }
+                        if($t_lfile_name['folder'] != true) {
+                                $t_non_dir_count++;
+                        }
+                }
+
+                echo "<table width='100%'>";
+                $t_header = "<tr style='background: #c8c8e8;'><td>&nbsp;</td><td>Filename</td><td>Size</td><td>M-Time</td></tr>";
+                echo $t_header;
+
+                $i = 0;
+                $t_split_at = 1+ floor( ($t_non_dir_count / 2));
+                foreach($t_file_list as $t_lfile_name) {
+                        if($t_lfile_name['folder'] != true) {
+                                $i++;
+                                if($i > $t_split_at && $i) {
+                                        echo '</table></td><td width="50%"><table width="100%">';
+                                        echo $t_header;
+                                        $i = 1;
+                                }
+                                if($i % 2 == 0) {
+                                        $t_bgcolor = "#d8d8bf";
+                                }
+                                else {
+                                        $t_bgcolor = "#ecece5";
+                                }
+                                echo "<tr style='background: $t_bgcolor;'><td width='20'>";
+                                $t_href = "<a href=\"file_download.php?file_id=" . $p_attach_id .
+                                          "&amp;subfile=". urlencode(base64_encode($t_lfile_name['filename'])) . 
+                                          "&amp;type=bug\" target=\"_blank\">";
+                                echo $t_href;
+                                print_file_icon ( $t_lfile_name['filename'] );
+                                echo '</a></td><td>' . $t_href .  $t_lfile_name['filename'];
+                                echo "</a>";
+                                echo "</td><td>";
+                                print_file_size($t_lfile_name['size']);
+                                echo '</td><td>'.date("M j G:i",$t_lfile_name['mtime']).'</td>';
+                                echo '</tr>';
+                        }
+                }
+                echo"</table>";
+                echo "</td></tr></table></div>";
+                return true;
+        }
+
+
 	# --------------------
 	# delete all files that are associated with the given bug
 	function file_delete_attachments( $p_bug_id ) {
Index: core/html_api.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/html_api.php,v
retrieving revision 1.78
diff -u -r1.78 html_api.php
--- core/html_api.php	12 Nov 2003 20:40:08 -0000	1.78
+++ core/html_api.php	7 Jan 2004 05:47:22 -0000
@@ -179,6 +179,21 @@
 		echo '<script language="JavaScript" type="text/javascript">';
 		echo '<!--';
 		echo 'if(document.layers) {document.write("<style>td{padding:0px;}<\/style>")}';
+                echo "
+                     function gotoBug(bug_id) {
+                         window.location = \"/mantis/bug_view_advanced_page.php?bug_id=\" + bug_id;
+                     }
+
+                     function show(object) {
+                         var ta = document.getElementById(object);
+                         ta.style.display = '';
+                     }
+
+                     function hide(object) {
+                         var ta = document.getElementById(object);
+                         ta.style.display = 'none';
+                     }
+                    ";
 		echo '//-->';
 		echo '</script>';
 	}
Index: core/print_api.php
===================================================================
RCS file: /cvsroot/mantisbt/mantisbt/core/print_api.php,v
retrieving revision 1.70
diff -u -r1.70 print_api.php
--- core/print_api.php	17 Aug 2003 23:08:48 -0000	1.70
+++ core/print_api.php	7 Jan 2004 05:47:22 -0000
@@ -1062,7 +1062,22 @@
 		print_bracket_link( $p_link, lang_get( 'proceed' ) );
 		PRINT '</div>';
 	}
-
+	# --------------------
+	# prints a filesize in a human readable format.
+        function print_file_size($p_size) {
+                if($p_size > 1024*1024*1024) {
+                        echo number_format( round( $p_size / 1024 / 1024 / 1024, 2) ) ." GB";
+                }
+                elseif($p_size > 1024*1024) {
+                        echo number_format( round( $p_size / 1024 / 1024, 2) ) ." MB";
+                }
+                elseif($p_size > 1024) {
+                        echo number_format( round( $p_size / 1024, 2) ) ." KB";
+                }
+                else {
+                        echo number_format( round( $p_size, 2) ) ." B";
+                }
+        }
 
 	#===============================
 	# Deprecated Functions
archive-expand.patch (17,379 bytes)   

Activities

chipux

chipux

2004-01-07 10:02

reporter   ~0004860

Patch:
http://force-elite.com/~chip/patches/mantis/archive-expand.patch

vboctor

vboctor

2008-07-13 02:58

manager   ~0018390

I've attached the patch from the above link.