#!/usr/bin/perl -w # -*- Mode: perl; indent-tabs-mode: nil -*- # # The contents of this file are subject to the Netscape Public # License Version 1.1 (the "License"); you may not use this file # except in compliance with the License. You may obtain a copy of # the License at http://www.mozilla.org/NPL/ # # Software distributed under the License is distributed on an "AS # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or # implied. See the License for the specific language governing # rights and limitations under the License. # # The Original Code is the Bonsai CVS tool. # # The Initial Developer of the Original Code is Netscape Communications # Corporation. Portions created by Netscape are # Copyright (C) 1998 Netscape Communications Corporation. All # Rights Reserved. # # Contributor(s): Ben Hsieh (adds graph output button) use strict; # Shut up misguided -w warnings about "used only once". "use vars" just # doesn't work for me. sub sillyness { my $zz; $zz = $::CI_BRANCH; $zz = $::CI_REPOSITORY; $zz = $::lines_added; $zz = $::lines_removed; $zz = $::query_begin_tag; $zz = $::query_branchtype; $zz = $::query_dirtype; $zz = $::query_date_max; $zz = $::query_debug; $zz = $::query_end_tag; $zz = $::query_filetype; $zz = $::query_logexpr; $zz = $::query_whotype; $zz = $::script_type; } require 'CGI.pl'; $::query_debug = (defined($::FORM{'debug'}) ? 1 : 0); $::query_module = &SanitizeModule($::FORM{'module'}); $::CVS_ROOT = $::FORM{'cvsroot'}; $::CVS_ROOT = &pickDefaultRepository() unless $::CVS_ROOT; &validateRepository($::CVS_ROOT); $::TreeID = $::query_module if (!exists($::FORM{'treeid'}) && defined($::query_module) && exists($::TreeInfo{$::query_module}{'repository'})); $::TreeID = 'default' if (!exists($::TreeInfo{$::TreeID}{'repository'}) || exists($::TreeInfo{$::TreeID}{'nobonsai'})); &LoadTreeConfig(); require 'cvsquery.pl'; my $userdomain = Param('userdomain'); my $registryurl = Param('registryurl'); $registryurl =~ s@/$@@; $| = 1; my $sm_font_tag = ""; my $generateBackoutCVSCommands = 0; if (defined $::FORM{'generateBackoutCVSCommands'}) { $generateBackoutCVSCommands = 1; } my $show_raw = 0; if ($::FORM{'raw'}) { $show_raw = 1; } my $show_xml = 0; my $show_graph = 0; my $xml_nofiles = 0; if ($::FORM{'xml'}) { $show_xml = 1; if ($::FORM{'xml_nofiles'}) { $xml_nofiles = 1; } } if ($::FORM{'graph'}) { $show_graph = 1; } if (!$show_xml && !$generateBackoutCVSCommands) { print "Content-type: text/html; charset=UTF-8\n\n"; if (!$show_graph) { print setup_script(); } } elsif ($show_xml) { print "Content-type: text/xml\n\n"; } elsif ($generateBackoutCVSCommands) { print "Content-type: text/plain\n\n"; } #print "
";


my $CVS_REPOS_SUFIX = $::CVS_ROOT;
$CVS_REPOS_SUFIX =~ s/\//_/g;

my $CHECKIN_DATA_FILE = "data/checkinlog${CVS_REPOS_SUFIX}";
my $CHECKIN_INDEX_FILE = "data/index${CVS_REPOS_SUFIX}";


my $SORT_HEAD="bgcolor=\"#DDDDDD\"";

#
# Log the query
Log("Query [$ENV{'REMOTE_ADDR'}]: $ENV{'QUERY_STRING'}");

#
# build a module map
#

#
# allow ?file=/a/b/c/foo.c to be synonymous with ?dir=/a/b/c&file=foo.c
#
$::FORM{'file'} = "" unless defined $::FORM{'file'};
unless ($::FORM{'dir'}) {
    $::FORM{'file'} = Fix_BonsaiLink($::FORM{'file'});
    if ($::FORM{'file'} =~ m@(.*?/)([^/]*)$@) {
        $::FORM{'dir'} = $1;
        $::FORM{'file'} = $2;
    } else {
        $::FORM{'dir'} = "";
    }
}

