public inbox for gnats-devel@sourceware.org
 help / color / mirror / Atom feed
* patch for gnatsweb.pl
@ 2001-09-06 14:09 David, Lysander
  0 siblings, 0 replies; 14+ messages in thread
From: David, Lysander @ 2001-09-06 14:09 UTC (permalink / raw)
  To: 'gnats-devel@sources.redhat.com'

Hi,

When there is an gnats error, while submitting a pr,
the error message doesn't get returned.  Here is a patch to fix it.
I am using gnatsweb 2.8.2.

diff gnatsweb.pl gnatsweb.pl.new
1185c1185,1191
<       print_gnatsd_error($gnats::ERRSTR);
---
> 		my $page = "Error";
> 		print_header();
> 		page_start_html ( $page );
> 		page_heading ( $page, "GNATS Error" );
> 		print_gnatsd_error($gnats::ERRSTR);
> 		page_footer ( $page );
> 		page_end_html ( $page );


Thanks,
Lysander

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Patch for gnatsweb.pl
  2002-09-25 13:13       ` Lars Henriksen
  2002-09-26 15:46         ` Robert Lupton the Good
  2002-09-27  0:32         ` Robert Lupton the Good
@ 2002-09-30  2:07         ` Lars Henriksen
  2 siblings, 0 replies; 14+ messages in thread
From: Lars Henriksen @ 2002-09-30  2:07 UTC (permalink / raw)
  To: Yngve Svendsen; +Cc: Robert Lupton the Good, help-gnats

[-- Attachment #1: Type: text/plain, Size: 2118 bytes --]

On Wed, Sep 25, 2002 at 08:14:14PM +0200, Lars Henriksen wrote:
> On Wed, Sep 25, 2002 at 05:59:53PM +0200, Yngve Svendsen wrote:
> > At 17:39 25.09.2002 +0200, Lars Henriksen wrote:
> > >Do we want to (must we) keep backward combatibility?
> 
> > While working with the recent "Sort By" patches, I had occasion to look 
> > more closely at this. Compatibility with stored Gnatsweb 2 queries is a 
> > non-issue I think. There are a few sites I know of that use Gnatsweb 3.99.x 
> > in production (Dirk, this probably concerns you), but if we are ever to rid 
> > Gnatsweb of this totally unnecessary level of complexity, this is the time.
snip..
> > I think I'll use my Supreme Maintainer Authority to decree that field2param 
> > and param2field must die.
> 
> Fine. That implies that the query expression logic in submitquery() must be
> corrected since it depends on case differences.
> 
> > Relevant patches are very welcome, since I have somewhat limited time to 
> > code right now

Attached is my attempt at eliminating the field/parameter/upper-case/lower-case
conversions from gnatsweb.

Our friends field2param() and param2field() have gone: gnatsweb uses dbconfig
field names exclusively (this is somewhat ironic since gnatsd happily accepts
category for Category, etc.).

With this patch gnatsweb is NOT backwards compatible, neither with versions 2.* nor 3.*:

1) Stored and bookmarked queries may no longer work or may return different
   results (all field names are now exact dbconfig field names).
2) submitquery() uses anchored regexp searches (^ and $) for enumerated
   types. For list box selection this leads to the expected result; for
   regular expression queries (advanced queries) it still leaves the
   possibility of inserting suitable ".*". This isn't the best possible
   solution, but one requiring only a small change in the code. I prefer
   postponing a better one (divide and conquer).
3) Field related callbacks (sendpr() and edit()) must have their "reason"
   adjusted to use dbconfig field names.

The patch is against the current HEAD (revison 1.101).

Regards
Lars Henriksen

[-- Attachment #2: gnatsweb context diff --]
[-- Type: text/plain, Size: 23140 bytes --]

Index: gnatsweb.pl
===================================================================
RCS file: /cvsroot/gnatsweb/gnatsweb/gnatsweb.pl,v
retrieving revision 1.101
diff -c -p -r1.101 gnatsweb.pl
*** gnatsweb.pl	24 Sep 2002 20:39:17 -0000	1.101
--- gnatsweb.pl	29 Sep 2002 17:56:01 -0000
*************** sub sendpr
*** 1040,1046 ****
      {
        next;
      }
-     my $lc_fieldname = field2param($_);
  
      $field_number++;
  
--- 1040,1045 ----
*************** sub sendpr
*** 1051,1057 ****
  
      # The "intro" provides a way for the site callback to print something
      # at the top of a given field.
!     my $intro = cb("sendpr_intro_$lc_fieldname", $field_number) || '';
  
      print "<tr><td valign=\"top\" width=\"20%\"><b>$_:</b><br /><small>\n",
            fieldinfo($_, 'desc'),
--- 1050,1056 ----
  
      # The "intro" provides a way for the site callback to print something
      # at the top of a given field.
!     my $intro = cb("sendpr_intro_$_", $field_number) || '';
  
      print "<tr><td valign=\"top\" width=\"20%\"><b>$_:</b><br /><small>\n",
            fieldinfo($_, 'desc'),
*************** sub edit
*** 1525,1531 ****
      {
        next;
      }
-     my $lc_fieldname = field2param($_);
  
      $field_number++;
  
--- 1524,1529 ----
*************** sub edit
*** 1533,1539 ****
  
      # The "intro" provides a way for the site callback to print something
      # at the top of a given field.
!     my $intro = cb("edit_intro_$lc_fieldname", $field_number) || '';
      print "<tr><td valign=\"top\" width=\"20%\"><b>$_:</b><br /><small>\n",
            fieldinfo($_, 'desc'),
  	  "</small><td>\n", $intro, "\n";
--- 1531,1537 ----
  
      # The "intro" provides a way for the site callback to print something
      # at the top of a given field.
!     my $intro = cb("edit_intro_$_", $field_number) || '';
      print "<tr><td valign=\"top\" width=\"20%\"><b>$_:</b><br /><small>\n",
            fieldinfo($_, 'desc'),
  	  "</small><td>\n", $intro, "\n";
*************** sub query_page
*** 1840,1888 ****
                         -values=>['Originated by You'],
                         -defaults=>[]),
          "</td>\n</tr>\n",
!         "<tr>\n<td>Synopsis Search:</td>\n<td>",
!         $q->textfield(-name=>'synopsis',-size=>25),
          "</td>\n</tr>\n",
          "<tr>\n<td>Multi-line Text Search:</td>\n<td>",
          $q->textfield(-name=>'multitext',-size=>25),
          "</td>\n</tr>\n",
          "<tr valign=top>\n<td>Column Display:</td>\n<td>";
  
!   # We operate internally with parameter names, not real-world
!   # fieldnames (see dtb's comment in field2param()).  This is for
!   # backward compatibility and should be dealt with properly at some
!   # point by making Gnatsweb use the fieldnames set in dbconfig
!   # exclusively (XXX ??? !!! FIXME).  We want to use real fieldnames
!   # in the query page, so we construct a hash of (param , fieldname)
!   # pairs to use in the scrolling_list. We also construct an array of
!   # param names (@lcfields) which is fed to the scrolling_list in
!   # order to keep the "natural" order of the fields. Merely using
!   # keys() would cause fields to be listed in arbitrary order.
!   my @lcfields;
!   my %labels;
!   foreach (@fieldnames)
!   {
!     if (fieldinfo($_, 'fieldtype') ne 'multitext')
!     {
!       my $param = field2param($_);
!       $labels{$param} = $_;
!       push (@lcfields, field2param($_));
      }
    }
! 
!   my(@columns) = split(' ', $global_prefs{'columns'} || '');
!   @columns = keys(%labels) unless @columns;
! 
!   # The 'number' field is always first in the @lcfields array. If
    # users were allowed to select it in this list, the PR number would
    # appear twice in the Query Results table. We prevent this by
    # shifting 'number' out of the array.
!   my(@sh_lcfields) = @lcfields;
!   shift(@sh_lcfields);
  
    print $q->scrolling_list(-name=>'columns',
!                            -values=>\@sh_lcfields,
!                            -labels=>\%labels,
                             -defaults=>\@columns,
                             -multiple=>1,
                             -size=>5),
--- 1838,1868 ----
                         -values=>['Originated by You'],
                         -defaults=>[]),
          "</td>\n</tr>\n",
!         "<tr>\n<td>$SYNOPSIS_FIELD Search:</td>\n<td>",
!         $q->textfield(-name=>$SYNOPSIS_FIELD,-size=>25),
          "</td>\n</tr>\n",
          "<tr>\n<td>Multi-line Text Search:</td>\n<td>",
          $q->textfield(-name=>'multitext',-size=>25),
          "</td>\n</tr>\n",
          "<tr valign=top>\n<td>Column Display:</td>\n<td>";
  
!   my @allcolumns;
!   foreach (@fieldnames) {
!     if (fieldinfo($_, 'fieldtype') ne 'multitext') {
!       push (@allcolumns, $_);
      }
    }
