fileViewer.cgi #9

  • //
  • guest/
  • fredric_fredricson/
  • P4DB/
  • main/
  • fileViewer.cgi
  • View
  • Commits
  • Open Download .zip Download (10 KB)
#!/usr/bin/perl -w
# -*- perl -*-
use P4CGI ;
use strict ;
#
#################################################################
#  CONFIGURATION INFORMATION 
#  All config info should be in P4CGI.pm
#
#################################################################
#
#  P4 file  viewer
#  View a file
#
#################################################################

use viewConfig ;
use colorView ;

$| = 1 ;

# A hash containing file extensions that can be viewed with special viewers
# Data is:
#             <extension> => <semicolon separated list of:
#                             url      - Url to be used
#                             typecode - Will be sent as parameter TYPE to url
#                             text     - A text for the href to url>
# Other than the TYPE parameter mentioned above the file name (depot format) will
# be sent as FILE parameter and file revision as REV parameter.
#

# return number of digits in an integer
sub digits($) {
    my $n = shift;
    return int(log($n)/log(10))+1 ;    
}


# Get file spec argument

my $file = &P4CGI::cgi()->param("FSPC") ;
&P4CGI::bail("No file specified") unless defined $file ;

my $showannotaed = &P4CGI::cgi()->param("ANNOTATE") ;
#my $showdeleted = &P4CGI::cgi()->param("SHOWDEL") ;
my $showdeleted = $showannotaed ;
my $showhelp = &P4CGI::cgi()->param("HELP") ;
$showhelp="N" unless defined $showhelp ;

#$showdeleted = undef unless defined $showannotaed ;

my $ext = $file ;
$ext =~ s/^.*\.// ;

my $revision = P4CGI::cgi()->param("REV") ;
#    &P4CGI::bail("No revision specified") unless defined $revision ;
#$revision="" unless defined $revision ;

my $force = P4CGI::cgi()->param("FORCE") ;

my @legend ;

my $trev = "" ;
$trev = "\#$revision" if defined $revision ;

my $filetype = "UNKNOWN" ;
my $filesize = "UNKNOWN" ;
local *P4 ;
&P4CGI::p4call(*P4,"fstat -l -s \"$file$trev\"")  ;
while(<P4>) {
    /... headType (\S+)/ and do {
	$filetype = $1 ;
	next ;
    } ;
    /... fileSize (\d+)/ and do {
	$filesize = $1 ;
	next ;
    }
}

my %revToChange ;
&P4CGI::p4call(*P4,"filelog \"$file$trev\"")  ;
while(<P4>) {
    /... \#(\d+) change (\d+)/ and do {
	$revToChange{$1} = $2 ;
    }
} ;
close P4 ;

if(defined $showannotaed) {
    &P4CGI::p4call(*P4,"annotate -a \"$file$trev\"")  ;
}
else {
    &P4CGI::p4call(*P4,"print \"$file$trev\"")  ;
}

my $info = <P4> ;
&P4CGI::bail("Failed to read file $file$trev") unless defined $info ;

$info =~ /\#(\d+) - / or &P4CGI::bail("Failed to parse first line from \"p4 print/annotate -a $file$trev\" command") ;
my $rev = $1 ;

my @filetext ;
if(defined $showannotaed) {
    &P4CGI::p4call(\@filetext,"print -q \"$file$trev\"") ;
}
else {
    @filetext = map { &P4CGI::rmTabs($_) ; } <P4> ;
} ;

{
    my $buttontext ;
    my $helptext ;
    if($rev > 1) {	
	if(defined $showannotaed) { 
	    &P4CGI::cgi()->delete("ANNOTATE") ;
	    $buttontext = "Hide annotations" ;
	    $helptext = "Show file without annotations" ;
	}
	else {
	    &P4CGI::cgi()->param("ANNOTATE","Y") ;
	    $buttontext = "Show annotated" ;
	    $helptext = "Show file with annotaions" ;
	} ;
	push @legend, &P4CGI::buttonCell(&P4CGI::cgi()->url(-relative => 1,
							    -query => 1),
					 $helptext,,
					 $buttontext) ;
	if(defined $showannotaed) { &P4CGI::cgi()->param("ANNOTATE","Y") ; }
	else                      { &P4CGI::cgi()->delete("ANNOTATE") ;    } ;

# 	if(defined $showdeleted) { 
# 	    &P4CGI::cgi()->delete("SHOWDEL") ;
# 	    $buttontext = "Hide deleted lines" ;
# 	    $helptext = "Hide the deleted lines and revisions" ;
# 	}
# 	else {
# 	    &P4CGI::cgi()->param("SHOWDEL","Y") ;
# 	    &P4CGI::cgi()->param("ANNOTATE","Y") ;
# 	    $buttontext = "Show deleted lines" ;
# 	    $helptext = "Show all deleted lines and the revision where they where deleted" ;
# 	} ;
# 	if(defined $showannotaed) {
# 	    push @legend, &P4CGI::buttonCell(&P4CGI::cgi()->url(-relative => 1,
# 								-query => 1),
# 					     $helptext,,
# 					     $buttontext) ;
# 	} ;
# 	if(defined $showdeleted)  { &P4CGI::cgi()->param("SHOWDEL","Y") ;  }
# 	else                      { &P4CGI::cgi()->delete("SHOWDEL") ;     } ;
    }
};

