fileViewer.cgi #6

  • //
  • guest/
  • fredric_fredricson/
  • P4DB/
  • main/
  • fileViewer.cgi
  • View
  • Commits
  • Open Download .zip Download (11 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 $showdeleted = &P4CGI::cgi()->param("SHOWDEL") ;
my $showhelp = &P4CGI::cgi()->param("HELP") ;
$showhelp="N" unless defined $showhelp ;

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 @filetext ;
&P4CGI::p4call(\@filetext,"print -q \"$file$trev\"") ;
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 $@ ;
} ;

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

&P4CGI::p4call(*P4,"annotate -a \"$file$trev\"")  ;

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

$info =~ /\#(\d+) - / or &P4CGI::bail("Failed to parse first line from \"p4 annotate -a $file$trev\" 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(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",
				     "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, &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 = ":Other" ;
    $key = ":MSIE" if &P4CGI::IS_MSEXPLORER() ;
    $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>" ;

}

# NOTE! 
# CSS support for MS-Explorer 5 and 6 is broken in the sense that it does not handle
# "white-space: pre" properly in normal mode.
# Most (all?) other recent browsers work but it is very hard do ignore Explorer, no matter
# how broken it is.......
# Sigh! The code below (and the CSS file!) differs between Explorer and other
# browsers (Netscape etc,). It would be possible to use the "Explorer method" for
# all browsers but I do not want to punish all users just because Explorer is 
# a bit broken.

my $isExplorer = &P4CGI::IS_MSEXPLORER() ;


# Get number of digits required for revision and lineNo
my $lines = scalar @filetext ;
my $lineNoDigits = digits($lines) ;
my $revDigits    = digits($rev) ;
$revDigits = 1 unless $revDigits > 1 ;


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

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

unless($isExplorer) {
    print "<tr><th class=\"fileViewerHeader\">Add<br>Rev.</th>" ;
    print "<th class=\"fileViewerHeader\">Del<br>Rev.</th>" if $showdeleted ;
    print "<th class=\"fileViewerHeader\">Line</th><th class=\"fileViewerHeader\">Content</th></tr>\n" ;
} ;
my $lastRevStr = "" ;
my $lineNo = 0 ;
my @dataC ;

my $emptyRev    = substr("            ",0,$revDigits) ;    # lets hope there are never more than 999,999,999,999
my $emptyLineNo = substr("            ",0,$lineNoDigits) ; # lines in a file or revisions on a file!

my $emptyRevStr ;
if(defined $showdeleted) { $emptyRevStr = "$emptyRev     $emptyRev" ; } 
else                     { $emptyRevStr = "$emptyRev" ; } 

while(<P4>) {
    chomp ;
    s/^(\d+)-(\d+): // and do {
	my ($firstrev,$lastrev,$line) = ($1,$2,$_) ;
	my $addspaces = $revDigits - digits($firstrev) ;
	$firstrev = 
	    "<a class=\"normal\" title=\"Line(s) added by change $revToChange{$firstrev}. Click to view change.\" ".
	    " href=\"changeView.cgi?CH=$revToChange{$firstrev}\">$firstrev</a>" ;
	while($addspaces-- > 0) { $firstrev .= " " ; } ;
	if($lastrev < $rev) {
	    my $r = $lastrev + 1 ;
	    $addspaces = $revDigits - digits($r) ;
	    $lastrev = 
		"<a class=\"normal\" title=\"Line(s) deleted by change $revToChange{$r}. Click to view change.\" ".
		" href=\"changeView.cgi?CH=$revToChange{$r}\">$r</a>" ;
	    while($addspaces-- > 0) { $lastrev .= " " ; } ;
	}
	else {
	    $lastrev = "" ;
	}
	my $cclass = "" ;
	my $revStr = "XX" ;
	my $lineNoStr = "$emptyLineNo " ;
	if($lastrev ne "") {
	    next unless defined $showdeleted ;
	    $revStr = "A:$firstrev D:$lastrev" ;
	    $cclass= "class=\"deleted\"" ;
	    $line = &P4CGI::htmlEncode($line)
	}
	else {
	    $line = shift @filetext ;
	    if(defined $showdeleted) { $revStr = "A:$firstrev   $emptyRev" ; } 
	    else                     { $revStr = "$firstrev" ; } 
	    $lineNo++ ;
	    if($lineNo == 1 or $lineNo % 5 == 0) {
		
		$lineNoStr="<a name=\"L$lineNo\">".sprintf("%${lineNoDigits}d:",$lineNo)."</a>" ;
	    }
	    else {
		$lineNoStr="<a name=\"L$lineNo\">$emptyLineNo </a>" ;
	    }
	}
	my $revclass ;
	if($lastRevStr eq $revStr) {
	    $revStr = "$emptyRevStr" ;
	    $firstrev = "" ;
	    $lastrev = "" ;	    
	    $revclass="fileViewerRevEmpty" ;
	}
	else {
	    $lastRevStr = $revStr ; 
	    $revclass="fileViewerRev" ;
	} ;
	
	if($isExplorer) {
	    if($cclass ne "") {
		push @dataC ,	"".
		    "<span class=\"$revclass\">$revStr</span> ".
		    "<span class=\"fileViewerLineNo\">$lineNoStr</span>".
		    "<span $cclass>" .
		    "<span class=\"fileViewerData\">$line </span>".
		    "</span>" ;
	    } else {
		push @dataC ,	"".
		    "<span class=\"$revclass\">$revStr</span> ".
		    "<span class=\"fileViewerLineNo\">$lineNoStr</span>".
		    "<span class=\"fileViewerData\">$line </span>" ;
	    }
	}
	else {
	    print "<tr><th class=\"$revclass\">$firstrev</th>" ;
	    print "<th class=\"$revclass\">$lastrev</th>" if $showdeleted ;
	    print "<th class=\"fileViewerLineNo\">$lineNoStr</th><td $cclass>$line </td></tr>\n" ;
	}
    }
}
if($isExplorer) {
    print 
	"<tr>\n",
	"  <td class=\"fileViewerDataMSIE\"><pre>", join("\n",@dataC), "</pre></td>\n",
	"</tr>\n" ;   
} ;    

print "</table>" ;

close P4 ;


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

#
# That's all folks
#

__END__
:MSIE, 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 contain the revision where the line was added.
    <li> The second column shows source line numbers.
    <li> The third column shows the file content.
    </ol>
 
:MSIE, 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 three columns:
    <ol>
    <li> The first column contain the revision where the line was added prepended with <b>A:</b> and, 
         optionally the revision where the line was deleted prepended with a <b>D:</b>.
    <li> The second column shows source line numbers.
    <li> The third column shows the file content.
    </ol>

:Other, 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 "Add Rev." column contain the revision where the line was added.
    <li> The "Line" column shows source line numbers..
    <li> The "Content" column shows the file content.
    </ol>

:Other, 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 "Add Rev." column contain the revision where the line was added.
    <li> The "Del Rev." column contain the revision where the line was deleted
    <li> The "Line" column shows source line numbers..
    <li> The "Content" column shows the file content.
    </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