Changeset 344

Show
Ignore:
Timestamp:
10/15/07 21:45:11 (2 years ago)
Author:
eevee
Message:

Lowered the non-wildcard-character limit to 2 (for now).
Added wildcard support to the searches.
Cleaned up wildcard display a bit.

Location:
veekun/trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • veekun/trunk/lib/Vee/Controller/Dex.pm

    r315 r344  
    1313use Storable qw/dclone/; 
    1414use Data::Dumper; 
     15 
     16# TODO: move this somewhere shared 
     17my $MAX_WILDCARD_RESULTS = 10;  # maximum wildcard matches per category 
    1518 
    1619=head1 NAME 
     
    171174     
    172175    (my $test = $entry) =~ s/[^-_ 0-9a-zA-Z]//g; 
    173     if (3 > length $test) { 
     176    if (2 > length $test) { 
    174177        $c->vee_abort('Your entry ', $entry, ' is too vague.  Please try to tone down the use of wildcards.'); 
    175178        die; 
     
    184187 
    185188    my $re = qr/^$entry$/i; 
    186     my %results; 
    187      
    188     # TODO: use %FuzzyMatches somehow 
    189     $results{abilities} = [ grep { $AbilityNames[$_] =~ $re } 1 .. $#AbilityNames ]; 
    190     $results{pokemon}   = [ grep { $PokemonNames[$_] =~ $re } 1 .. $#PokemonNames ]; 
    191     $results{types}     = [ grep { $TypeNames[$_] =~ $re } 0 .. $#TypeNames ]; 
    192     $results{moves}     = [ grep { $MoveData[$_]->name =~ $re } 1 .. $#MoveData ]; 
    193      
    194     my $total = 0; 
    195     $total += $#{$results{$_}} + 1 for keys %results; 
     189    my (%results, %overflow); 
     190     
     191    # Arrange the results by type 
     192    my @keys = grep { $_ =~ $re } keys %FuzzyMatches; 
     193    for my $key (@keys) { 
     194        my $type  = $FuzzyMatches{$key}{type}; 
     195        my $array = ($results{$type} ||= []); 
     196 
     197        push @$array, $FuzzyMatches{$key}; 
     198    } 
     199 
     200    # Sort by name, for lack of anything particularly better 
     201    for my $type (keys %results) { 
     202        my $array = $results{$type}; 
     203        @$array = sort { 
     204            $a->{name} cmp $b->{name} 
     205        } @$array; 
     206 
     207        # Don't go crazy listing matches 
     208        if (@$array > $MAX_WILDCARD_RESULTS) { 
     209            @$array = @$array[ 0 .. $MAX_WILDCARD_RESULTS - 1 ]; 
     210            $overflow{$type} = 1; 
     211        } 
     212    } 
     213 
     214    my $total = @keys; 
    196215    $c->vee_stop('No match for ', $orig, ' was found.  You may wish to try the <a href="' . $c->uri('Dex', 'pokemon_list') . '">Pok&eacute;mon list</a>, <a href="' . $c->uri('Dex', 'move_list') . '">move list</a>, <a href="' . $c->uri('Dex', 'type_list') . '">type list</a>, etc. to find what you are looking for.') unless $total; 
    197     $c->vee_stop('', $orig, ' returned too many matches.  Please try something more specific.') if $total > 50; 
    198      
     216     
     217    $s->{entry}    = $orig; 
    199218    $s->{results}  = \%results; 
     219    $s->{overflow} = \%overflow; 
    200220    $s->{template} = 'dex/lookup/wildcard.tt'; 
    201221} 
  • veekun/trunk/lib/Vee/Controller/Dex/Search.pm

    r332 r344  
    109109        # BASIC 
    110110        if ($p->{name}) { 
    111             $criteria{'me.name'} = { like => '%' . $p->{name} . '%' }; 
     111            my $name = $p->{name}; 
     112            if ($name =~ /[*?]/) { 
     113                $name =~ tr/*?/%_/; 
     114                $criteria{'me.name'} = { like => $name }; 
     115            } else { 
     116                $criteria{'me.name'} = { like => "%$name%" }; 
     117            } 
    112118        } 
    113119        if ($p->{habitat} ne 'any') { $criteria{'me.habitat'} = $p->{habitat} } 
     
    328334        # BASIC 
    329335        if ($p->{name}) { 
    330             $criteria{name} = { LIKE => '%' . $p->{name} . '%' }; 
     336            my $name = $p->{name}; 
     337            if ($name =~ /[*?]/) { 
     338                $name =~ tr/*?/%_/; 
     339                $criteria{'me.name'} = { like => $name }; 
     340            } else { 
     341                $criteria{'me.name'} = { like => "%$name%" }; 
     342            } 
    331343        } 
    332344        if ($p->{class} ne 'any') { $criteria{class} = $p->{class} } 
  • veekun/trunk/t/dex-search.t

    r343 r344  
    55use lib 'lib'; 
    66 
    7 use Test::More tests => 34; 
     7use Test::More tests => 35; 
    88 
    99BEGIN { $ENV{CATALYST_DEBUG} = 0; } 
     
    2121    [qw/ 5 134 135 136 196 197 352 395 456 457 470 471 /], 
    2222    "Name substring"; 
     23 
     24search_ok { name => '???' }, 
     25    [qw/ 89 151 /], 
     26    "Name with wildcards"; 
    2327 
    2428search_ok { ability => 'Drizzle' }, 
  • veekun/trunk/templates/dex/lookup/wildcard.tt

    r282 r344  
    77<h2>Pok&eacute;mon</h2> 
    88<ul> 
    9 [%     FOREACH p IN results.pokemon.nsort %] 
    10 <li><a href="[% dex_uri('pokemon', PokemonNames.$p) %]"><img src="/dex-images/icons/[% p.pad(3) %].png" alt=""/> [% PokemonNames.$p %]</a></li> 
     9[%     FOREACH match IN results.pokemon %] 
     10<li><a href="[% dex_uri('pokemon', match.name) %]"><img src="/dex-images/icons/[% match.id.pad(3) %].png" alt=""/> [% match.name %]</a></li> 
    1111[%     END %] 
    1212</ul> 
     13[%     IF overflow.pokemon %] 
     14<p> Too many Pok&eacute;mon matched to list.  Try the <a href="[% c.uri_for('/dex/pokemon/search', { name => entry }) %]">search</a> for more, or to narrow the list down. </p> 
     15[%     END %] 
    1316[% END %] 
    1417 
    15 [% IF results.moves.size %] 
     18[% IF results.move.size %] 
    1619<h2>Moves</h2> 
    1720<ul> 
    18 [%     FOREACH m IN results.moves.nsort %] 
    19 <li><a href="[% dex_uri('moves', MoveData.$m.name) %]">[% MoveData.$m.name %]</a></li> 
     21[%     FOREACH match IN results.move %] 
     22<li><a href="[% dex_uri('moves', match.name) %]">[% match.name %]</a></li> 
    2023[%     END %] 
    2124</ul> 
     25[%     IF overflow.move %] 
     26<p> Too many moves matched to list.  Try the <a href="[% c.uri_for('/dex/moves/search', { name => entry }) %]">search</a> for more, or to narrow the list down. </p> 
     27[%     END %] 
    2228[% END %] 
    2329 
    24 [% IF results.abilities.size %] 
     30[% IF results.ability.size %] 
    2531<h2>Abilities</h2> 
    2632<ul> 
    27 [%     FOREACH a IN results.abilities.nsort %] 
    28 <li><a href="[% dex_uri('abilities', AbilityNames.$a) %]">[% AbilityNames.$a %]</a></li> 
     33[%     FOREACH match IN results.ability %] 
     34<li><a href="[% dex_uri('abilities', match.name) %]">[% match.name %]</a></li> 
    2935[%     END %] 
    3036</ul> 
     37[%     IF overflow.ability %] 
     38<p> Too many abilities matched to list.  Try the <a href="[% c.uri_for('/dex/abilities') %]">list</a> instead? </p> 
     39[%     END %] 
    3140[% END %] 
    3241 
    33 [% IF results.types.size %] 
     42[% IF results.type.size %] 
    3443<h2>Types</h2> 
    3544<ul> 
    36 [%     FOREACH t IN results.types.nsort %] 
    37 <li><a href="[% dex_uri('types', TypeNames.$t) %]">[% TypeNames.$t %]</a></li> 
     45[%     FOREACH match IN results.type %] 
     46<li><a href="[% dex_uri('types', match.name) %]">[% match.name %]</a></li> 
    3847[%     END %] 
    3948</ul> 
     49[%     IF overflow.type %] 
     50<p> Too many types matched to list.  Try the <a href="[% c.uri_for('/dex/types') %]">list</a> instead? </p> 
     51[%     END %] 
    4052[% END %] 
  • veekun/trunk/templates/dex/search/moves.tt

    r291 r344  
    4343<ul> 
    4444[%             FOREACH m IN results %] 
    45 <li><a href="[% dex_uri('moves', MoveData.${m.id}.name) %]">[% m.id %]: [% MoveData.${m.id}.name %]</a></li> 
     45<li><a href="[% dex_uri('moves', MoveData.${m.id}.name) %]">[% MoveData.${m.id}.name %]</a></li> 
    4646[%             END %] 
    4747</ul>