2002-01-20 04:44:52 +03:00
|
|
|
#!/usr/bonsaitools/bin/perl -wT
|
1999-05-27 18:13:41 +04:00
|
|
|
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
|
|
|
#
|
1999-11-02 02:33:56 +03:00
|
|
|
# The contents of this file are subject to the Mozilla 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/MPL/
|
|
|
|
#
|
|
|
|
# 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.
|
|
|
|
#
|
1999-05-27 18:13:41 +04:00
|
|
|
# The Original Code is the Bugzilla Bug Tracking System.
|
1999-11-02 02:33:56 +03:00
|
|
|
#
|
1999-05-27 18:13:41 +04:00
|
|
|
# The Initial Developer of the Original Code is Netscape Communications
|
1999-11-02 02:33:56 +03:00
|
|
|
# Corporation. Portions created by Netscape are
|
|
|
|
# Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
# Rights Reserved.
|
|
|
|
#
|
1999-05-27 18:13:41 +04:00
|
|
|
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
2002-04-04 11:39:19 +04:00
|
|
|
# Gervase Markham <gerv@gerv.net>
|
1999-05-27 18:13:41 +04:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
|
2002-01-20 04:44:52 +03:00
|
|
|
use lib qw(.);
|
|
|
|
|
1999-05-27 18:13:41 +04:00
|
|
|
require "CGI.pl";
|
|
|
|
|
2001-05-31 19:52:25 +04:00
|
|
|
ConnectToDatabase();
|
|
|
|
|
|
|
|
quietly_check_login();
|
|
|
|
|
2002-09-22 21:15:13 +04:00
|
|
|
use vars qw($template $vars $userid);
|
1999-05-27 18:13:41 +04:00
|
|
|
|
|
|
|
my %seen;
|
|
|
|
my %edgesdone;
|
|
|
|
|
2002-05-07 13:14:38 +04:00
|
|
|
sub CreateImagemap {
|
|
|
|
my $mapfilename = shift;
|
|
|
|
my $map = "<map name=\"imagemap\">\n";
|
|
|
|
my $default;
|
|
|
|
|
|
|
|
open MAP, "<$mapfilename";
|
|
|
|
while(my $line = <MAP>) {
|
|
|
|
if($line =~ /^default ([^ ]*)(.*)$/) {
|
2002-06-28 04:18:32 +04:00
|
|
|
$default = qq{<area alt="" shape="default" href="$1">\n};
|
2002-05-07 13:14:38 +04:00
|
|
|
}
|
|
|
|
if ($line =~ /^rectangle \((.*),(.*)\) \((.*),(.*)\) (http[^ ]*)(.*)?$/) {
|
2002-06-28 04:18:32 +04:00
|
|
|
$map .= qq{<area alt="bug$6" name="bug$6" shape="rect" href="$5" coords="$1,$4,$3,$2">\n};
|
2002-05-07 13:14:38 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
close MAP;
|
|
|
|
|
|
|
|
$map .= "$default</map>";
|
|
|
|
return $map;
|
|
|
|
}
|
|
|
|
|
1999-05-27 18:13:41 +04:00
|
|
|
sub AddLink {
|
|
|
|
my ($blocked, $dependson) = (@_);
|
|
|
|
my $key = "$blocked,$dependson";
|
|
|
|
if (!exists $edgesdone{$key}) {
|
|
|
|
$edgesdone{$key} = 1;
|
|
|
|
print DOT "$blocked -> $dependson\n";
|
|
|
|
$seen{$blocked} = 1;
|
|
|
|
$seen{$dependson} = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-05-28 00:20:57 +04:00
|
|
|
$::FORM{'rankdir'} = "LR" if !defined $::FORM{'rankdir'};
|
|
|
|
|
2002-05-02 11:03:00 +04:00
|
|
|
if (!defined($::FORM{'id'}) && !defined($::FORM{'doall'})) {
|
2002-10-06 15:52:37 +04:00
|
|
|
ThrowCodeError("missing_bug_id");
|
2002-04-04 11:39:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
my $filename = "data/webdot/$$.dot";
|
|
|
|
my $urlbase = Param('urlbase');
|
1999-05-27 18:13:41 +04:00
|
|
|
|
2002-04-04 11:39:19 +04:00
|
|
|
open(DOT, ">$filename") || die "Can't create $filename";
|
|
|
|
print DOT "digraph G {";
|
|
|
|
print DOT qq{
|
1999-09-08 21:27:42 +04:00
|
|
|
graph [URL="${urlbase}query.cgi", rankdir=$::FORM{'rankdir'}, size="64,64"]
|
1999-05-27 18:13:41 +04:00
|
|
|
node [URL="${urlbase}show_bug.cgi?id=\\N", style=filled, color=lightgrey]
|
|
|
|
};
|
|
|
|
|
2002-04-04 11:39:19 +04:00
|
|
|
my %baselist;
|
1999-05-27 18:13:41 +04:00
|
|
|
|
2002-04-04 11:39:19 +04:00
|
|
|
if ($::FORM{'doall'}) {
|
|
|
|
SendSQL("SELECT blocked, dependson FROM dependencies");
|
|
|
|
|
|
|
|
while (MoreSQLData()) {
|
|
|
|
my ($blocked, $dependson) = FetchSQLData();
|
|
|
|
AddLink($blocked, $dependson);
|
|
|
|
}
|
|
|
|
} else {
|
2002-05-02 11:03:00 +04:00
|
|
|
foreach my $i (split('[\s,]+', $::FORM{'id'})) {
|
|
|
|
$i = trim($i);
|
|
|
|
ValidateBugID($i);
|
|
|
|
$baselist{$i} = 1;
|
|
|
|
}
|
|
|
|
|
2002-04-04 11:39:19 +04:00
|
|
|
my @stack = keys(%baselist);
|
|
|
|
foreach my $id (@stack) {
|
|
|
|
SendSQL("SELECT blocked, dependson
|
|
|
|
FROM dependencies
|
|
|
|
WHERE blocked = $id or dependson = $id");
|
1999-05-27 18:13:41 +04:00
|
|
|
while (MoreSQLData()) {
|
2002-04-04 11:39:19 +04:00
|
|
|
my ($blocked, $dependson) = FetchSQLData();
|
|
|
|
if ($blocked != $id && !exists $seen{$blocked}) {
|
|
|
|
push @stack, $blocked;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($dependson != $id && !exists $seen{$dependson}) {
|
|
|
|
push @stack, $dependson;
|
|
|
|
}
|
|
|
|
|
1999-05-27 18:13:41 +04:00
|
|
|
AddLink($blocked, $dependson);
|
|
|
|
}
|
2002-04-04 11:39:19 +04:00
|
|
|
}
|
|
|
|
|
2002-05-02 11:03:00 +04:00
|
|
|
foreach my $k (keys(%baselist)) {
|
|
|
|
$seen{$k} = 1;
|
|
|
|
}
|
2002-04-04 11:39:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
foreach my $k (keys(%seen)) {
|
|
|
|
my $summary = "";
|
|
|
|
my $stat;
|
|
|
|
if ($::FORM{'showsummary'}) {
|
2002-09-22 21:15:13 +04:00
|
|
|
if (CanSeeBug($k, $::userid)) {
|
|
|
|
SendSQL("SELECT bug_status, short_desc FROM bugs " .
|
|
|
|
"WHERE bugs.bug_id = $k");
|
|
|
|
($stat, $summary) = FetchSQLData();
|
|
|
|
$stat = "NEW" if !defined $stat;
|
|
|
|
$summary = "" if !defined $summary;
|
|
|
|
}
|
1999-05-27 18:13:41 +04:00
|
|
|
} else {
|
2002-04-04 11:39:19 +04:00
|
|
|
SendSQL("SELECT bug_status FROM bugs WHERE bug_id = $k");
|
|
|
|
$stat = FetchOneColumn();
|
1999-05-27 18:13:41 +04:00
|
|
|
}
|
2002-04-04 11:39:19 +04:00
|
|
|
my @params;
|
1999-05-27 18:13:41 +04:00
|
|
|
|
2002-04-04 11:39:19 +04:00
|
|
|
if ($summary ne "") {
|
|
|
|
$summary =~ s/([\\\"])/\\$1/g;
|
|
|
|
push(@params, qq{label="$k\\n$summary"});
|
1999-05-27 18:42:19 +04:00
|
|
|
}
|
2002-04-04 11:39:19 +04:00
|
|
|
|
|
|
|
if (exists $baselist{$k}) {
|
|
|
|
push(@params, "shape=box");
|
1999-05-27 18:13:41 +04:00
|
|
|
}
|
|
|
|
|
2002-04-04 11:39:19 +04:00
|
|
|
if ($stat =~ /^(NEW|ASSIGNED|REOPENED)$/) {
|
|
|
|
push(@params, "color=green");
|
|
|
|
}
|
1999-05-27 18:13:41 +04:00
|
|
|
|
2002-04-04 11:39:19 +04:00
|
|
|
if (@params) {
|
|
|
|
print DOT "$k [" . join(',', @params) . "]\n";
|
2002-03-31 08:19:07 +04:00
|
|
|
} else {
|
2002-04-04 11:39:19 +04:00
|
|
|
print DOT "$k\n";
|
1999-05-27 18:13:41 +04:00
|
|
|
}
|
2002-04-04 11:39:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
print DOT "}\n";
|
|
|
|
close DOT;
|
|
|
|
|
|
|
|
chmod 0777, $filename;
|
|
|
|
|
|
|
|
my $webdotbase = Param('webdotbase');
|
|
|
|
|
|
|
|
if ($webdotbase =~ /^https?:/) {
|
|
|
|
# Remote dot server
|
|
|
|
my $url = PerformSubsts($webdotbase) . $filename;
|
|
|
|
$vars->{'image_url'} = $url . ".gif";
|
|
|
|
$vars->{'map_url'} = $url . ".map";
|
1999-05-27 18:13:41 +04:00
|
|
|
} else {
|
2002-04-04 11:39:19 +04:00
|
|
|
# Local dot installation
|
|
|
|
my $pngfilename = "data/webdot/$$.png";
|
|
|
|
my $mapfilename = "data/webdot/$$.map";
|
|
|
|
system("$webdotbase","-Tpng","-o","$pngfilename","$filename");
|
|
|
|
$vars->{'image_url'} = $pngfilename;
|
2002-05-07 13:14:38 +04:00
|
|
|
system("$webdotbase","-Tismap","-o","$mapfilename","$filename");
|
|
|
|
$vars->{'image_map'} = CreateImagemap($mapfilename);
|
2002-04-04 11:39:19 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
# Cleanup any old .dot files created from previous runs.
|
|
|
|
my $since = time() - 24 * 60 * 60;
|
2002-07-10 03:40:32 +04:00
|
|
|
# Can't use glob, since even calling that fails taint checks for perl < 5.6
|
|
|
|
opendir(DIR, "data/webdot/");
|
|
|
|
my @files = grep { /\.dot$|\.png$|\.map$/ && -f "data/webdot/$_" } readdir(DIR);
|
|
|
|
closedir DIR;
|
|
|
|
foreach my $f (@files)
|
2002-04-04 11:39:19 +04:00
|
|
|
{
|
2002-07-10 03:40:32 +04:00
|
|
|
$f = "data/webdot/$f";
|
2002-04-04 11:39:19 +04:00
|
|
|
# Here we are deleting all old files. All entries are from the
|
|
|
|
# data/webdot/ directory. Since we're deleting the file (not following
|
|
|
|
# symlinks), this can't escape to delete anything it shouldn't
|
|
|
|
trick_taint($f);
|
|
|
|
if (ModTime($f) < $since) {
|
|
|
|
unlink $f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$vars->{'bug_id'} = $::FORM{'id'};
|
|
|
|
$vars->{'multiple_bugs'} = ($::FORM{'id'} =~ /[ ,]/);
|
|
|
|
$vars->{'doall'} = $::FORM{'doall'};
|
|
|
|
$vars->{'rankdir'} = $::FORM{'rankdir'};
|
|
|
|
$vars->{'showsummary'} = $::FORM{'showsummary'};
|
1999-05-27 18:13:41 +04:00
|
|
|
|
2002-04-04 11:39:19 +04:00
|
|
|
# Generate and return the UI (HTML page) from the appropriate template.
|
|
|
|
print "Content-type: text/html\n\n";
|
2002-04-24 11:24:50 +04:00
|
|
|
$template->process("bug/dependency-graph.html.tmpl", $vars)
|
|
|
|
|| ThrowTemplateError($template->error());
|