$ext = uc($ext) ;
if(exists $viewConfig::ExtensionToType{$ext}) {
    my $type = $viewConfig::ExtensionToType{$ext} ;
    my ($url,$desc,$content,$about) = @{$viewConfig::TypeData{$type}} ;    
    push @legend, &P4CGI::buttonCell($url,
				     "View file $file",
				     "TYPE=$type",
				     "FSPC=$file",
				     "TARGET=_blank",
				     "REV=$rev",
				     "View $desc") ;
} ;
push @legend, &P4CGI::buttonCell("fileLogView.cgi",
				 "View file log for $file",
				 "FSPC=$file",
				 "File log");

push @legend, &P4CGI::buttonCell("fileDownLoad.cgi",
				 "Download file $file",
				 "FSPC=$file",
				 "REV=$rev",
				 "Download") ;

{
    &P4CGI::cgi()->delete("HELP") ;
    my $buttontext ;
    my $helptext ;
    if($showhelp ne "Y") { 
	&P4CGI::cgi()->param("HELP","Y") ;
	$buttontext = "Show help" ;
	$helptext = "Show a help text that describes this page" ;
    }
    else {
	&P4CGI::cgi()->param("HELP","N") ;
	$buttontext = "Hide help" ;
	$helptext = "Hide help" ;
    } ;	
    push @legend,  "<td>&nbsp;</td>",&P4CGI::buttonCell(&P4CGI::cgi()->url(-relative => 1,
									   -query => 1),
							$helptext,,
							$buttontext) ;
    &P4CGI::cgi()->delete("HELP") ;    
};

print 
    &P4CGI::start_page("File <tt>$file</tt>\#$rev",@legend) ;
if($showhelp eq "Y") {
    print 
	&P4CGI::start_framedTable("Page help") ;

    my $key ;
    $key = ":Hide" unless defined $showdeleted ;
    $key = ":Show" if defined $showdeleted ;

    while(<DATA>) {
	/^$key/ and do {
	    while(<DATA>) {
		last if /^:/ ;
		print ;
	    }
	    last ;
	}
    }

    print 
	&P4CGI::end_framedTable(), "<br>" ;

}

print
    &P4CGI::start_framedTable("File info"),
    &P4CGI::start_table(),
    &P4CGI::table_row({-class => "Prompt",
		       -text  => "File type:"},
		      $filetype),
    &P4CGI::table_row({-class => "Prompt",
		       -text  => "File size:"},
		      "$filesize Bytes"),
    &P4CGI::end_table(),
    &P4CGI::end_framedTable() ;
    


unless($force or $filetype =~ /text/ or $filetype =~ /unicode/) {
    print "File type is \"$filetype\" and not text<br>" ;
    &P4CGI::cgi()->param("FORCE"=>"Y") ;
    print 
	&P4CGI::buttonLink(&P4CGI::cgi()->url(-query=>1),
			   "View file even if not text type",
			   "View anyway"),
        &P4CGI::end_page() ;
    exit 0 ;        
}

map { my $x = &P4CGI::htmlEncode($_) ; $_ = $x ; } @filetext ;

if(&P4CGI::VIEW_WITH_COLORS()) {
    my $tmp = join("\n",@filetext) ;    
    &colorView::color($file,\$tmp) ;
    @filetext = split("\n",$tmp) unless $@ ;
} ;

my $lines = scalar @filetext ;

print
    &P4CGI::start_framedTable("File ($lines lines)") ;

print "<table class=\"fileViewer\">\n" ;

print "<tr>" ;
print "<th class=\"fileViewerHeader\">Added in rev./ch.</th>" if $showannotaed ;
print "<th class=\"fileViewerHeader\">Deleted to rev./ch.</th>" if $showdeleted ;
print "<th class=\"fileViewerHeader\">Line</th> ";
print "<th class=\"fileViewerHeader\">File<br>content</th> ";
print "</tr>\n" ;

my $lastRevStr = "" ;
my $lineNo = 0 ;
my @dataC ;

my $p4_depot=&P4CGI::CURR_DEPOT_NO() ;