#
# build a directory map
#
@::query_dirs = split(/[;, \t\000]+/, $::FORM{'dir'});

$::query_file = $::FORM{'file'};
$::query_filetype = &ExpectMatchtype($::FORM{'filetype'});
$::query_logexpr = $::FORM{'logexpr'};

#
# date
#
$::query_date_type = $::FORM{'date'} || 'nothing';
my $query_hours;
if( $::query_date_type eq 'hours' ){
    $query_hours = &ExpectDigit('hours', $::FORM{'hours'});
    $::query_date_min = time - $query_hours*60*60;
}
elsif( $::query_date_type eq 'day' ){
    $::query_date_min = time - 24*60*60;
}
elsif( $::query_date_type eq 'week' ){
    $::query_date_min = time - 7*24*60*60;
}
elsif( $::query_date_type eq 'month' ){
    $::query_date_min = time - 30*24*60*60;
}
elsif( $::query_date_type eq 'all' ){
    $::query_date_min = 0;
}
elsif( $::query_date_type eq 'explicit' ){
    if ($::FORM{'mindate'}) {
        $::query_date_min = parse_date($::FORM{'mindate'});
    }

    if ($::FORM{'maxdate'}) {
        $::query_date_max = parse_date($::FORM{'maxdate'});
    }
    if (defined($::query_date_min) && defined($::query_date_max) &&
        ($::query_date_max < $::query_date_min)) {
        ($::query_date_min, $::query_date_max) =
            ($::query_date_max, $::query_date_min);
    }
}
else {
    $::query_date_min = time-60*60*2;
}

#
# who
#
$::query_who = $::FORM{'who'};
$::query_whotype = &ExpectMatchtype($::FORM{'whotype'});
if ($::query_whotype eq 'notregexp' || $::query_whotype eq 'regexp') {
    $::query_who = &SanitizeRegexp($::query_who);
} else {
    $::query_who = &SanitizeUsernames($::query_who);
}

#
# branch
#
$::query_branch = $::FORM{'branch'};
$::query_branchtype = &ExpectMatchtype($::FORM{'branchtype'});
$::query_branch = 'HEAD' if !defined($::query_branch);
if ($::query_branchtype eq 'notregexp' || $::query_branchtype eq 'regexp') {
    $::query_branch = &SanitizeRegexp($::query_branch);
} else {
    $::query_branch = &SanitizeRevision($::query_branch);
}
$::query_dirtype = $::FORM{'dirtype'};
$::query_dirtype = 'recurse' if !defined ($::query_dirtype);

if ($::query_branch eq 'HEAD' && $::query_branchtype ne 'notregexp') {
    $::query_branch_head = 1 ;
}

#
# tags
#
$::query_begin_tag = &SanitizeRevision($::FORM{'begin_tag'});
$::query_end_tag = &SanitizeRevision($::FORM{'end_tag'});


#
# Get the query in english and print it.
#
my ($t, $e);
$t = $e = &query_to_english;
$t =~ s/<[^>]*>//g;

my %mod_map = ();
my $result= &query_checkins( %mod_map );

my %w;

for my $i (@{$result}) {
	my $aname=$i->[$::CI_WHO];
# the else is for compatibility w/ something that uses the other format
# the regexp is probably not the best, but I think it might work
	if ($aname =~ /%\w*.\w\w+/) {
		my $tmp = join("@",split("%",$aname));
		$w{"$tmp"} = 1;
	}else{
		$w{"$i->[$::CI_WHO]\@$userdomain"} = 1;
	}
}

my @p = sort keys %w;
my $pCount = @p;
my $s = join(",%20", @p);

$e =~ s/Checkins in/In/;

my $menu = "

$e

