fileViewer.cgi #11

  • //
  • guest/
  • fredric_fredricson/
  • P4DB/
  • main/
  • fileViewer.cgi
  • View
  • Commits
  • Open Download .zip Download (9 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 ;
$file = &P4CGI::htmlEncode($file) ;

my $showdeleted = &P4CGI::cgi()->param("SHOWDEL") ;
my $showhelp = &P4CGI::cgi()->param("HELP") ;
$showhelp="N" unless defined $showhelp ;
my $revision = P4CGI::cgi()->param("REV") ;
my $force = P4CGI::cgi()->param("FORCE") ;


my $fileExtension = $file ;
$fileExtension =~ s/^.*\.// ;
$fileExtension = uc($fileExtension) ;

$revision = "\#$revision" if defined $revision ;
$revision = "" unless defined $revision ;


my @legend ;

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

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


my @fileContents ;
&P4CGI::p4call(\@fileContents,"print \"$file$revision\"") ;

my $info = shift @fileContents;
&P4CGI::bail("Failed to read file $file$revision") unless defined $info ;

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


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

};

if(exists $viewConfig::ExtensionToType{$fileExtension}) {
    my $type = $viewConfig::ExtensionToType{$fileExtension} ;
    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 ; } @fileContents ;

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

my $lines = scalar @fileContents ;

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

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

print "<tr>" ;
print "<th class=\"fileViewerHeader\">Added in rev./ch.</th>" ;
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() ;

&P4CGI::p4call(*P4,"annotate -a \"$file$revision\"")  ;
my $firstline = <P4> ;

while(<P4>) {
    chomp ;
    s/^(\d+)-(\d+): // and do {
	my ($firstrev,$lastrev,$line) = ($1,$2,&P4CGI::rmTabs($_)) ;
	next if ($lastrev < $rev) and ! $showdeleted ;
	$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 ;
	    if($showdeleted) {
		$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 = "" ;
	    } ;
	}
	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 @fileContents ;
	    $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 = "" 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>" if $showdeleted ;
	print "<th class=\"fileViewerLineNo\">$lineNoStr</th><td><span $cclass>$line</span> </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 three columns:
    <ol>
    <li> The first column show revision and change where line was added or modified.
    <li> The second column shows source line numbers..
    <li> The third 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 and change where the line was added.
    <li> The "Deleted in rev." column contain the revision and change where the line was deleted. This column is 
         empty if the line is not deleted.
    <li> The third column shows source line numbers (in the current revision)
    <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