if($showannotaed) {
    while(<P4>) {
	chomp ;
	s/^(\d+)-(\d+): // and do {
	    my ($firstrev,$lastrev,$line) = ($1,$2,&P4CGI::rmTabs($_)) ;
	    $firstrev = 
		"<a class=\"normal\" title=\"Line(s) added by change $revToChange{$firstrev}. Click to view change.\" ".
		" href=\"changeView.cgi?CH=$revToChange{$firstrev};DP=$p4_depot\">$firstrev/$revToChange{$firstrev}</a>" ;
	    if($lastrev < $rev) {
		my $r = $lastrev + 1 ;
		$lastrev = 
		    "<a class=\"normal\" title=\"Line(s) deleted by change $revToChange{$r}. Click to view change.\" ".
		    " href=\"changeView.cgi?CH=$revToChange{$r};DP=$p4_depot\">$r/$revToChange{$r}</a>" ;
	    }
	    else {
		$lastrev = "" ;
	    }
	    my $cclass = "" ;
	    my $revStr = "XX" ;
	    my $lineNoStr = "" ;
	    if($lastrev ne "") {
		$revStr = "A:$firstrev D:$lastrev" ;
		$cclass= "class=\"deleted\"" ;
		$line = &P4CGI::htmlEncode($line) ;
	    }
	    else {
		$line = shift @filetext ;
		$revStr = "A:$firstrev   " ; 
		$lineNo++ ;
		if($lineNo == 1 or $lineNo % 5 == 0) {
		    
		    $lineNoStr="<a name=\"L$lineNo\">$lineNo</a>" ;
		}
		else {
		    $lineNoStr="<a name=\"L$lineNo\">  </a>" ;
		}
	    }
	    my $revclass ;
	    if($lastRevStr eq $revStr) {
		$revStr = "" ;
		$firstrev = "" ;
		$lastrev = "" ;	    
		$revclass="fileViewerRevEmpty" ;
	    }
	    else {
		$lastRevStr = $revStr ; 
		$revclass="fileViewerRev" ;
	    } ;

	    #$line = &P4CGI::rmTabs($line) ;
	    $line = "" unless defined $line ;
	    while($line =~ s/(<[^>]*) ([^>]*>)/$1===SPACE===HERE===$2/g) {} ;
	    $line =~ s/ /&nbsp;/g ;
	    $line =~ s/===SPACE===HERE===/ /g ;
	    
	    print "<tr><th class=\"$revclass\">$firstrev</th>" ;
	    print "<th class=\"$revclass\">$lastrev</th>" ;
	    print "<th class=\"fileViewerLineNo\">$lineNoStr</th><td><span $cclass>$line</span></td></tr>\n" ;
	}
    }
}
else { # if defined $showannotaed
    my $line ;
    foreach $line (@filetext) {
	my $lineNoStr = "" ;
	$lineNo++ ;
	if($lineNo == 1 or $lineNo % 5 == 0) {
	    $lineNoStr="<a name=\"L$lineNo\">$lineNo</a>" ;
	}
	else {
	    $lineNoStr="<a name=\"L$lineNo\">  </a>" ;
	}	
	#$line = &P4CGI::rmTabs($line) ;
	while($line =~ s/(<[^>]*) ([^>]*>)/$1===SPACE===HERE===$2/g) {} ;
	$line =~ s/ /&nbsp;/g ;
	$line =~ s/===SPACE===HERE===/ /g ;
	print "<th class=\"fileViewerLineNo\">$lineNoStr</th><td>$line</td></tr>\n" ;
    }
}
print "</table>" ;

close P4 ;


print 
    &P4CGI::end_framedTable(),    
    &P4CGI::end_page() ;

#
# That's all folks
#

__END__
:Hide deleted
    This page show contents of a specific revision of a file as text.<br>
    The contents may be colorized for some file types (html, perl and c source).<br>
    The contents is displayed in a table with two columns:
    <ol>
    <li> The first column shows source line numbers..
    <li> The second column shows the file content.
    </ol>

:Show deleted
    This page show all lines that ever has been in the file for a specific revision of it.<br>
    The contents may be colorized for some file types (html, perl and c source).<br>
    The contents is displayed in a table with four columns:
    <ol>
    <li> The "Added in rev." column contain the revision where the line was added.
    <li> The "Deleted in rev." column contain the revision where the line was deleted
    <li> The third column shows source line numbers..
    <li> The fourth column shows the file content. Deleted will be marked as:<br>
         <span class="deleted">This is a deleted line</span><br>
    </ol>
# Change User Description Committed
#11 4916 Fredric Fredricson P4DB: Improved file viewer (and simplified the code)
#10 4306 Fredric Fredricson P4DB: Hardened P4DB against malicious parameters (cross site scripting),
performed some cleanup and increased version to 3.1.1.
#9 4237 Fredric Fredricson P4DB: Maybe the final submit for P4DB 3.1.0
#8 4216 Fredric Fredricson P4DB: Another partial submit on my way to P4DB 3.1...
#7 4176 Fredric Fredricson P4DB: Still working my way to P4DB 3.1...
#6 4152 Fredric Fredricson P4DB: Some more work on tha way to version 3.1....
#5 4069 Fredric Fredricson P4DB: More changes on the way to 3.1
#4 4048 Fredric Fredricson P4DB: Updated for Explorer.
* Updated Style Sheet to work for Explorer as well as Netscape
* Improved alternate header
* Some other small fixes....
#3 2875 Fredric Fredricson P4DB 3.0 first beta...
#2 1920 Fredric Fredricson P4DB: Mainly some user interface fixes:
* Added a small arrow that points to selection in list of options
* Added tooltip help
* Added user prefereces to turn the above off (or on)
* Some other user interface fixes
And fixed a bug in jobList.cgi and some minor bugs in label and branch
viewers.
#1 1638 Fredric Fredricson P4DB: Added all (I think) files for P4DB