? a2.pl
? a3.pl
? a4.pl
? bb1
? diff
? patch
? testscript.pl
Index: checksetup.pl
===================================================================
RCS file: /cvs/gnome/bugzilla-newer/checksetup.pl,v
retrieving revision 1.41
diff -u -p -r1.41 checksetup.pl
--- checksetup.pl	14 Oct 2006 22:41:54 -0000	1.41
+++ checksetup.pl	5 Nov 2006 16:12:47 -0000
@@ -4614,6 +4614,10 @@ if (!$dbh->bz_column_info('profiles', 'i
                         {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'FALSE'});
 }
 
+# Bugzilla.gnome.org:
+$dbh->bz_add_table('traces') if !$dbh->bz_table_info('traces');
+AddGroup('edittraces', 'Can edit stack traces for all products');
+
 # 2006-08-19 LpSolit@gmail.com - Bug 87795
 $dbh->bz_alter_column('tokens', 'userid', {TYPE => 'INT3'});
 
Index: edittraces.cgi
===================================================================
RCS file: edittraces.cgi
diff -N edittraces.cgi
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ edittraces.cgi	5 Nov 2006 16:12:47 -0000
@@ -0,0 +1,229 @@
+#!/usr/bin/perl -wT
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# 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.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# 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): Terry Weissman <terry@mozilla.org>
+
+use strict;
+
+use lib qw(.);
+use vars qw ($template $vars);
+# Suppress "used only once" warnings.
+use vars 
+  qw(
+    %proddesc
+    %classdesc
+  );
+
+use Bugzilla;
+use Bugzilla::Constants;
+use Bugzilla::GNOME;
+use Digest::MD5 qw(md5_hex);
+
+require "CGI.pl";
+
+use vars qw($vars @legal_product @legal_gnome_target @legal_gnome_version
+            @legal_priority @legal_severity);
+
+my $cgi = Bugzilla->cgi;
+my $dbh = Bugzilla->dbh;
+
+###############################################################################
+# Begin Data/Security Validation
+###############################################################################
+
+# Check whether or not the user is currently logged in. 
+Bugzilla->login(LOGIN_REQUIRED);
+GetVersionTable();
+
+UserInGroup("edittraces")
+  || ThrowUserError("auth_failure", {group  => "edittraces",
+                                     action => "edit",
+                                     object => "traces"});
+
+my $action   = trim($cgi->param('action')   || '');
+my $hash     = trim($cgi->param('hash')     || '');
+my $old_hash = trim($cgi->param('old_hash') || '');
+trick_taint($hash); trick_taint($old_hash);
+
+my $report = "traces/list.html.tmpl";
+my $cur_trace;
+
+print $cgi->header();
+
+sub ValidateForm {
+    my %cur_trace;
+
+    my $id = trim($cgi->param('dupe_of') || '');
+    ValidateBugID($id);
+
+    my $trace = trim($cgi->param('trace') || '');
+    trick_taint($trace);
+    my $version = trim($cgi->param('version') || '');
+    trick_taint($version);
+    $version = undef unless $version;
+    
+    my $product_id = trim($cgi->param('product_id') || undef);
+
+    my $product;
+    if ($product_id) {
+        detaint_natural($product_id) || ThrowCodeError("invalid_product_id");
+        $product = get_product_name($product_id);
+        CanEnterProductOrWarn($product);
+    }
+   
+    CheckFormField($cgi, 'gnome_version', \@legal_gnome_version)
+        if $cgi->param('gnome_version');
+    my $gnome_version = $cgi->param('gnome_version');
+    $gnome_version = undef unless $gnome_version;
+    trick_taint($gnome_version) if $gnome_version;
+
+    my $functions = join(' ', get_traces_from_string($trace));
+    my $hash = md5_hex($functions);
+
+    %cur_trace = (
+        hash => $hash,
+        dupe_of => $id,
+        product_id => $product_id,
+        user_id => Bugzilla->user->id,
+        version => $version,
+        gnome_version => $gnome_version,
+        trace => $trace,
+
+        functions => $functions,
+        product => $product,
+    );
+
+    return \%cur_trace;
+}
+
+if ($action eq 'add') {
+    $report = "traces/show.html.tmpl";
+
+    $cur_trace = ValidateForm();
+
+    $cur_trace->{'is_dupe'} = $dbh->selectrow_array(
+        'SELECT 1 FROM traces WHERE hash = ?', undef, $cur_trace->{'hash'});
+
+    if ($cgi->param('do_add') && $cur_trace->{'functions'} ne ''
+        && !$cur_trace->{'is_dupe'})
+    {
+        $dbh->do('INSERT INTO traces (hash, dupe_of, product_id, user_id,
+                                      version, gnome_version, trace)
+                       VALUES (?, ?, ?, ?, ?, ?, ?)',
+               undef, ($cur_trace->{'hash'}, $cur_trace->{'dupe_of'},
+                       $cur_trace->{'product_id'}, $cur_trace->{'user_id'},
+                       $cur_trace->{'version'}, $cur_trace->{'gnome_version'},
+                       $cur_trace->{'trace'}));
+        
+        $vars->{'message'} = 'trace_created';
+        $action = 'edit';
+        $old_hash = '';
+    }
+    else {
+        $vars->{'cur_trace'} = $cur_trace;
+    }
+}
+if ($action eq 'edit') {
+    $report = "traces/show.html.tmpl";
+
+    if ($old_hash) {
+        # Validate:
+        $cur_trace = ValidateForm();
+        my $trace_info = Bugzilla::GNOME->get_traces_info($old_hash);
+        ThrowUserError('trace_nonexistent') unless @{$trace_info};
+
+        $cur_trace->{'old_hash'} = $old_hash;
+
+        if ($cur_trace->{'old_hash'} eq $cur_trace->{'hash'}) {
+            $cur_trace->{'is_dupe'} = 0
+        } else {
+          $cur_trace->{'is_dupe'} = $dbh->selectrow_array(
+                'SELECT 1 FROM traces WHERE hash = ?', undef, $cur_trace->{'hash'});
+        }
+
+        if ($cgi->param('do_edit') && $cur_trace->{'functions'} ne ''
+            && !$cur_trace->{'is_dupe'})
+        {
+            $dbh->do('UPDATE traces
+                         SET hash = ?, dupe_of = ?, product_id = ?, user_id = ?,
+                             version = ?, gnome_version = ?, trace = ?
+                       WHERE hash = ?',
+                     undef, ($cur_trace->{'hash'}, $cur_trace->{'dupe_of'},
+                             $cur_trace->{'product_id'}, $cur_trace->{'user_id'},
+                             $cur_trace->{'version'}, $cur_trace->{'gnome_version'},
+                             $cur_trace->{'trace'},
+                             $cur_trace->{'old_hash'}));
+
+            # Very important (old_hash has been changed in the database to hash!):
+            $cur_trace->{'old_hash'} = $cur_trace->{'hash'};
+
+            $trace_info = Bugzilla::GNOME->get_traces_info($cur_trace->{'hash'});
+            $cur_trace = $trace_info->[0]; # get the data again from the database.. just for testing purposes
+            $vars->{'message'} = 'trace_updated';
+        }
+
+    } else {
+        my $trace_info = Bugzilla::GNOME->get_traces_info($hash);
+        ThrowUserError('trace_nonexistent') unless @{$trace_info};
+
+        $cur_trace = $trace_info->[0];
+        $cur_trace->{'old_hash'} = $cur_trace->{'hash'};
+    }
+}
+elsif ($action eq "delete") {
+    my $trace_info = Bugzilla::GNOME->get_traces_info($hash);
+    ThrowUserError('trace_nonexistent') unless @{$trace_info};
+
+    $cur_trace = $trace_info->[0];
+    
+    if ($cgi->param('do_delete')) {
+        $dbh->do('DELETE FROM traces WHERE hash = ?', undef, ($hash));
+        $vars->{'message'} = 'trace_deleted';
+    }
+    else {
+        $action = 'delete';
+        $report = 'traces/confirm-delete.html.tmpl';
+    }
+}
+
+$vars->{'legal_gnome_versions'} = \@legal_gnome_version;
+my %products = reverse GetSelectableProducts(1);
+$vars->{'products'} = \%products;
+$vars->{'action'} = $action;
+
+if ($cur_trace && %{$cur_trace}) {
+    if (defined $cur_trace->{'dupe_of'}) {
+        $cur_trace->{'dupe_of_bug'} =
+            new Bugzilla::Bug($cur_trace->{'dupe_of'}, Bugzilla->user->id);
+    }
+
+    if (!defined $cur_trace->{'functions'}
+        && defined $cur_trace->{'trace'})
+    {
+        $cur_trace->{'functions'} =
+            join(' ', get_traces_from_string($cur_trace->{'trace'}));
+    }
+    $vars->{'cur_trace'} = $cur_trace;
+}
+
+$template->process($report, $vars)
+  || ThrowTemplateError($template->error());
+
+
Index: Bugzilla/GNOME.pm
===================================================================
RCS file: Bugzilla/GNOME.pm
diff -N Bugzilla/GNOME.pm
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Bugzilla/GNOME.pm	5 Nov 2006 16:12:47 -0000
@@ -0,0 +1,121 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# 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.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# 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): Olav Vitters <olav@bkor.dhs.org>
+
+use strict;
+
+package Bugzilla::GNOME;
+
+use Bugzilla;
+use Bugzilla::Config;
+use base qw(Exporter);
+@Bugzilla::GNOME::EXPORT = qw(
+    get_traces_from_string
+); 
+
+=head1 get_traces_from_string
+
+takes a string that may contain a stack trace. If it does contain
+a viable stack trace, the first five useful functions are returned.
+
+=cut
+sub get_traces_from_string {
+  my ($string) = @_;
+  my @functions = ();
+  my $function_index = -1;
+  my @lines = split('\n', $string);
+
+  # For a simplification, all of this could be done in one
+  # regexp. [Ben Frantzdale] You volunteering to write it, Ben? :)
+  # [Luis 'not great with regexp' Villa]
+
+  my $possible_starts = join('|', ('<signal handler called>',
+                                   'killpg',
+                                   'sigaction',
+                                   'sigsuspend',
+                                   '\(gdb\) bt',
+                                   'gnome_init',
+                                   'g_log'));
+  my $bad_functions = join('|', ('__kernel_vsyscall',
+                                 'raise',
+                                 'abort'));
+
+  foreach my $line (@lines) {
+  # Here, we try to ignore things before <signal handler> and/or killpg()
+    if ( $line =~ /$possible_starts/ ) {
+      # Now we've started looking for real functions, or reset after
+      # reading g_log tops
+      $function_index = 0;
+    }
+    elsif ( $line =~ /^#\d+ +0x[0-9A-F]+ in ((\w|::|_)+) \(/i &&
+	    $function_index >= 0){
+      # eliminate dups
+      if ($function_index != 0 && $functions[$function_index-1] eq $1) {
+        next;
+      }
+
+      # eliminate meaningless functions in the stack trace
+      if ($1 =~ /$bad_functions/) {
+        next;
+      }
+      $functions[$function_index]=$1;
+      $function_index++;
+    }
+    # We stop after five functions are found:
+    last if $function_index > 4;
+  }
+
+  #did we go all the way through without getting any frames?
+  #if so, we've got a weird trace; we'll pick it up ourselves [since we take for granted there is actually a trace there]
+  if ( $function_index == -1 ) {
+      foreach my $line (@lines) {
+          if ( $line =~ /^#\d+ +0x[0-9A-F]+ in ((\w|::|_)+) \(/i ){
+              push(@functions, $1);
+              $function_index++;
+          }
+          # We stop after five functions are found:
+          last if $function_index > 3; # only go to three because we started at -1
+      }
+  }
+
+  return grep {$_} @functions;
+}
+
+sub get_traces_info {
+    my $self = shift;
+
+    my ($hash) = @_;
+    my $dbh = Bugzilla->dbh;
+
+    my @args = ();
+    push @args, $hash if $hash;
+
+    return $dbh->selectall_arrayref(
+        'SELECT hash, dupe_of, product_id, user_id, version, gnome_version, 
+                trace, products.name AS product
+           FROM traces
+      LEFT JOIN products
+             ON traces.product_id = products.id' . (defined $hash ? '
+          WHERE hash = ?' : ''),  {'Slice' => {}}, @args);
+
+}
+
+
+1;
Index: Bugzilla/RPC.pm
===================================================================
RCS file: /cvs/gnome/bugzilla-newer/Bugzilla/RPC.pm,v
retrieving revision 1.11
diff -u -p -r1.11 RPC.pm
--- Bugzilla/RPC.pm	18 Oct 2006 15:51:22 -0000	1.11
+++ Bugzilla/RPC.pm	5 Nov 2006 16:12:47 -0000
@@ -10,6 +10,8 @@ use Bugzilla::DB;
 use Bugzilla::Error;
 use Bugzilla::Config;
 use Bugzilla::User;
+use Bugzilla::GNOME;
+use Digest::MD5 qw(md5_hex);
 
 # These are functions written by me or extracted from hard-to-extract places.
 #  heavily hacked and custom function
@@ -232,6 +234,40 @@ sub Add {
     push (@used_fields, 'product_id');
     $data{'component_id'} = $component_id;
     push (@used_fields, 'component_id');
+
+
+    my @functions = get_traces_from_string($comment);
+    if (@functions) {
+        my $hash = md5_hex(join(" ", @functions));
+
+        my $dupe_id = $dbh->selectrow_array(
+            'SELECT dupe_of
+               FROM traces
+              WHERE hash = ?
+                AND (product_id = ? OR product_id IS NULL)
+                AND (version = ? or version IS NULL)
+                AND (gnome_version = ? or gnome_version IS NULL)',
+            undef,
+            ($hash, $product_id, $data{'version'}, $data{'gnome_version'}));
+
+        if ($dupe_id) {
+            # XXX - check status of dupe
+            #
+            # if NEEDINFO.. foo 1
+            # if OPEN, add stack?
+            # if CLOSED, do nothing?
+            my $dupe_status = $dbh->selectrow_array(
+                'SELECT bug_status FROM bugs WHERE bug_id = ?', undef, $dupe_id);
+
+#            if (IsOpenedState($dupe_status)) {
+#                # XXX - MIA
+#                #
+#            } else {
+#                # Fake the reporter created the bug this strack is a duplicate of
+                return $dupe_id;
+#            }
+        }
+    }
 
     # get current time
     my $timestamp = $dbh->selectrow_array("SELECT NOW()");
Index: Bugzilla/DB/Schema.pm
===================================================================
RCS file: /cvs/gnome/bugzilla-newer/Bugzilla/DB/Schema.pm,v
retrieving revision 1.8
diff -u -p -r1.8 Schema.pm
--- Bugzilla/DB/Schema.pm	27 Aug 2006 12:42:58 -0000	1.8
+++ Bugzilla/DB/Schema.pm	5 Nov 2006 16:12:47 -0000
@@ -696,6 +696,22 @@ use constant ABSTRACT_SCHEMA => {
         ],
     },
 
+    traces => {
+        FIELDS => [
+            hash          => {TYPE => 'varchar(32)', NOTNULL => 1,
+                              PRIMARYKEY => 1},
+            dupe_of       => {TYPE => 'INT3', NOTNULL => 1},
+            product_id    => {TYPE => 'INT3', NOTNULL => 1},
+            user_id       => {TYPE => 'INT3', NOTNULL => 1},
+            version       => {TYPE => 'varchar(64)'},
+            gnome_version => {TYPE => 'varchar(64)'},
+            trace         => {TYPE => 'MEDIUMTEXT'},
+        ],
+        INDEXES => [
+            traces_dupe_of_idx  => ['dupe_of'],
+        ],
+    },
+
     namedqueries => {
         FIELDS => [
             userid       => {TYPE => 'INT3', NOTNULL => 1},
Index: Bugzilla/Template/Plugin/GNOME.pm
===================================================================
RCS file: Bugzilla/Template/Plugin/GNOME.pm
diff -N Bugzilla/Template/Plugin/GNOME.pm
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Bugzilla/Template/Plugin/GNOME.pm	5 Nov 2006 16:12:47 -0000
@@ -0,0 +1,64 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# 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.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# 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): Olav Vitters <olav@bkor.dhs.org>
+#
+
+package Bugzilla::Template::Plugin::GNOME;
+
+use strict;
+
+use base qw(Template::Plugin);
+
+use Bugzilla::GNOME;
+
+sub new {
+    my ($class, $context) = @_;
+
+    return bless {}, $class;
+}
+
+sub AUTOLOAD {
+    my $class = shift;
+    our $AUTOLOAD;
+
+    $AUTOLOAD =~ s/^.*:://;
+
+    return if $AUTOLOAD eq 'DESTROY';
+
+    return Bugzilla::GNOME->$AUTOLOAD(@_);
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Bugzilla::Template::Plugin::GNOME
+
+=head1 DESCRIPTION
+
+Template Toolkit plugin to allow access to the C<GNOME>
+object.
+
+=head1 SEE ALSO
+
+L<Bugzilla::GNOME>, L<Template::Plugin>
+
Index: dupfinder/find-traces.pl
===================================================================
RCS file: /cvs/gnome/bugzilla-newer/dupfinder/find-traces.pl,v
retrieving revision 1.9
diff -u -p -r1.9 find-traces.pl
--- dupfinder/find-traces.pl	18 Oct 2006 19:18:49 -0000	1.9
+++ dupfinder/find-traces.pl	5 Nov 2006 16:12:47 -0000
@@ -4,78 +4,6 @@ use strict;
 use Bugzilla;
 my $dbh = Bugzilla->dbh;
 
-=head1 get_traces_from_string
-
-takes a string that may contain a stack trace. If it does contain
-a viable stack trace, the first five useful functions are returned.
-
-=cut
-
-sub get_traces_from_string {
-  my ($string) = @_;
-  my @functions = ();
-  my $function_index = -1;
-  my @lines = split('\n', $string);
-
-  # For a simplification, all of this could be done in one
-  # regexp. [Ben Frantzdale] You volunteering to write it, Ben? :)
-  # [Luis 'not great with regexp' Villa]
-
-  my $possible_starts = join('|', ('<signal handler called>',
-                                   'killpg',
-                                   'sigaction',
-                                   'sigsuspend',
-                                   '\(gdb\) bt',
-                                   'gnome_init',
-                                   'g_log'));
-  my $bad_functions = join('|', ('__kernel_vsyscall',
-                                 'raise',
-                                 'abort'));
-
-  foreach my $line (@lines) {
-  # Here, we try to ignore things before <signal handler> and/or killpg()
-    if ( $line =~ /$possible_starts/ ) {
-      # Now we've started looking for real functions, or reset after
-      # reading g_log tops
-      $function_index = 0;
-    }
-    elsif ( $line =~ /^#\d+ +0x[0-9A-F]+ in ((\w|::|_)+) \(/i &&
-	    $function_index >= 0){
-      # eliminate dups
-      if ($function_index != 0 && $functions[$function_index-1] eq $1) {
-        next;
-      }
-
-      # eliminate meaningless functions in the stack trace
-      if ($1 =~ /$bad_functions/) {
-        next;
-      }
-      $functions[$function_index]=$1;
-      $function_index++;
-    }
-    # We stop after five functions are found:
-    last if $function_index > 4;
-  }
-
-  #did we go all the way through without getting any frames?
-  #if so, we've got a weird trace; we'll pick it up ourselves [since we take for granted there is actually a trace there]
-  if ( $function_index == -1 ) {
-      foreach my $line (@lines) {
-          if ( $line =~ /^#\d+ +0x[0-9A-F]+ in ((\w|::|_)+) \(/i ){
-              push(@functions, $1);
-              $function_index++;
-          }
-          # We stop after five functions are found:
-          last if $function_index > 3; # only go to three because we started at -1
-      }
-  }
-
-  return @functions;
-}
-
-
-
-
 
 =head1 get_long_description_from_database
 
Index: dupfinder/simple-dup-finder.cgi
===================================================================
RCS file: /cvs/gnome/bugzilla-newer/dupfinder/simple-dup-finder.cgi,v
retrieving revision 1.7
diff -u -p -r1.7 simple-dup-finder.cgi
--- dupfinder/simple-dup-finder.cgi	5 Nov 2006 11:50:52 -0000	1.7
+++ dupfinder/simple-dup-finder.cgi	5 Nov 2006 16:12:47 -0000
@@ -72,15 +72,15 @@ if (defined($bug_id) || defined($custom_
   }
   else {
     ValidateBugID($bug_id);
-    $comment_id || = 0;
-    $comment_id unless detaint_natural($comment_id);
+    $comment_id ||= 0;
+    $comment_id = 0 unless detaint_natural($comment_id);
     
     $text = 
       $dbh->selectrow_array("SELECT substr(thetext, 1, 7500)
                                FROM longdescs
                               WHERE bug_id = ?
                            ORDER BY bug_when
-                              LIMIT 1 OFFSET ?", undef, ($bug_id, $comment_id));
+                              LIMIT 1 OFFSET $comment_id", undef, ($bug_id));
     $vars->{'bug_id'} = $bug_id;
     $vars->{'comment_id'} = $comment_id;
   }
Index: template/en/custom/pages/admin.html.tmpl
===================================================================
RCS file: /cvs/gnome/bugzilla-newer/template/en/custom/pages/admin.html.tmpl,v
retrieving revision 1.2
diff -u -p -r1.2 admin.html.tmpl
--- template/en/custom/pages/admin.html.tmpl	18 Dec 2005 16:43:19 -0000	1.2
+++ template/en/custom/pages/admin.html.tmpl	5 Nov 2006 16:12:48 -0000
@@ -55,6 +55,8 @@ Choose one of:
                                                  IF user.groups.editkeywords %]
         [% ' <li> <a href="editwhines.cgi">Whining</a>' 
                                               IF user.groups.bz_canusewhines %]
+        [% ' <li> <a href="edittraces.cgi">Stack traces</a>'
+                                              IF user.groups.edittraces %]
 </ul>
     </div>
 
Index: template/en/custom/traces/confirm-delete.html.tmpl
===================================================================
RCS file: template/en/custom/traces/confirm-delete.html.tmpl
diff -N template/en/custom/traces/confirm-delete.html.tmpl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ template/en/custom/traces/confirm-delete.html.tmpl	5 Nov 2006 16:12:48 -0000
@@ -0,0 +1,44 @@
+[%# 1.0@bugzilla.org %]
+[%# 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.
+  #
+  # The Original Code is the Bugzilla Bug Tracking System.
+  #
+  # 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): Terry Weissman <terry@mozilla.org>
+  #                 Vlad Dascalu <jocuri@softhome.net>
+  #%]
+
+[%# INTERFACE:
+  # name: string. The name of the keyword.
+  # keyword_id: number. The ID of the keyword.
+  # bug_count: number. The number of bugs with the keyword.
+  #%]
+
+[% PROCESS global/header.html.tmpl
+  title = "Delete Trace"
+%]
+
+<p>
+  Are you <b>sure</b> you want to delete
+  the <code>[% name FILTER html %]</code> trace?
+</p>
+
+<form action="edittraces.cgi" method="POST">
+  <input name="hash" type="hidden" value="[% cur_trace.hash FILTER html %]">
+  <input type="hidden" name="action" value="[% action FILTER html %]">
+  <input type="submit" name="do_delete" value="Yes, really delete the trace">
+</form>
+
+[% PROCESS global/footer.html.tmpl %] 
Index: template/en/custom/traces/list.html.tmpl
===================================================================
RCS file: template/en/custom/traces/list.html.tmpl
diff -N template/en/custom/traces/list.html.tmpl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ template/en/custom/traces/list.html.tmpl	5 Nov 2006 16:12:48 -0000
@@ -0,0 +1,77 @@
+[%# 1.0@bugzilla.org %]
+[%# -*- mode: html -*- %]
+[%# 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.
+  #
+  # The Original Code is the Bugzilla Bug Tracking System.
+  #
+  # The Initial Developer of the Original Code is Olav Vitters
+  # Corporation. Portions created by Netscape are
+  # Copyright (C) 2005 Olav Vitters Corporation. All
+  # Rights Reserved.
+  #
+  #%]
+
+[%# INTERFACE:
+  # This template has no interface.
+  #%]
+
+[% PROCESS global/variables.none.tmpl %]
+
+[% PROCESS global/header.html.tmpl
+    title = "Auto strack trace rejecting"
+    h1 = "" %]
+
+[% USE GNOME %]
+
+[% PROCESS "traces/show.html.tmpl" action="add" cur_trace = {} hide_header = 1 %]
+
+<br><hr><br>
+
+<table>
+<tr><th>Action</th><th>Main bug</th><th>Product</th><th>user_id</th><th>Version</th><th>GNOME version</th></tr>
+[% data = GNOME.get_traces_info %]
+[% FOREACH row = data %]
+  <tr>
+    <td>
+      <a name="[% row.hash FILTER html %]" href="edittraces.cgi?action=edit&amp;hash=[% row.hash FILTER url_quote %]">Edit</a>
+      | <a href="edittraces.cgi?action=delete&amp;hash=[% row.hash FILTER url_quote %]">Remove</a>
+      | <a href="#" onClick="document.getElementById('st_[% row.hash FILTER js %]').style.display = 'block'; return false">Show bt</a>
+    </td>
+    <td>[% row.dupe_of FILTER bug_link(row.dupe_of) %]</td>
+    <td>
+      [% IF product %]
+        <a href="browse.cgi?product=[% row.product FILTER html %]">[% row.product FILTER html %]</a>
+      [% ELSE %]
+        <i>Any</i>
+      [% END %]
+    </td>
+    <td>[% row.user_id FILTER html %]</td>
+    <td>
+      [% IF row.version %]
+        [% row.version FILTER html %]
+      [% ELSE %]
+        <i>Any</i>
+      [% END %]
+    </td>
+    <td>
+      [% IF row.gnome_version %]
+        [% row.gnome_version FILTER html %]
+      [% ELSE %]
+        <i>Any</i>
+      [% END %]
+    </td>
+  </tr>
+  <tr><td colspan="6"><div style="display: none" id="st_[% row.hash FILTER html %]">Stack trace:<br><pre>[% row.trace FILTER quoteUrls %]</pre></div></td></tr>
+[% END %]
+</table>
+
+
+[% PROCESS global/footer.html.tmpl %]
Index: template/en/custom/traces/show.html.tmpl
===================================================================
RCS file: template/en/custom/traces/show.html.tmpl
diff -N template/en/custom/traces/show.html.tmpl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ template/en/custom/traces/show.html.tmpl	5 Nov 2006 16:12:48 -0000
@@ -0,0 +1,122 @@
+[%# 1.0@bugzilla.org %]
+[%# -*- mode: html -*- %]
+[%# 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.
+  #
+  # The Original Code is the Bugzilla Bug Tracking System.
+  #
+  # The Initial Developer of the Original Code is Olav Vitters
+  # Corporation. Portions created by Netscape are
+  # Copyright (C) 2005 Olav Vitters Corporation. All
+  # Rights Reserved.
+  #
+  #%]
+
+[%# INTERFACE:
+  # action: action to take
+  # hide_header: boolean; true if header and footer should not be shown.
+  #%]
+
+[% IF !hide_header %]
+[% PROCESS global/variables.none.tmpl %]
+
+[% PROCESS global/header.html.tmpl
+    title = "Auto strack trace rejecting"
+    h1 = "" %]
+[% END %]
+
+[% USE GNOME %]
+
+<form action="edittraces.cgi" method="POST">
+<input type="hidden" name="action" value="[% action FILTER html %]">
+[% IF action == "edit" && cur_trace.old_hash %]
+<input type="hidden" name="old_hash" value="[% cur_trace.old_hash FILTER html %]">
+[% END %]
+[% IF cur_trace.exists('hash') %]<input name="hash" type="hidden" value="[% cur_trace.hash FILTER html %]">[% END %]
+<style><!--
+.foo tr { vertical-align: top }
+ --></style>
+<table border=0 cellpadding=4 cellspacing=0 class="foo">
+<tr>
+  <th align="right"><label for="dupe_of">Duplicate of?</label>:</th>
+  <td><input name="dupe_of" id="dupe_of" value="[% cur_trace.dupe_of FILTER html %]"></td>
+</tr>
+<tr>
+  <th align="right"><label for="product_only">Product</label>:</th>
+  <td><select name="product_id" id="product_id">
+    <option value="">Do not reject for a specific product</option>
+    [% FOREACH product = products.keys.sort %]
+      <option value="[% products.$product FILTER html %]" [% IF products.$product == cur_trace.product_id %] selected="selected"[% END %]>[% product FILTER html %]</option>
+    [% END %]</select>
+    [% IF cur_trace.dupe_of_bug && cur_trace.dupe_of_bug.bug_id
+          && (!cur_trace.product_id || cur_trace.dupe_of_bug.product != cur_trace.product) %]
+      <br><font color="red">Main bugs product: [% cur_trace.dupe_of_bug.product FILTER html %]</font>
+    [% END %]
+  </td>
+</tr>
+<tr>
+  <th align="right"><label for="version">Product version</label>:</th>
+  <td>
+    <input name="version" id="version" value="[% cur_trace.version FILTER html %]">
+    <br>(leave empty to reject for all versions)
+    [% IF cur_trace.dupe_of_bug && cur_trace.dupe_of_bug.bug_id
+          && (!cur_trace.version || cur_trace.dupe_of_bug.version != cur_trace.version) %]
+      <br><font color="red">Main bugs version: [% cur_trace.dupe_of_bug.version FILTER html %]</font>
+    [% END %]
+  </td>
+</tr>
+<tr>
+  <th align="right"><label for="gnome_version">GNOME version</label>:</th>
+  <td><select name="gnome_version" id="gnome_version">
+    <option value="">Do not reject using GNOME version (recommended)</option>
+    [% FOREACH opt = legal_gnome_versions %]
+      <option value="[% opt FILTER html %]" [% IF opt == cur_trace.gnome_version %] selected="selected"[% END %]>[% opt FILTER html %]</option>
+    [% END %]</select>
+    <br>WARNING: GNOME version is optional
+    [% IF cur_trace.dupe_of_bug && cur_trace.dupe_of_bug.bug_id
+          && (!cur_trace.gnome_version || cur_trace.dupe_of_bug.gnome_version != cur_trace.gnome_version) %]
+      <br><font color="red">Main bugs GNOME version: [% cur_trace.dupe_of_bug.gnome_version FILTER html %]</font>
+    [% END %]
+  </td>
+</tr>
+[% IF cur_trace.functions %]
+  <tr>
+    <th align="right"><label for="gnome_version">Detected functions</label>:</th>
+    <td>
+      [% cur_trace.functions FILTER html %]
+      [% IF cur_trace.is_dupe %]
+        <br><font color="red">ERROR: Stack trace is already rejected (perhaps for another product, etc). See <a href="edittraces.cgi?action=edit&amp;hash=[% cur_trace.hash FILTER url_quote %]" target="_new">here</a></font>
+      [% END %]
+    </td>
+  </tr>
+[% END %]
+<tr>
+  <th align="right"><label for="trace">Stack trace:</label></td>
+  <td><textarea name="trace" id="trace" cols="80" rows=15>[% cur_trace.trace FILTER html %]</textarea></td>
+</tr>
+<tr>
+  <td>&nbsp;</td>
+  <td>
+    [% IF action == "add" %]
+      [% IF cur_trace.exists('hash') %]
+        <input type="submit" value="Re-parse above stack trace">
+        [% IF ! cur_trace.is_dupe %] <input type="submit" name="do_add" value="Reject above stack trace">[% END %]
+      [% ELSE %]
+        <input type="submit" value="Parse stack trace for functions">
+      [% END %]
+    [% ELSIF action == "edit" %]
+      <input type="submit" value="Validate changes">
+      [% IF ! cur_trace.is_dupe %] <input type="submit" name="do_edit" value="Update above stack trace">[% END %]
+    [% END %]
+  </td>
+</table>
+</form>
+
+[% PROCESS global/footer.html.tmpl IF !hide_header %]
Index: template/en/default/global/messages.html.tmpl
===================================================================
RCS file: /cvs/gnome/bugzilla-newer/template/en/default/global/messages.html.tmpl,v
retrieving revision 1.6
diff -u -p -r1.6 messages.html.tmpl
--- template/en/default/global/messages.html.tmpl	27 Aug 2006 12:43:05 -0000	1.6
+++ template/en/default/global/messages.html.tmpl	5 Nov 2006 16:12:48 -0000
@@ -264,6 +264,15 @@
     user, so we have instead left the [% match_field FILTER html %]
     field blank.
     
+  [% ELSIF message_tag == "trace_created" %]
+    Stack trace has been created.
+
+  [% ELSIF message_tag == "trace_updated" %]
+    Stack trace has been updated.
+
+  [% ELSIF message_tag == "trace_deleted" %]
+    Stack trace has been deleted.
+
   [% ELSE %]
     [%# Give sensible error if error functions are used incorrectly.
       #%]        
Index: template/en/default/global/user-error.html.tmpl
===================================================================
RCS file: /cvs/gnome/bugzilla-newer/template/en/default/global/user-error.html.tmpl,v
retrieving revision 1.20
diff -u -p -r1.20 user-error.html.tmpl
--- template/en/default/global/user-error.html.tmpl	14 Oct 2006 18:20:46 -0000	1.20
+++ template/en/default/global/user-error.html.tmpl	5 Nov 2006 16:12:48 -0000
@@ -186,6 +186,8 @@
       users
     [% ELSIF object == "versions" %]
       versions
+    [% ELSIF object == "traces" %]
+      stack traces
     [% END %].
 
   [% ELSIF error == "attachment_removed" %]