Modify Query "; if ($pCount) { my $persons = "people"; $persons = "person" if ($pCount == 1); $menu .= "
Mail everyone on this page ($pCount $persons)
Show commands which could be used to back out these changes "; } if (defined $::FORM{'generateBackoutCVSCommands'}) { print "Content-type: text/plain # This page can be saved as a shell script and executed. It should be # run at the top of your CVS work area. It will update your workarea to # backout the changes selected by your query. "; unless ($pCount) { print " # # No changes occurred during this interval. # There is nothing to back out. # "; exit; } foreach my $ci (reverse @{$result}) { if ($ci->[$::CI_REV] eq "") { print "echo 'Changes made to $ci->[$::CI_DIR]/$ci->[$::CI_FILE] need to be backed out by hand'\n"; next; } my $prev_revision = PrevRev($ci->[$::CI_REV]); print "cvs update -j$ci->[$::CI_REV] -j$prev_revision $ci->[$::CI_DIR]/$ci->[$::CI_FILE]\n"; } exit; } if (!$show_xml && !$show_graph) { PutsHeader($t, "CVS Checkins", "$menu"); } # # Test code to print the results # $|=1; my $head_who = ''; my $head_file = ''; my $head_directory = ''; my $head_delta = ''; my $head_date = ''; if ($show_graph) { my $headerinfo = ''; # headerinfo will be written enclosed in the tag generated by PutsHeader $headerinfo .= ''; # this part sets up the variables checkinsbargraph.js expects $headerinfo .= ' }; return $script_str; } # # Actually do the query # sub query_to_english { my $english = 'Checkins '; $::query_module = 'all' unless defined $::query_module; if( $::query_module eq 'allrepositories' ){ $english .= "to All Repositories "; } elsif( $::query_module ne 'all' && @::query_dirs == 0 ){ $english .= "to module " . html_quote($::query_module) . " "; } elsif( $::FORM{dir} ne "" ) { my $word = "directory"; if (@::query_dirs > 1) { $word = "directories"; } $english .= "to $word " . html_quote($::FORM{dir}) . " "; } if ($::query_file ne "") { if ($english ne 'Checkins ') { $english .= "and "; } if (defined($::query_filetype) && $::query_filetype eq 'regexp') { $english .= "to a file like "; } elsif (defined($::query_filetype) && $::query_filetype eq 'notregexp') { $english .= "to a file not like "; } else { $english .= "to file "; } $english .= "" . &html_quote($::query_file) . " "; } if (!$::query_branch_head) { if ($::query_branch eq '') { $english .= "on all branches "; } else { if ($::query_branchtype eq 'notregexp') { if ($::query_branch eq 'HEAD') { $english .= "not on "; } else { $english .= "not like "; } } elsif ($::query_branchtype eq 'regexp') { $english .= "like "; } else { $english .= "on "; } $english .= "branch " . html_quote($::query_branch) . " "; } } if( $::query_who) { if (defined($::query_whotype) && $::query_whotype eq 'regexp') { $english .= "by someone like "; } elsif (defined($::query_whotype) && $::query_whotype eq 'notregexp') { $english .= "by someone not like "; } else { $english .= "by "; } $english .= "" . &html_quote($::query_who) . " "; } $::query_date_type = $::FORM{'date'} || 'nothing'; if( $::query_date_type eq 'hours' ){ $english .="in the last $query_hours hours"; } elsif( $::query_date_type eq 'day' ){ $english .="in the last day"; } elsif( $::query_date_type eq 'week' ){ $english .="in the last week"; } elsif( $::query_date_type eq 'month' ){ $english .="in the last month"; } elsif( $::query_date_type eq 'all' ){ $english .="since the beginning of time"; } elsif( $::query_date_type eq 'explicit' ){ my ($w1, $w2); if ( $::FORM{mindate} && $::FORM{maxdate}) { $w1 = "between"; $w2 = "and" ; } else { $w1 = "since"; $w2 = "before"; } if( $::FORM{'mindate'}){ my $dd = &parse_date($::FORM{'mindate'}); my ($sec,$minute,$hour,$mday,$mon,$year) = localtime( $dd ); my $t = sprintf("%04d-%02d-%02d %02d:%02d",$year+1900,$mon+1,$mday,$hour,$minute); $english .= "$w1 $t "; } if( $::FORM{'maxdate'}){ my $dd = &parse_date($::FORM{'maxdate'}); my ($sec,$minute,$hour,$mday,$mon,$year) = localtime( $dd ); my $t = sprintf("%04d-%02d-%02d %02d:%02d",$year+1900,$mon+1,$mday,$hour,$minute); $english .= "$w2 $t "; } } return $english . ":"; } PutsTrailer();