!   # The 'number' field is always first in the @allcolumns array. If
    # users were allowed to select it in this list, the PR number would
    # appear twice in the Query Results table. We prevent this by
    # shifting 'number' out of the array.
!   shift(@allcolumns);
! 
!   my(@columns) = split(' ', $global_prefs{'columns'} || '');
!   @columns = @allcolumns unless @columns;
  
    print $q->scrolling_list(-name=>'columns',
!                            -values=>\@allcolumns,
                             -defaults=>\@columns,
                             -multiple=>1,
                             -size=>5),
*************** sub advanced_query_page
*** 1962,1980 ****
    {
      if (fieldinfo ($_, 'fieldtype') eq 'date')
      {
!       my $headerstr = $_." after";
!       my $param_name = $headerstr;
!       $param_name =~ s/ /_/;
!       $param_name =  field2param ($param_name);
!       print "<tr>\n<td>$headerstr:</td>\n<td>",
!           $q->textfield(-name=>$param_name, -size=>$width),
            "</td>\n</tr>\n";
!       $headerstr = $_." before";
!       $param_name = $headerstr;
!       $param_name =~ s/ /_/;
!       $param_name = field2param ($param_name);
!       print "<tr>\n<td>$headerstr:</td>\n<td>",
!           $q->textfield(-name=>$param_name, -size=>$width),
            "</td>\n</tr>\n";
      }
    }
--- 1942,1952 ----
    {
      if (fieldinfo ($_, 'fieldtype') eq 'date')
      {
!       print "<tr>\n<td>$_ after:</td>\n<td>",
!           $q->textfield(-name=>$_."_after", -size=>$width),
            "</td>\n</tr>\n";
!       print "<tr>\n<td>$_ before:</td>\n<td>",
!           $q->textfield(-name=>$_."_before", -size=>$width),
            "</td>\n</tr>\n";
      }
    }
*************** sub advanced_query_page
*** 1995,2002 ****
          "</tr>\n";
    foreach (@fieldnames)
    {
-     my $lc_fieldname = field2param($_);
- 
      print "<tr valign=top>\n";
  
      # 1st column is field name
--- 1967,1972 ----
*************** sub advanced_query_page
*** 2004,2010 ****
  
      # 2nd column is regexp search field
      print "<td>",
!           $q->textfield(-name=>$lc_fieldname,
                          -size=>$width);
      print "\n";
      # XXX ??? !!! FIXME
--- 1974,1980 ----
  
      # 2nd column is regexp search field
      print "<td>",
!           $q->textfield(-name=>$_,
                          -size=>$width);
      print "\n";
      # XXX ??? !!! FIXME
*************** sub advanced_query_page
*** 2026,2032 ****
        my $ary_ref = fieldinfo($_, 'values');
        my $size = scalar(@$ary_ref);
        $size = 4 if $size > 4;
!       print $q->scrolling_list(-name=>$lc_fieldname,
                                 -values=>$ary_ref,
                                 -multiple=>1,
                                 -size=>$size);
--- 1996,2002 ----
        my $ary_ref = fieldinfo($_, 'values');
        my $size = scalar(@$ary_ref);
        $size = 4 if $size > 4;
!       print $q->scrolling_list(-name=>$_,
                                 -values=>$ary_ref,
                                 -multiple=>1,
                                 -size=>$size);
*************** sub advanced_query_page
*** 2044,2084 ****
          "<caption>Display</caption>\n",
          "<tr valign=top>\n<td>Display these columns:</td>\n<td>";
  
!   # We operate internally with parameter names, not real-world
!   # fieldnames (see dtb's comment in field2param()).  This is for
!   # backward compatibility and should be dealt with properly at some
!   # point by making Gnatsweb use the fieldnames set in dbconfig
!   # exclusively (XXX ??? !!! FIXME).  We want to use real fieldnames
!   # in the query page, so we construct a hash of (param , fieldname)
!   # pairs to use in the scrolling_list. We also construct an array of
!   # param names (@lcfields) which is fed to the scrolling_list in
!   # order to keep the "natural" order of the fields. Merely using
!   # keys() would cause fields to be listed in arbitrary order.
!   my @lcfields;
!   my %labels;
!   foreach (@fieldnames)
!   {
!     if (fieldinfo($_, 'fieldtype') ne 'multitext')
!     {
!       my $param = field2param($_);
!       $labels{$param} = $_;
!       push (@lcfields, field2param($_));
      }
    }
! 
!   my(@columns) = split(' ', $global_prefs{'columns'} || '');
!   @columns = keys(%labels) unless @columns;
! 
!   # The 'number' field is always first in the @lcfields array. If
    # users were allowed to select it in this list, the PR number would
    # appear twice in the Query Results table. We prevent this by
    # shifting 'number' out of the array.
!   my(@sh_lcfields) = @lcfields;
!   shift(@sh_lcfields);
  
    print $q->scrolling_list(-name=>'columns',
!                            -values=>\@sh_lcfields,
!                            -labels=>\%labels,
                             -defaults=>\@columns,
                             -multiple=>1,
                             -size=>5),
--- 2014,2036 ----
          "<caption>Display</caption>\n",
          "<tr valign=top>\n<td>Display these columns:</td>\n<td>";
  
!   my @allcolumns;
!   foreach (@fieldnames) {
!     if (fieldinfo($_, 'fieldtype') ne 'multitext') {
!       push (@allcolumns, $_);
      }
    }
!   # The 'number' field is always first in the @allcolumns array. If
    # users were allowed to select it in this list, the PR number would
    # appear twice in the Query Results table. We prevent this by
    # shifting 'number' out of the array.
!   shift(@allcolumns);
! 
!   my(@columns) = split(' ', $global_prefs{'columns'} || '');
!   @columns = @allcolumns unless @columns;
  
    print $q->scrolling_list(-name=>'columns',
!                            -values=>\@allcolumns,
                             -defaults=>\@columns,
                             -multiple=>1,
                             -size=>5),
*************** sub submitquery
*** 2235,2242 ****
    page_heading($page, $heading);
    my $debug = 0;
  
-   my @fielddisplaylist = $q->param('columns');
- 
    my $originatedbyme = $q->param('originatedbyme');
    my $ignoreclosed   = $q->param('ignoreclosed');
  
--- 2187,2192 ----
*************** sub submitquery
*** 2263,2270 ****
      # Bleah. XXX ??? !!!
      if ($stringval ne '')
      {
!       my $ucfield = param2field ($field);
!       if (isvalidfield ($ucfield))
        {
          my $subexp = "";
          my $sval;
--- 2213,2219 ----
      # Bleah. XXX ??? !!!
      if ($stringval ne '')
      {
!       if (isvalidfield ($field))
        {
          my $subexp = "";
          my $sval;
*************** sub submitquery
*** 2276,2288 ****
            {
              # Most (?) people expect queries on enums to be of the
              # exact, not the substring type.
              if (fieldinfo($field, 'fieldtype') =~ "enum|multienum")
              {
!               $subexp = appendexpr ($subexp, '|', "$ucfield==\"$sval\"");
              }
              else
              {
!               $subexp = appendexpr ($subexp, '|', "$ucfield~\"$sval\"");
              }
            }
          }
--- 2225,2241 ----
            {
              # Most (?) people expect queries on enums to be of the
              # exact, not the substring type.
+ 	    # Hence, provide explicit anchoring for enums. This
+ 	    # still leaves the user the possibility of inserting
+ 	    # ".*" before and/or after regular expression searches
+ 	    # on the advanced query page.
              if (fieldinfo($field, 'fieldtype') =~ "enum|multienum")
              {
!               $subexp = appendexpr ($subexp, '|', "$field~\"^$sval\$\"");
              }
              else
              {
!               $subexp = appendexpr ($subexp, '|', "$field~\"$sval\"");
              }
            }
          }
*************** sub submitquery
*** 2306,2325 ****
          }
          # Whack off the trailing _after or _before.
          $field =~ s/_[^_]*$//;
-         $field = param2field ($field);
          $expr = appendexpr ($expr, '&', $field.$op.'"'.$stringval.'"');
        }
      }
    }
  
    my $format="\"%s";
-   my @ucfields = map { param2field ($_) } @fielddisplaylist;
  
    # We are using ASCII octal 037 (unit separator) to separate the
    # fields in the query output. Note that the format strings are
    # interpolated (quoted with ""'s), so make sure to escape any $ or @
    # signs.
!   foreach (@ucfields) {
  	if (fieldinfo ($_, 'fieldtype') eq 'date') {
        $format .= "\037%{%Y-%m-%d %H:%M:%S %Z}D";
  	} elsif (fieldinfo ($_, 'fieldtype') eq 'enum') {
--- 2259,2277 ----
          }
          # Whack off the trailing _after or _before.
          $field =~ s/_[^_]*$//;
          $expr = appendexpr ($expr, '&', $field.$op.'"'.$stringval.'"');
        }
      }
    }
  
    my $format="\"%s";
  
+   my @columns = $q->param('columns');
    # We are using ASCII octal 037 (unit separator) to separate the
    # fields in the query output. Note that the format strings are
    # interpolated (quoted with ""'s), so make sure to escape any $ or @
    # signs.
