diff --git a/mozilla/webtools/bonsai/CGI.pl b/mozilla/webtools/bonsai/CGI.pl index fb02e8bd3fe..0b8f7a44171 100644 --- a/mozilla/webtools/bonsai/CGI.pl +++ b/mozilla/webtools/bonsai/CGI.pl @@ -77,16 +77,6 @@ sub url_encode2 { return $s; } -sub url_encode3 { - my ($s) = @_; - - $s =~ s/\n/\%0a/g; - $s =~ s/\r//g; - $s =~ s/\"/\%22/g; - $s =~ s/\+/\%2b/g; - return $s; -} - ## ## Routines to generate html as part of Bonsai ## diff --git a/mozilla/webtools/bonsai/cvslog.cgi b/mozilla/webtools/bonsai/cvslog.cgi index 21e9dc1d33b..abab98d0574 100755 --- a/mozilla/webtools/bonsai/cvslog.cgi +++ b/mozilla/webtools/bonsai/cvslog.cgi @@ -48,6 +48,9 @@ sub sillyness { require 'CGI.pl'; require 'cvsblame.pl'; +use Date::Parse; +use Date::Format; + # Some Globals # $| = 1; @@ -143,10 +146,6 @@ if ($browse_revtag eq 'HEAD') { } else { $start_rev = map_tag_to_revision($browse_revtag); } -print "Content-Type:text/html\n"; -print "Last-Modified: ".time2str("%a, %d %b %Y %T %Z", str2time($::revision_ctime{$start_rev}), "GMT")."\n"; -print "Expires: ".time2str("%a, %d %b %Y %T %Z", time+1200, "GMT")."\n"; -print "\n"; # Handle the "mark" argument # @@ -166,11 +165,29 @@ foreach my $author (split(',',$author_arg)) { $use_author{$author} = 1; } - # Handle the "sort" argument my $opt_sort = ''; $opt_sort = $::FORM{'sort'} if defined $::FORM{'sort'}; +my $sortstr = $opt_sort eq "author" ? "&sort=author" : ""; +print "Last-Modified: ".time2str("%a, %d %b %Y %T %Z", str2time($::revision_ctime{$start_rev}), "GMT")."\n"; +print "Expires: ".time2str("%a, %d %b %Y %T %Z", time+1200, "GMT")."\n"; + +my $ctype = $::FORM{ctype}; +if (defined($ctype) && $ctype eq "rss") { + print "Content-Type: application/rss+xml\n\n"; + display_rss(); +} +else { + print "Content-Type: text/html\n\n"; + display_html(); +} + +exit; + +## END of main script + +sub display_html { # Start printing out the page # @@ -241,6 +258,12 @@ print qq( Annotate the author of each line. + + + RSS  + + Get an RSS version of this page. + $graph_cell @@ -259,12 +282,11 @@ $graph_cell my $table_tag = ""; my $table_header_tag = ""; if ($opt_sort eq 'author') { - $table_header_tag .= "'; $output .= "
RevAuthorDateLog"; + $table_header_tag .= "RevAuthorDateLog" } else { $table_header_tag .= "RevAuthorDateLog"; } -$table_header_tag = &url_encode3($table_header_tag); print "$table_tag$table_header_tag"; # Print each line of the revision, preceded by its annotation. @@ -306,25 +328,7 @@ foreach $revision (@revisions) } $output .= "" - .""; - - my $anchor = "$revision" .' ' x ($max_rev_length - length($revision)).'".$author @@ -363,8 +367,124 @@ foreach $revision (@revisions) } print "
"; &print_bottom; +} -## END of main script +sub display_rss { + my @revisions = ($start_rev, ancestor_revisions($start_rev)); + @revisions = sort by_author @revisions if $opt_sort eq 'author'; + + # The escaped path+name of the file; included in the channel title. + my $html_filename = html_quote($filename); + + # The canonical URL of the file; we use a link to its revision history, + # but arguably this should be a link to the LXR page or, for web pages, + # a link to the actual web page. + my $link = Param("urlbase") . "cvslog.cgi?file=$url_filename"; + $link .= "&root=$root" if $::FORM{'root'} ne ""; + $link .= $revstr; + $link .= $sortstr; + $link .= "&author=$url_author_arg" if $author_arg ne ""; + $link = value_quote($link); + + print <<"END"; + + + + + Revision History for $html_filename + $link + Revision History for $html_filename + + +END + + # We loop over revisions twice. The first time, here, it's just to populate + # the "items" list of revisions inside the channel tag. All we need to know + # is whether to skip this author and the link to the revision. + foreach my $revision (@revisions) { + next unless $author_arg eq '' || $use_author{$::revision_author{$revision}}; + my $link = value_quote(revision_link($revision)); + print <<"END"; + +END + } + + print <<"END"; + + + +END + + # The second time we loop over revisions, it's to generate "item" resources + # for each one. + foreach my $revision (@revisions) { + my $author = $::revision_author{$revision}; + next unless $author_arg eq '' || $use_author{$author}; + $author = html_quote($author); + + my $link = value_quote(revision_link($revision)); + + my $log = $::revision_log{$revision}; + $log = html_quote($log); + $log = MarkUpText($log); + $log =~ s/\n|\r|\r\n/
/g; + + my $date = date_to_w3cdtf($::revision_ctime{$revision}); + + print <<"END"; + + Version $revision + $link + + $author + $date + +END + } + + print <<"END"; +
+END + +} + +sub revision_link { + my $revision = shift; + + my $link = Param('urlbase') . "cvsview2.cgi"; + if (defined($::prev_revision{$revision})) { + $link .= "?diff_mode=context&whitespace_mode=show&file=$url_file_tail" + . "&branch=$::opt_rev&root=$root&subdir=$url_rcs_path" + . "&command=DIFF_FRAMESET&rev1=$::prev_revision{$revision}" + . "&rev2=$revision"; + } else { + $link .= "?files=$url_file_tail&root=$root&subdir=$url_rcs_path" + . "\&command=DIRECTORY\&rev2=$revision&branch=$::opt_rev"; + $link .= "&branch=$browse_revtag" unless $browse_revtag eq 'HEAD'; + } + + return $link; +} + +# Format a date/time in W3CDTF per http://www.w3.org/TR/NOTE-datetime +sub date_to_w3cdtf { + my ($date) = @_; + + $date = str2time($date); + + # Date::Format returns timezone offsets without a colon, while W3CDTF + # requires a colon between the hour and minute offsets, so we have to + # convert the timezone specially. + my $timezone = time2str("%z", $date); + $timezone =~ s/([+-])(\d\d)(\d\d)/$1$2:$3/; + + $date = time2str("%Y-%m-%dT%R", $date) . $timezone; + + return $date; +} sub by_revision { my (@a_parts) = split(/\./,$a); @@ -386,11 +506,6 @@ sub by_author { return by_revision; } -sub revision_pad { - my ($revision) = @_; - return ' ' x ($max_rev_length - length($revision)); -} - sub sprint_author { my ($revision) = @_; my ($author) = $::revision_author{$revision};