!   foreach (@columns) {
  	if (fieldinfo ($_, 'fieldtype') eq 'date') {
        $format .= "\037%{%Y-%m-%d %H:%M:%S %Z}D";
  	} elsif (fieldinfo ($_, 'fieldtype') eq 'enum') {
*************** sub submitquery
*** 2329,2335 ****
      }
    }
  
!   $format .= "\" ".${NUMBER_FIELD}." ".join (" ", @ucfields);
  
    client_cmd("expr $expr") if $expr;
    client_cmd("qfmt $format");
--- 2281,2287 ----
      }
    }
  
!   $format .= "\" ".${NUMBER_FIELD}." ".join (" ", @columns);
  
    client_cmd("expr $expr") if $expr;
    client_cmd("qfmt $format");
*************** sub nonempty
*** 2353,2423 ****
  }
  
  
- # dtb - are field2param & param2field really only here for backwards
- # compatibility?  if so, maybe we should get rid of them.
- # unfortunately, all the saved and bookmarked queries, and people's
- # column prefs (in their cookies) out there in the world would
- # break.  sigh, stuck with bad backwards compatibility...
- # field2param -
- #     Convert gnats field name into parameter name, e.g.
- #     "Submitter-Id" => "submitter_id".  It's done this crazy way for
- #     compatibility with queries stored by gnatsweb 2.1.
- #
- # used in sendpr(), edit(), query_page(), advanced_query_page()
- sub field2param
- {
-   my $name = shift;
-   $name =~ s/-/_/g;
-   $name = lc($name);
-   return $name;
- }
- 
- # param2field -
- #     Find gnats field name corresponding to parameter name, e.g.
- #     "submitter_id" => "Submitter-Id".
- #     If not gnats field corresponds, reverse the action of
- #     field2param().  Note that
- #       param2field(field2param($val)) != $val
- #     if $val =~ /_/ or $val =~ /[A-Z]{2,}/
- #
- sub param2field
- {
-     my $munged_field;
-     my $name = shift;
-     $name =~ s/_/-/g;
-     foreach my $field (@fieldnames) {
-       if ($name eq 'PR') {
-         return 'Number';
-       }
-       else {
-         ($munged_field = $field) =~ s/_/-/g;
-         if (lc($name) eq lc($munged_field)) {
-           return $field;
-         }
-       }
-     }
- 
-     # if we get here, $name is not a gnats field, so just
-     # programmatically un-munge it
-     my @words = split(/_/, $name);
-     map { $_ = ucfirst($_); } @words;
-     $name = join('-', @words);
-     return $name;
- }
- 
- 
  # display_query_results -
  #     Display the query results, and the "store query" form.
  #     The results only have the set of fields that we requested, although
  #     the first field is always the PR number.
  sub display_query_results
  {
-   my ($nooffields);
    my(@query_results) = @_;
-   my(@fields) = $q->param('columns');
    my $displaydate = $q->param('displaydate');
    my $reversesort = $q->param('reversesort');
-   my($field, %fields);
  
    my $num_matches = scalar(@query_results);
    my $heading = sprintf("%s %s found",
--- 2305,2319 ----
*************** sub display_query_results
*** 2433,2477 ****
          $q->hidden(name=>'cmd', -value=>'view', -override=>1),
          "<table border=1 cellspacing=0 cellpadding=1><tr>\n";
  
!   # Note that $sortby is the normal uppercased name of the field, and not
!   # a "parameterized" version.
!   my($sortby) = $q->param('sortby') || 'PR';
  
    my $whichfield = 0;
    my ($sortbyfieldnum) = 0;
    # Print table header which allows sorting by columns.
    # While printing the headers, temporarily override the 'sortby' param
    # so that self_url() works right.
! 
!   my @ufields;
! 
!   for $field ('PR', @fields)
    {
!     my $ufield = param2field ($field);
!     if ($field ne 'PR')
!     {
!       push (@ufields, $ufield);
      }
!     $q->param(-name=>'sortby', -value=>$ufield);
  
      # strip empty params out of self_url().  in a gnats db with many
      # fields, the url query-string will become very long.  this is a
      # problem, since IE5 truncates query-strings at ~2048 characters.
      my ($query_string) = $q->self_url() =~ m/^[^?]*\?(.*)$/;
!     $query_string =~ s/\w+=;//g;
!     my $href = $script_name . '?' . $query_string;
  
!     $fields{$field}++;
!     if ($ufield eq $sortby)
!     {
!       $sortbyfieldnum = $whichfield;
!     }
!     $whichfield++;
!     if ($ufield eq 'PR') {
!       $ufield='Number';
!     }
!     print "\n<th><a href=\"$href\">$ufield</a></th>\n";
!     $nooffields = @ufields;
    }
    # finished the header row
    print "</tr>\n";
--- 2329,2360 ----
          $q->hidden(name=>'cmd', -value=>'view', -override=>1),
          "<table border=1 cellspacing=0 cellpadding=1><tr>\n";
  
!   # By default sort by PR number.
!   my($sortby) = $q->param('sortby') || $fieldnames[0];
  
    my $whichfield = 0;
    my ($sortbyfieldnum) = 0;
+   my @columns = $q->param('columns');
+   my $noofcolumns = @columns;
    # Print table header which allows sorting by columns.
    # While printing the headers, temporarily override the 'sortby' param
    # so that self_url() works right.
!   for ($fieldnames[0], @columns)
    {
!     $q->param(-name=>'sortby', -value=>$_);
!     if ($_ eq $sortby) {
!       $sortbyfieldnum = $whichfield;
      }
!     $whichfield++;
  
      # strip empty params out of self_url().  in a gnats db with many
      # fields, the url query-string will become very long.  this is a
      # problem, since IE5 truncates query-strings at ~2048 characters.
      my ($query_string) = $q->self_url() =~ m/^[^?]*\?(.*)$/;
!     $query_string =~ s/(\w|-)+=;//g;
  
!     my $href = $script_name . '?' . $query_string;
!     print "\n<th><a href=\"$href\">$_</a></th>\n";
    }
    # finished the header row
    print "</tr>\n";
*************** sub display_query_results
*** 2485,2492 ****
    my(@presplit_prs) = map { [ (split /\037/) ] } @query_results;
    my(@sorted_prs);
    my $sortby_fieldtype = fieldinfo ($sortby, 'fieldtype') || '';
!   if ($sortby_fieldtype eq 'enum' || $sortby_fieldtype eq 'integer'
!       || $sortby eq 'PR') {
      # sort numerically
      @sorted_prs = sort({$a->[$sortbyfieldnum] <=> $b->[$sortbyfieldnum]}
  		       @presplit_prs);
--- 2368,2374 ----
    my(@presplit_prs) = map { [ (split /\037/) ] } @query_results;
    my(@sorted_prs);
    my $sortby_fieldtype = fieldinfo ($sortby, 'fieldtype') || '';
!   if ($sortby_fieldtype eq 'enum' || $sortby_fieldtype eq 'integer') {
      # sort numerically
      @sorted_prs = sort({$a->[$sortbyfieldnum] <=> $b->[$sortbyfieldnum]}
  		       @presplit_prs);
*************** sub display_query_results
*** 2499,2505 ****
    @sorted_prs = reverse @sorted_prs if $reversesort;
  
    # Print the PR's.
!   my @fieldtypes = map { fieldinfo ($_, 'fieldtype') } @ufields;
    foreach (@sorted_prs)
    {
      print "<tr valign=top>\n";
--- 2381,2387 ----
    @sorted_prs = reverse @sorted_prs if $reversesort;
  
    # Print the PR's.
!   my @fieldtypes = map { fieldinfo ($_, 'fieldtype') } @columns;
    foreach (@sorted_prs)
    {
      print "<tr valign=top>\n";
*************** sub display_query_results
*** 2520,2532 ****
        # map them back into strings.
        if ($fieldtypes[$whichfield] eq 'enum')
        {
!         my $enumvals = fieldinfo($ufields[$whichfield], 'values');
          $fieldcontents = $$enumvals[$fieldcontents - 1] || 'invalid';
        }
        $fieldcontents = $q->escapeHTML($fieldcontents);
        $fieldcontents = nonempty($fieldcontents);
  
!       if ($ufields[$whichfield] =~ /responsible/i) {
  	  $fieldcontents = make_mailto($fieldcontents);
        } else {
  	  # make urls and email addresses into live hrefs
--- 2402,2414 ----
        # map them back into strings.
        if ($fieldtypes[$whichfield] eq 'enum')
        {
!         my $enumvals = fieldinfo($columns[$whichfield], 'values');
          $fieldcontents = $$enumvals[$fieldcontents - 1] || 'invalid';
        }
        $fieldcontents = $q->escapeHTML($fieldcontents);
        $fieldcontents = nonempty($fieldcontents);
  
!       if ($columns[$whichfield] =~ /responsible/i) {
  	  $fieldcontents = make_mailto($fieldcontents);
        } else {
  	  # make urls and email addresses into live hrefs
*************** sub display_query_results
*** 2538,2544 ****
      }
      # Pad the remaining, empty columns with &nbsp;'s
      my $n = @{$_};
!     while ($nooffields - $n > 0)
      {
        print "<td>&nbsp;</td>";
        $n++;
--- 2420,2426 ----
      }
      # Pad the remaining, empty columns with &nbsp;'s
      my $n = @{$_};
!     while ($noofcolumns - $n > 0)
      {
        print "<td>&nbsp;</td>";
        $n++;
*************** sub display_query_results
*** 2553,2559 ****
    # strip empty params out of $url.  in a gnats db with many
    # fields, the url query-string will become very long.  this is a
    # problem, since IE5 truncates query-strings at ~2048 characters.
!   $url =~ s/\w+=;//g;
    print $q->p(qq{<a href="$url">View for bookmarking</a>\n});
  
    # Allow the user to store this query.  Need to repeat params as hidden
--- 2435,2441 ----
    # strip empty params out of $url.  in a gnats db with many
    # fields, the url query-string will become very long.  this is a
    # problem, since IE5 truncates query-strings at ~2048 characters.
!   $url =~ s/(\w|-)+=;//g;
    print $q->p(qq{<a href="$url">View for bookmarking</a>\n});
  
    # Allow the user to store this query.  Need to repeat params as hidden

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Patch for gnatsweb.pl
  2002-09-25 13:13       ` Lars Henriksen
  2002-09-26 15:46         ` Robert Lupton the Good
@ 2002-09-27  0:32         ` Robert Lupton the Good
  2002-09-30  2:07         ` Lars Henriksen
  2 siblings, 0 replies; 14+ messages in thread
From: Robert Lupton the Good @ 2002-09-27  0:32 UTC (permalink / raw)
  To: help-gnats


I don't think that I ever posted my custom sort routine.  Thinking
about it, this might go better in gnatsweb.pl itself, as the custom
sort itself uses cb('sort_keys') for customization.


				R


    elsif ($reason eq 'sort_keys')
    {
	return qw(Severity Priority Class State Category Scheduled);
    }
    elsif ($reason eq 'sort_query')
    {
       my($sortby) = shift @args;
       if(defined($sortby) && $sortby eq "custom") {
	   if($args[0] ne 'checking_if_custom_sort_exists') {
	       my(@fields) = $q->param('columns');
	       #
	       # Sort by these fields in this order; PR is always added
	       # as a final key.  We'll start by figuring out which
	       # field is which, and whether they are numeric or string valued
	       #
	       my(@sort_keys) = cb('sort_keys');

	       my($field, $i, @keys);
	       my($whichfield) = 1; # field counter (0 is PR)
	       for $field (@fields) {
		   $field = param2field($field);

		   $i = 0;
		   foreach (@sort_keys) {
		       if($_ eq $field) {
			   my $fieldtype = 
			       fieldinfo($field, 'fieldtype') || '';

			   $keys[$i] = {};
			   $keys[$i]->{field} = $field;
			   $keys[$i]->{i} = $whichfield;

			   if ($fieldtype eq 'enum' || 
			       $fieldtype eq 'integer') {
			       $keys[$i]->{cmp} = "<=>"
			   } else {
			       $keys[$i]->{cmp} = "cmp";
			   }
		       }
		       $i++;
		   }
		   
		   $whichfield++;		   
	       }
	       #
	       # OK, @keys is now an array telling us how to sort.
	       # Generate the sort BLOCK
	       #
	       my($sort_block) = "";
	       for (@keys) {
		   if(defined($_->{field})) {
		       $sort_block .= 
			   "   \$a->[$_->{i}] $_->{cmp} \$b->[$_->{i}] or \# $_->{field}\n";
		   }
	       }
	       $sort_block .= "   \$a->[0] <=> \$b->[0];   \# PR\n";
	       
	       my($debug) = 0;
	       if($debug) {
		   print_header();
		   print "<BR>sort_block: <PRE>$sort_block</PRE>\n";
	       }

	       eval "\@args = sort({ $sort_block } \@args)";
	       if($@) {
		   print $@;
	       }
	   }
	   
	   return @args;
       } else {
	   return undef;
       }
    }


_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Patch for gnatsweb.pl
  2002-09-25 13:13       ` Lars Henriksen
@ 2002-09-26 15:46         ` Robert Lupton the Good
  2002-09-27  0:32         ` Robert Lupton the Good
  2002-09-30  2:07         ` Lars Henriksen
  2 siblings, 0 replies; 14+ messages in thread
From: Robert Lupton the Good @ 2002-09-26 15:46 UTC (permalink / raw)
  To: help-gnats


Here's a patch to help debug things (my patch.7).

It allows the user to define a callback to print debugging
information, specifically to add a "Debug" button to the gnats
menubar.  It's up to gnatsweb-site.pl what to do with this,
but I use it to print the state of the server with a callback like:

    elsif ($reason eq 'cmd')
    {
        # Handle site-specific values for 'cmd' param.
        my $cmd = shift(@args);
        if ($cmd eq 'debug') {
	    if(!@args) {
		print_header();
		initialize();

		print "global_prefs:\n<DL>";
		foreach (sort keys %global_prefs) {
		    print "<DT>$_\n<DD>\"$global_prefs{$_}\"\n";
		}
		print "</DL>\n";

		print "db_prefs:\n<DL>";
		foreach (sort keys %db_prefs) {
		    print "<DT>$_\n<DD>\"$db_prefs{$_}\"\n";
		}
		print "</DL>\n";

		print "<PRE>";
		debug_print_all_cookies(\*STDOUT);
		print "</PRE>";
	    }
	    return 1;
...
	

I also changed debug_print_all_cookies() to optinally take a file
handle (the default's still STDERR so it goes to the httpd log).


					R



*** /u/gnats/src/Patches/gnatsweb.pl	Mon Sep 16 09:28:38 2002
--- /u/dss/cgi-bin/gnatsweb-v4.pl	Wed Sep 18 15:44:57 2002
***************
*** 3285,3290 ****
--- 3285,3292 ----
    $row2 .= qq(<td><a href="$url&cmd=logout" style="$buttonstyle">LOG OUT</a></td>)
          unless ($site_gnatsweb_server_auth);
    $row2 .= qq(<td><a href="$url&cmd=help" style="$buttonstyle">HELP</a></td>);
+   $row2 .= qq(<td><a href="$url&cmd=debug" style="$buttonstyle">DEBUG</a></td>)
+ 	if(cb('cmd', 'debug', 'inquire'));
    $row2 .= qq(</tr>\n);
    $row2 .= qq(</table>\n</td>\n</tr>);
  
***************
*** 4122,4140 ****
  
  sub debug_print_all_cookies
  {
    # Debug: print all our cookies into server log.
!   warn "================= all cookies ===================================\n";
    my @c;
    my $i = 0;
    foreach my $y ($q->cookie())
    {
      @c = $q->cookie($y);
!     warn "got cookie: length=", scalar(@c), ": $y =>@c<=\n";
      $i += length($y);
    }
  #  @c = $q->raw_cookie();
! #  warn "debug 0.5: @c:\n";
! #  warn "debug 0.5: total size of raw cookies: ", length("@c"), "\n";
  }
  
  # set_pref -
--- 4124,4149 ----
  
  sub debug_print_all_cookies
  {
+   my($fd) = @_;
+ 
+   if (!defined($fd))
+   {
+     $fd = \*STDERR;
+   }
+ 
    # Debug: print all our cookies into server log.
!   print $fd "================= all cookies ===================================\n";
    my @c;
    my $i = 0;
    foreach my $y ($q->cookie())
    {
      @c = $q->cookie($y);
!     print $fd "got cookie: length=", scalar(@c), ": $y =>@c<=\n";
      $i += length($y);
    }
  #  @c = $q->raw_cookie();
! #  print $fd "debug 0.5: @c:\n";
! #  print $fd "debug 0.5: total size of raw cookies: ", length("@c"), "\n";
  }
  
  # set_pref -


_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Patch for gnatsweb.pl
  2002-09-25 11:43     ` Yngve Svendsen
@ 2002-09-25 13:13       ` Lars Henriksen
  2002-09-26 15:46         ` Robert Lupton the Good
                           ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Lars Henriksen @ 2002-09-25 13:13 UTC (permalink / raw)
  To: Yngve Svendsen; +Cc: Robert Lupton the Good, help-gnats

On Wed, Sep 25, 2002 at 05:59:53PM +0200, Yngve Svendsen wrote:
> At 17:39 25.09.2002 +0200, Lars Henriksen wrote:
> >Do we want to (must we) keep backward combatibility? With gnatsweb 3.*?
> >With earlier gnatsweb 4 versions? As far as I can see from some bookmarks
> >produced by 3.113, compatibility with that version is already broken
> >(I have seen some "arrivedbefore=" or "modifiedafter=" query parameters
> >that are not recognised by gnatsweb 4).

Oops, got my version numbers mixed up here. Of course I meant gnatsweb 2.*
(not 3.*) and 2.9.* (not 3.113).

> While working with the recent "Sort By" patches, I had occasion to look 
> more closely at this. Compatibility with stored Gnatsweb 2 queries is a 
> non-issue I think. There are a few sites I know of that use Gnatsweb 3.99.x 
> in production (Dirk, this probably concerns you), but if we are ever to rid 
> Gnatsweb of this totally unnecessary level of complexity, this is the time.

Agreed. We use gnatsweb 3.99.3 (+patches) here, but until now it has
supported gnatsweb 2 queries--which I didn't realise until they stopped
working. I thought for a while that it would be possible to get rid of
field2param() entirely, isolate paramfield() to two or three places (where
query parameters are read) and keep backward compatibility. But I don't
any longer. The convoluted logic of submitquery() lives by the fact that
query_page() sets upper case query parameters while advanced_query_page()
sets lower case ones.

> I think I'll use my Supreme Maintainer Authority to decree that field2param 
> and param2field must die.

Fine. That implies that the query expression logic in submitquery() must be
corrected since it depends on case differences.

> Relevant patches are very welcome, since I have somewhat limited time to 
> code right now

I'll try my hand at some.

Lars Henriksen


_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Patch for gnatsweb.pl
  2002-09-25 11:18   ` Lars Henriksen
@ 2002-09-25 11:43     ` Yngve Svendsen
  2002-09-25 13:13       ` Lars Henriksen
  0 siblings, 1 reply; 14+ messages in thread
From: Yngve Svendsen @ 2002-09-25 11:43 UTC (permalink / raw)
  To: Lars Henriksen, Robert Lupton the Good; +Cc: help-gnats

At 17:39 25.09.2002 +0200, Lars Henriksen wrote:
>I've realised that there is even more to it than I thought at first.
>
>Robert Lupton's patch as well as mine breaks backward compatibility:
>bookmarked and stored queries may stop working or behave differently.
>
>According to comments in the gnatsweb code, that is also what has kept
>the parameter/field/lower/upper case confusion from being dealt with and
>field2param() and param2field() from disappearing. I have spent some
>time on figuring out the use of (dbconfig) field names versus form
>parameter (lower case) versions. It is not too difficult to eliminate
>the parameter/field conversion entirely and use dbconfig names (I have
>a patch) but again, not without breaking some existing bookmarked and
>stored queries.
>
>Do we want to (must we) keep backward combatibility? With gnatsweb 3.*?
>With earlier gnatsweb 4 versions? As far as I can see from some bookmarks
>produced by 3.113, compatibility with that version is already broken
>(I have seen some "arrivedbefore=" or "modifiedafter=" query parameters
>that are not recognised by gnatsweb 4).

While working with the recent "Sort By" patches, I had occasion to look 
more closely at this. Compatibility with stored Gnatsweb 2 queries is a 
non-issue I think. There are a few sites I know of that use Gnatsweb 3.99.x 
in production (Dirk, this probably concerns you), but if we are ever to rid 
Gnatsweb of this totally unnecessary level of complexity, this is the time.

I think I'll use my Supreme Maintainer Authority to decree that field2param 
and param2field must die. A first step has been to use the dbconfig field 
names in the Query Page fields instead of built-in/lowercase names.

Relevant patches are very welcome, since I have somewhat limited time to 
code right now (With Milan out of the picture I'd also like to keep half an 
eye on GNATS itself and apply those simple uncontroversial patches that are 
submitted from time to time)

- Yngve



_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Patch for gnatsweb.pl
  2002-09-23 12:22 ` Lars Henriksen
@ 2002-09-25 11:18   ` Lars Henriksen
  2002-09-25 11:43     ` Yngve Svendsen
  0 siblings, 1 reply; 14+ messages in thread
From: Lars Henriksen @ 2002-09-25 11:18 UTC (permalink / raw)
  To: Robert Lupton the Good; +Cc: help-gnats, Yngve Svendsen

Hello,

Since no one else will, I'll comment myself ;-)

On Sun, Sep 22, 2002 at 08:47:33PM +0200, Lars Henriksen wrote:
> On Mon, Sep 16, 2002 at 09:41:21AM -0400, Robert Lupton the Good wrote:
> 
> > (This is my `patch.3b')
> [snip]
> > 	1/ requires exact matches for field names selected using
> > scrolling lists.  For example, we have a "Scheduled" field that
> > has entries "approved" and "notapproved"; without this patch
> > selecting "approved" gets "notapproved" too.  The reason is that
> > gnatsweb uses a ~ match in its query, and this seems reasonable.
> > 
> > This patch adds explicit "^" and "$" to the fields, and then
> > adds code so that the user doesn't see them (Note: this doesn't
> > work very elegantly with my "load stored query" patch that
> > I sent to the list a few days ago.  This problem is fixed in
> > a later patch that I'll send today).
> 
> This is a clever trick, but I believe there is more to it.

I've realised that there is even more to it than I thought at first.

Robert Lupton's patch as well as mine breaks backward compatibility:
bookmarked and stored queries may stop working or behave differently.

According to comments in the gnatsweb code, that is also what has kept
the parameter/field/lower/upper case confusion from being dealt with and
field2param() and param2field() from disappearing. I have spent some
time on figuring out the use of (dbconfig) field names versus form
parameter (lower case) versions. It is not too difficult to eliminate
the parameter/field conversion entirely and use dbconfig names (I have
a patch) but again, not without breaking some existing bookmarked and
stored queries.

Do we want to (must we) keep backward combatibility? With gnatsweb 3.*?
With earlier gnatsweb 4 versions? As far as I can see from some bookmarks
produced by 3.113, compatibility with that version is already broken
(I have seen some "arrivedbefore=" or "modifiedafter=" query parameters
that are not recognised by gnatsweb 4).

Are we stuck with the broken logic in the following piece of code which
means that list selection on the advanced query page is interpreted
as a regular expression match whereas list selection on the query page
is interpreted as a string match (e.g. selecting state = critical will also
return non-critical from the advanced query page, but not from the query
page)?

> This affects the following piece of code in submitquery():
> 
>             # Most (?) people expect queries on enums to be of the
>             # exact, not the substring type.
>             if (fieldinfo($field, 'fieldtype') =~ "enum|multienum")
>             {
>               $subexp = appendexpr ($subexp, '|', "$ucfield==\"$sval\"");
>             }
>             else
>             {
>               $subexp = appendexpr ($subexp, '|', "$ucfield~\"$sval\"");
>             }
> 
> ...
> The upshot is that the if-clause is taken from query_page() (except for
> Synopsis), the else-clause from advanced_query_page() whether the field
> type is enumerated or not. If that was the intention, the comments and the
> if-expression are misleading to put it mildly!

What do you think?

Lars Henriksen


_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Patch for gnatsweb.pl
  2002-09-16  6:48 Robert Lupton the Good
  2002-09-17  9:47 ` Yngve Svendsen
@ 2002-09-23 12:22 ` Lars Henriksen
  2002-09-25 11:18   ` Lars Henriksen
  1 sibling, 1 reply; 14+ messages in thread
From: Lars Henriksen @ 2002-09-23 12:22 UTC (permalink / raw)
  To: Robert Lupton the Good; +Cc: help-gnats, Yngve Svendsen

On Mon, Sep 16, 2002 at 09:41:21AM -0400, Robert Lupton the Good wrote:

> (This is my `patch.3b')
[snip]
> 	1/ requires exact matches for field names selected using
> scrolling lists.  For example, we have a "Scheduled" field that
> has entries "approved" and "notapproved"; without this patch
> selecting "approved" gets "notapproved" too.  The reason is that
> gnatsweb uses a ~ match in its query, and this seems reasonable.
> 
> This patch adds explicit "^" and "$" to the fields, and then
> adds code so that the user doesn't see them (Note: this doesn't
> work very elegantly with my "load stored query" patch that
> I sent to the list a few days ago.  This problem is fixed in
> a later patch that I'll send today).

This is a clever trick, but I believe there is more to it.

The query_page() and advanced_query_page() subroutines both use field names
as names of form parameters whose values are then taken by submitquery() to
construct a query expression. But query_page() uses dbconfig field names
(except for Synopsis) while advanced_query_page() uses lower case versions!
By lower case versions I mean those returned by field2param().

This affects the following piece of code in submitquery():

            # Most (?) people expect queries on enums to be of the
            # exact, not the substring type.
            if (fieldinfo($field, 'fieldtype') =~ "enum|multienum")
            {
              $subexp = appendexpr ($subexp, '|', "$ucfield==\"$sval\"");
            }
            else
            {
              $subexp = appendexpr ($subexp, '|', "$ucfield~\"$sval\"");
            }

Here $field is a form parameter, hence a dbconfig name if set by
query_page() and a lower case version if set by advanced_query_page();
$ucfield is the upper case version of $field. Now, when called with a lower
case field name, fieldinfo() will never return enum or multienum (because
there is no such field).

The upshot is that the if-clause is taken from query_page() (except for
Synopsis), the else-clause from advanced_query_page() whether the field
type is enumerated or not. If that was the intention, the comments and the
if-expression are misleading to put it mildly!

There are further complications. The advanced_query_page() sets two form
parameters with the same name for each field of enumerated type: one for
regular expression match and one for list selection. Hence we cannot use the
field type to distinguish between the two. The problem is sidestepped in the
patch from Robert Lupton the Good by having the form parameter values include
regular expression anchors in the list case.

In stead I believe the correction should coordinate the two query pages and
submitquery() in a better way:

1) Use dbconfig field names consistently for query form parameters, and
2) avoid upper/lower case conversion.
3) Use a recognizable form parameter name for enumerated type regexp
   matches (like the *_after and *_before date parameters).
4) Rewrite the query expression construction in submitquery().

This is also a move towards getting rid of the upper/lower case field name
mess. Patch follows.

Regards
Lars Henriksen

Index: gnatsweb.pl
===================================================================
RCS file: /cvsroot/gnatsweb/gnatsweb/gnatsweb.pl,v
retrieving revision 1.99
diff -u -r1.99 gnatsweb.pl
--- gnatsweb.pl	17 Sep 2002 16:26:56 -0000	1.99
+++ gnatsweb.pl	22 Sep 2002 18:43:12 -0000
@@ -1840,8 +1840,8 @@
                        -values=>['Originated by You'],
                        -defaults=>[]),
         "</td>\n</tr>\n",
-        "<tr>\n<td>Synopsis Search:</td>\n<td>",
-        $q->textfield(-name=>'synopsis',-size=>25),
+        "<tr>\n<td>$SYNOPSIS_FIELD Search:</td>\n<td>",
+        $q->textfield(-name=>$SYNOPSIS_FIELD,-size=>25),
         "</td>\n</tr>\n",
         "<tr>\n<td>Multi-line Text Search:</td>\n<td>",
         $q->textfield(-name=>'multitext',-size=>25),
@@ -1961,14 +1961,12 @@
       my $headerstr = $_." after";
       my $param_name = $headerstr;
       $param_name =~ s/ /_/;
-      $param_name =  field2param ($param_name);
       print "<tr>\n<td>$headerstr:</td>\n<td>",
           $q->textfield(-name=>$param_name, -size=>$width),
           "</td>\n</tr>\n";
       $headerstr = $_." before";
       $param_name = $headerstr;
       $param_name =~ s/ /_/;
-      $param_name = field2param ($param_name);
       print "<tr>\n<td>$headerstr:</td>\n<td>",
           $q->textfield(-name=>$param_name, -size=>$width),
           "</td>\n</tr>\n";
@@ -1991,16 +1989,20 @@
         "</tr>\n";
   foreach (@fieldnames)
   {
-    my $lc_fieldname = field2param($_);
-
     print "<tr valign=top>\n";
 
     # 1st column is field name
     print "<td>$_:</td>\n";
 
     # 2nd column is regexp search field
+    my $param_name = $_;
+    # Usually we want an exact match for enumerated types,
+    # so recognize the regexp query explicitly.
+    if (fieldinfo($_, 'fieldtype') =~ /enum/) {
+      $param_name = $_ . "_enum";
+    }
     print "<td>",
-          $q->textfield(-name=>$lc_fieldname,
+          $q->textfield(-name=>$param_name,
                         -size=>$width);
     print "\n";
     # XXX ??? !!! FIXME
@@ -2017,12 +2019,12 @@
 
     # 3rd column is blank or scrolling multi-select list
     print "<td>";
-    if (fieldinfo($_, 'fieldtype') =~ 'enum')
+    if (fieldinfo($_, 'fieldtype') =~ /enum/)
     {
       my $ary_ref = fieldinfo($_, 'values');
       my $size = scalar(@$ary_ref);
       $size = 4 if $size > 4;
-      print $q->scrolling_list(-name=>$lc_fieldname,
+      print $q->scrolling_list(-name=>$_,
                                -values=>$ary_ref,
                                -multiple=>1,
                                -size=>$size);
@@ -2245,63 +2247,53 @@
     $expr = appendexpr ('(! builtinfield:State[type]="closed")', '&', $expr);
   }
 
-  ### Construct expression for each param which specifies a query.
-  my $field;
-  foreach $field ($q->param())
-  {
-    my @val = $q->param($field);
+  ### Construct expression for each param which specifies a query, i.e.
+  # the param name is a (dbconfig) field name, possibly followed by
+  # "_after", "_before" or "_enum", see advanced_query_page().
+  my $name;
+  foreach $name ($q->param()) {
+    my @val = $q->param($name);
     my $stringval = join(" ", @val);
 
-    # Bleah. XXX ??? !!!
-    if ($stringval ne '')
-    {
-      my $ucfield = param2field ($field);
-      if (isvalidfield ($ucfield))
-      {
-        my $subexp = "";
-        my $sval;
-
-        # Turn multiple param values into ORs.
-        foreach $sval (@val)
-        {
-          if ($sval ne 'any' && $sval ne '')
-          {
-            # Most (?) people expect queries on enums to be of the
-            # exact, not the substring type.
-            if (fieldinfo($field, 'fieldtype') =~ "enum|multienum")
-            {
-              $subexp = appendexpr ($subexp, '|', "$ucfield==\"$sval\"");
-            }
-            else
-            {
-              $subexp = appendexpr ($subexp, '|', "$ucfield~\"$sval\"");
-            }
-          }
-        }
-        $expr = appendexpr ($expr, '&', $subexp);
-      }
-      elsif ($field eq 'text' || $field eq 'multitext')
-      {
-        $expr = appendexpr ($expr, '&', "fieldtype:$field~\"$stringval\"");
-      }
-      elsif ($field =~ /_after$/ || $field =~ /_before$/)
-      {
-        my $op;
-        # Waaah, nasty. XXX ??? !!!
-        if ($field =~ /_after$/)
-        {
-          $op = '>';
-        }
-        else
-        {
-          $op = '<';
+    if ($stringval eq '') { next };
+
+    # First the params we recognize as query params ...
+    # ... text ...
+    if ($name eq 'text' || $name eq 'multitext') {
+      $expr = appendexpr ($expr, '&', 'fieldtype:'.$name.'~"'.$stringval.'"');
+      next;
+    }
+    # ... dates ...
+    if ($name =~ /_after$/ || $name =~ /_before$/) {
+      my $op = ($name =~ /_after$/) ? '>' : '<';
+      # Remove the trailer.
+      $name =~ s/_[^_]*$//;
+      $expr = appendexpr ($expr, '&', $name.$op.'"'.$stringval.'"');
+      next;
+    }
+    # ... regexp query for enumerated types ...
+    if ($name =~ /_enum$/) {
+      $name =~ s/_[^_]*$//;
+      $expr = appendexpr ($expr, '&', $name.'~"'.$stringval.'"');
+      next;
+    }
+    # ... then those that are NOT query params ...
+    if (! isvalidfield($name)) { next };
+    # ... and finally query params with field names.
+    # For enumerated type queries we want an exact string match ...
+    if (fieldinfo($name, 'fieldtype') =~ /enum/) {
+      my $subexp = "";
+      # Turn multiple param values into ORs.
+      foreach (@val) {
+        if ($_ ne 'any' && $_ ne '') {
+            $subexp = appendexpr ($subexp, '|', $name.'=="'.$_.'"');
         }
-        # Whack off the trailing _after or _before.
-        $field =~ s/_[^_]*$//;
-        $field = param2field ($field);
-        $expr = appendexpr ($expr, '&', $field.$op.'"'.$stringval.'"');
       }
+      $expr = appendexpr ($expr, '&', $subexp);
+      next;
     }
+    # ... and for the rest a regexp match.
+    $expr = appendexpr ($expr, '&', $name.'~"'.$stringval.'"');
   }
 
   my $format="\"%s";


_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: Patch for gnatsweb.pl
  2002-09-16  6:48 Robert Lupton the Good
@ 2002-09-17  9:47 ` Yngve Svendsen
  2002-09-23 12:22 ` Lars Henriksen
  1 sibling, 0 replies; 14+ messages in thread
From: Yngve Svendsen @ 2002-09-17  9:47 UTC (permalink / raw)
  To: Robert Lupton the Good, help-gnats

At 09:41 16.09.2002 -0400, Robert Lupton the Good wrote:
>         2/ Adds a field to the advanced query so that the
>user can choose which field to sort on.  This includes support
>for my "custom query" patch of a few days ago (but will work
>even without it)

Thanks,

I applied a variation of this both to the Query and Advanced Query pages. 
I'll be going through the other patches fairly soon -- some will make it 
into 4.0, some may be queued for 4.1.

- Yngve



_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* patch for gnatsweb.pl
       [not found] <20020915103254.22538.88942.Mailman@monty-python.gnu.org>
  2002-09-16  6:56 ` Robert Lupton the Good
  2002-09-16  7:24 ` patch " Robert Lupton the Good
@ 2002-09-16  7:45 ` Robert Lupton the Good
  2 siblings, 0 replies; 14+ messages in thread
From: Robert Lupton the Good @ 2002-09-16  7:45 UTC (permalink / raw)
  To: help-gnats


(This is my "patch.6", and brings me up-to-date, except that I
haven't posted my custom sort calback from gnatsweb-site.pl)

I should mention that all 7 of these patches are designed to be
applied in series; I'd be happy to regenerate them relative to some
baseline if requested.

This patch:
	1/ Check that $fields{$SUBMITTER_ID_FIELD} is defined;
	my site doesn't use it and gnats (otherwise) works fine.

	2/ Fixes the code for "load stored query" to set options
	in scrolling lists as appropriate rather then simply
	inserting the corresponding regexp.  This is especially
	important when using my exact-matches-for-scrolling-selections
	patch.

	3/ Make "load stored query" handle "Ignore Closed" correctly.

	4/ Fix the code that trims stored query cookies.  There
	were two problems:  "field=&" wasn't removed (just "field=;"),
	and the (long) return_url was included.  This URL doesn't
	seem to be needed (if it is, we need to add a regexp to
	strip it's [quoted] "field=&" entries)


				R


*** /u/gnats/src/Patches/gnatsweb.pl	Fri Sep 13 08:45:31 2002
--- /u/dss/cgi-bin/gnatsweb-v4.pl	Fri Sep 13 17:00:07 2002
***************
*** 1154,1160 ****
    {
      push(@errors, "Synopsis is blank or 'unknown'");
    }
!   if($fields{$SUBMITTER_ID_FIELD} eq 'unknown')
    {
      push(@errors, "Submitter-Id is 'unknown'");
    }
--- 1154,1161 ----
    {
      push(@errors, "Synopsis is blank or 'unknown'");
    }
!   if(defined($fields{$SUBMITTER_ID_FIELD}) &&
!      $fields{$SUBMITTER_ID_FIELD} eq 'unknown')
    {
      push(@errors, "Submitter-Id is 'unknown'");
    }
***************
*** 2004,2009 ****
--- 2005,2037 ----
      print "<td>$_:</td>\n";
  
      # 2nd column is regexp search field
+     #
+     # If we're loading a query the $$values_hash{$_} may contain
+     # a number of options ORd together rather than being a true
+     # regexp.  If this is so, remove them from the value and set
+     # them as defaults for the scrolling list in column 3
+     my $ary_ref = fieldinfo($_, 'values');
+     my @ary_defaults;
+     if (fieldinfo($_, 'fieldtype') =~ 'enum')
+     {
+       my $value = "";
+       if($$values_hash{$_})
+       {
+ 	foreach (split(/\|/, $$values_hash{$_})) {
+ 	  if (/^\^(.*)\$$/ && grep(/$1/, @$ary_ref))
+ 	  {
+ 	    push @ary_defaults, $_;
+ 	  }
+ 	  else
+ 	  {
+ 	    $value .= "|" if($value);
+ 	    $value .= $_;
+ 	  }
+ 	}
+ 	$$values_hash{$_} = $value;
+       }
+     }
+ 
      print "<td>",
            $q->textfield(-name=>$lc_fieldname,
                          -size=>$width, -value=>$$values_hash{$_});
***************
*** 2013,2022 ****
      # one can simply say "not closed".
      if ($_ eq $STATE_FIELD)
      {
        print "<br>",
              $q->checkbox_group(-name=>'ignoreclosed',
                                 -values=>['Ignore Closed'],
!                                -defaults=>['Ignore Closed']),
      }
      print "</td>\n";
  
--- 2041,2062 ----
      # one can simply say "not closed".
      if ($_ eq $STATE_FIELD)
      {
+       my @defaults;
+       if (defined(%$values_hash)) 
+       {
+ 	if (defined($$values_hash{Ignoreclosed}))
+ 	{
+ 	  @defaults = $$values_hash{Ignoreclosed};
+ 	}
+       }
+       else 
+       {
+ 	@defaults = 'Ignore Closed';
+       }
        print "<br>",
              $q->checkbox_group(-name=>'ignoreclosed',
                                 -values=>['Ignore Closed'],
!                                -defaults=>\@defaults),
      }
      print "</td>\n";
  
***************
*** 2024,2030 ****
      print "<td>";
      if (fieldinfo($_, 'fieldtype') =~ 'enum')
      {
-       my $ary_ref = fieldinfo($_, 'values');
        my $size = scalar(@$ary_ref);
        my %ary_ref_names;
        foreach (@$ary_ref) { $ary_ref_names{"^$_\$"} = "$_"; }
--- 2064,2069 ----
***************
*** 2033,2038 ****
--- 2072,2078 ----
        print $q->scrolling_list(-name=>$lc_fieldname,
                                 -values=>$ary_ref,
  			       -labels=>\%ary_ref_names,
+ 			       -defaults=>\@ary_defaults,
                                 -multiple=>1,
                                 -size=>$size);
      }
***************
*** 2622,2633 ****
  
    # Don't save certain params.
    $q->delete('cmd');
    my $query_string = $q->query_string();
  
    # strip empty params out of $query_string.  in a gnats db with many
    # fields, the query-string will become very long, and may exceed the
    # 4K limit for cookies.
!   $query_string =~ s/\w+=;//g;
  
    if (length($query_string . $global_cookie_path . "gnatsweb-query-$queryname") > 4050) {
      # this cookie is going to be longer than 4K, so we'll have to punt
--- 2662,2674 ----
  
    # Don't save certain params.
    $q->delete('cmd');
+   $q->delete('return_url');
    my $query_string = $q->query_string();
  
    # strip empty params out of $query_string.  in a gnats db with many
    # fields, the query-string will become very long, and may exceed the
    # 4K limit for cookies.
!   $query_string =~ s/\w+=[;&]//g;
  
    if (length($query_string . $global_cookie_path . "gnatsweb-query-$queryname") > 4050) {
      # this cookie is going to be longer than 4K, so we'll have to punt
***************
*** 2893,2901 ****
        if($key eq "Submitter_id") {
  	$key = "Submitter-Id";
        }
!       # I'm guessing here... (RHL)
        $val =~ s/%2A/*/g;
        $val =~ s/%20/ /g;
        $val =~ s/%5B/[/g;
        $val =~ s/%5D/]/g;
        $val =~ s/%5E/^/g;
--- 2934,2943 ----
        if($key eq "Submitter_id") {
  	$key = "Submitter-Id";
        }
!       # Undo hex escapes
        $val =~ s/%2A/*/g;
        $val =~ s/%20/ /g;
+       $val =~ s/%24/\$/g;
        $val =~ s/%5B/[/g;
        $val =~ s/%5D/]/g;
        $val =~ s/%5E/^/g;


_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* patch for gnatsweb.pl
       [not found] <20020915103254.22538.88942.Mailman@monty-python.gnu.org>
  2002-09-16  6:56 ` Robert Lupton the Good
@ 2002-09-16  7:24 ` Robert Lupton the Good
  2002-09-16  7:45 ` Robert Lupton the Good
  2 siblings, 0 replies; 14+ messages in thread
From: Robert Lupton the Good @ 2002-09-16  7:24 UTC (permalink / raw)
  To: help-gnats


(This is my "patch.5")

This patch:

	Includes the PR number in the title of the page when
	viewing/editing a PR.  I find this useful while e.g.  checking
	in the patch and I simply want to know the PR number.

	

				R


*** gnatsweb.pl	Thu Sep 12 08:59:55 2002
--- /u/dss/cgi-bin/gnatsweb-v4.pl	Thu Sep 12 09:28:11 2002
***************
*** 1346,1357 ****
  sub view
  {
    my($viewaudit, $tmp) = @_;
  
!   my $page = 'View PR';
    page_start_html($page);
  
-   # $pr must be 'local' to be available to site callback
-   local($pr) = $q->param('pr');
  
    # strip out leading category (and any other non-digit trash) from $pr
    $pr =~ s/\D//g;
--- 1346,1357 ----
  sub view
  {
    my($viewaudit, $tmp) = @_;
+   # $pr must be 'local' to be available to site callback
+   local($pr) = $q->param('pr');
  
!   my $page = "View PR $pr";
    page_start_html($page);
  
  
    # strip out leading category (and any other non-digit trash) from $pr
    $pr =~ s/\D//g;
***************
*** 1472,1483 ****
  #
  sub edit
  {
!   my $page = 'Edit PR';
    page_start_html($page);
  
    #my $debug = 0;
  
-   my($pr) = $q->param('pr');
  
    # strip out leading category (and any other non-digit trash) from
    # $pr, since it will unduly confuse gnats when we try to submit the
--- 1472,1484 ----
  #
  sub edit
  {
!   my($pr) = $q->param('pr');
! 
!   my $page = "Edit PR $pr";
    page_start_html($page);
  
    #my $debug = 0;
  
  
    # strip out leading category (and any other non-digit trash) from
    # $pr, since it will unduly confuse gnats when we try to submit the


_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Patch for gnatsweb.pl
       [not found] <20020915103254.22538.88942.Mailman@monty-python.gnu.org>
@ 2002-09-16  6:56 ` Robert Lupton the Good
  2002-09-16  7:24 ` patch " Robert Lupton the Good
  2002-09-16  7:45 ` Robert Lupton the Good
  2 siblings, 0 replies; 14+ messages in thread
From: Robert Lupton the Good @ 2002-09-16  6:56 UTC (permalink / raw)
  To: help-gnats


(This is my "patch.4")

This patch:
	1/ Allows the sendpr_intro_$lc_fieldname callback to modify
	the lists of fields for that field

	2/ Provides a callback (submitnewpr) for the user when the
	PR is being submitted.

I use this to add "<default>" to the list of possible Responsible
people, and then remove it if it's still there.  This means that my
users have the option of overriding the default Responsible Person
when the submit a PR.


					R

*** gnatsweb.pl	Wed Sep 11 14:12:31 2002
--- /u/dss/cgi-bin/gnatsweb-v4.pl	Thu Sep 12 08:58:55 2002
***************
*** 1057,1063 ****
  
      # The "intro" provides a way for the site callback to print something
      # at the top of a given field.
!     my $intro = cb("sendpr_intro_$lc_fieldname", $field_number) || '';
  
      print "<tr><td valign=\"top\" width=\"20%\"><b>$_:</b><br><small>\n",
            fieldinfo($_, 'desc'),
--- 1057,1063 ----
  
      # The "intro" provides a way for the site callback to print something
      # at the top of a given field.
!     my $intro = cb("sendpr_intro_$lc_fieldname", $field_number, @values) || '';
  
      print "<tr><td valign=\"top\" width=\"20%\"><b>$_:</b><br><small>\n",
            fieldinfo($_, 'desc'),
***************
*** 1183,1188 ****
--- 1183,1190 ----
        $val = unparse_multienum(\@val, $key);
      }
      $fields{$key} = $val;
+ 
+     cb("submitnewpr", $key, \%fields);
    }
  
    # Make sure the pr is valid.


_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Patch for gnatsweb.pl
@ 2002-09-16  6:48 Robert Lupton the Good
  2002-09-17  9:47 ` Yngve Svendsen
  2002-09-23 12:22 ` Lars Henriksen
  0 siblings, 2 replies; 14+ messages in thread
From: Robert Lupton the Good @ 2002-09-16  6:48 UTC (permalink / raw)
  To: help-gnats


(This is my `patch.3b')

I'd be happy to check these straight into cvs if given permission...


This patch:

	1/ requires exact matches for field names selected using
scrolling lists.  For example, we have a "Scheduled" field that
has entries "approved" and "notapproved"; without this patch
selecting "approved" gets "notapproved" too.  The reason is that
gnatsweb uses a ~ match in its query, and this seems reasonable.

This patch adds explicit "^" and "$" to the fields, and then
adds code so that the user doesn't see them (Note: this doesn't
work very elegantly with my "load stored query" patch that
I sent to the list a few days ago.  This problem is fixed in
a later patch that I'll send today).


	2/ Adds a field to the advanced query so that the
user can choose which field to sort on.  This includes support
for my "custom query" patch of a few days ago (but will work
even without it)


					R


*** gnatsweb.pl	Mon Sep 16 09:33:23 2002
--- ../gnatsweb.pl-3	Wed Sep 11 14:11:32 2002
***************
*** 2023,2031 ****
--- 2023,2035 ----
      {
        my $ary_ref = fieldinfo($_, 'values');
        my $size = scalar(@$ary_ref);
+       my %ary_ref_names;
+       foreach (@$ary_ref) { $ary_ref_names{"^$_\$"} = "$_"; }
+       @$ary_ref = map {"^$_\$"} @$ary_ref; # require exact matches
        $size = 4 if $size > 4;
        print $q->scrolling_list(-name=>$lc_fieldname,
                                 -values=>$ary_ref,
+ 			       -labels=>\%ary_ref_names,
                                 -multiple=>1,
                                 -size=>$size);
      }
***************
*** 2065,2070 ****
--- 2069,2080 ----
    {
      @columns = @lcfields;
    }
+ 
+   my(@sortfields) = @lcfields;
+   unshift @sortfields, "PR";
+   unshift @sortfields, "custom"
+ 	if(cb('sort_query', 'custom', 'checking_if_custom_sort_exists'));
+ 
    print "<table border=1 cellspacing=0 bgcolor=$cell_bg>\n",
          "<caption>Display</caption>\n",
          "<tr valign=top>\n<td>Display these columns:</td>\n<td>",
***************
*** 2072,2078 ****
                             -values=>\@lcfields,
                             -defaults=>\@columns,
                             -multiple=>1),
!     "</td>\n</tr>\n<tr>\n<td colspan=2>",
          $q->checkbox_group(-name=>'displaydate',
  			   -values=>['Display Current Date'],
  			   -defaults=>['Display Current Date']),
--- 2082,2093 ----
                             -values=>\@lcfields,
                             -defaults=>\@columns,
                             -multiple=>1),
!         "<tr valign=top>\n<td>Sort By:</td>\n<td>",
!         $q->scrolling_list(-name=>'sortby',
!                            -values=>\@sortfields,
!                            -multiple=>0,
! 			   -size=>1),
!         "</td>\n</tr>\n<tr>\n<td colspan=2>",
          $q->checkbox_group(-name=>'displaydate',
  			   -values=>['Display Current Date'],
  			   -defaults=>['Display Current Date']),


_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Patch for gnatsweb.pl
@ 2002-09-16  6:46 Robert Lupton the Good
  0 siblings, 0 replies; 14+ messages in thread
From: Robert Lupton the Good @ 2002-09-16  6:46 UTC (permalink / raw)
  To: help-gnats


(This is my `patch.3a')

This patch prints a header if needed when debug=all statements (this
is sometimes needed)

				R

	

*** gnatsweb.pl	Wed Sep 11 14:06:11 2002
--- /u/dss/cgi-bin/gnatsweb-v4.pl	Wed Sep 11 14:10:10 2002
***************
*** 357,363 ****
  {
    my($state, $text, $type);
    my $raw_reply = <SOCK>;
!   print "<tt>server_reply: $_</tt><br>\n" if defined($reply_debug);
    if($raw_reply =~ /(\d+)([- ]?)(.*$)/)
    {
      $state = $1;
--- 357,367 ----
  {
    my($state, $text, $type);
    my $raw_reply = <SOCK>;
!   if(defined($reply_debug))
!   {
!     print_header();
!     print "<tt>server_reply: $raw_reply</tt><br>\n";
!   }
    if($raw_reply =~ /(\d+)([- ]?)(.*$)/)
    {
      $state = $1;
***************
*** 389,395 ****
  
    while(<SOCK>)
    {
!     print "<tt>read_server: $_</tt><br>\n" if defined($reply_debug);
      if(/^\.\r/)
      {
        return @text;
--- 393,404 ----
  
    while(<SOCK>)
    {
!     if(defined($reply_debug))
!     {
!       print_header();
!       print "<tt>read_server: $_</tt><br>\n";
!     }
! 
      if(/^\.\r/)
      {
        return @text;
***************
*** 703,710 ****
    my $debug = 0;
    print SOCK "$cmd\n";
    warn "client_cmd: $cmd" if $debug;
!   print "<br><tt>client_cmd: <pre>$cmd</pre></tt><br>\n"
!         if defined($client_cmd_debug);
    return get_reply();
  }
  
--- 712,722 ----
    my $debug = 0;
    print SOCK "$cmd\n";
    warn "client_cmd: $cmd" if $debug;
!   if(defined($client_cmd_debug))
!   {
!     print_header();
!     print "<br><tt>client_cmd: <pre>$cmd</pre></tt><br>\n";
!   }
    return get_reply();
  }
  


_______________________________________________
Help-gnats mailing list
Help-gnats@gnu.org
http://mail.gnu.org/mailman/listinfo/help-gnats

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2002-09-29 19:06 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-06 14:09 patch for gnatsweb.pl David, Lysander
2002-09-16  6:46 Patch " Robert Lupton the Good
2002-09-16  6:48 Robert Lupton the Good
2002-09-17  9:47 ` Yngve Svendsen
2002-09-23 12:22 ` Lars Henriksen
2002-09-25 11:18   ` Lars Henriksen
2002-09-25 11:43     ` Yngve Svendsen
2002-09-25 13:13       ` Lars Henriksen
2002-09-26 15:46         ` Robert Lupton the Good
2002-09-27  0:32         ` Robert Lupton the Good
2002-09-30  2:07         ` Lars Henriksen
     [not found] <20020915103254.22538.88942.Mailman@monty-python.gnu.org>
2002-09-16  6:56 ` Robert Lupton the Good
2002-09-16  7:24 ` patch " Robert Lupton the Good
2002-09-16  7:45 ` Robert Lupton the Good

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).