Author: earle
Date: 2005-11-24 20:01:09 +0000 (Thu, 24 Nov 2005)
New Revision: 716
Added:
trunk/lib/OpenGuides/Search.pm
trunk/search.cgi
trunk/t/31_search.t
trunk/t/32_search_simple_metadata.t
trunk/t/33_search_advanced_search.t
trunk/t/33_search_advanced_search_utm.t
trunk/t/34_search_paging.t
trunk/t/35_search_two_searches.t
trunk/t/36_search_order.t
trunk/t/37_search_summaries.t
trunk/t/38_search_params.t
trunk/t/39_search_form.t
trunk/templates/search.tt
Removed:
trunk/lib/OpenGuides/SuperSearch.pm
trunk/supersearch.cgi
trunk/t/31_supersearch.t
trunk/t/32_supersearch_simple_metadata.t
trunk/t/33_supersearch_advanced_search.t
trunk/t/33_supersearch_advanced_search_utm.t
trunk/t/34_supersearch_paging.t
trunk/t/35_supersearch_two_searches.t
trunk/t/36_supersearch_order.t
trunk/t/37_supersearch_summaries.t
trunk/t/38_supersearch_params.t
trunk/t/39_supersearch_form.t
trunk/templates/supersearch.tt
Modified:
trunk/Changes
trunk/MANIFEST
trunk/t/01_load.t
trunk/templates/differences.tt
trunk/templates/footer.tt
trunk/templates/navbar.tt
trunk/templates/node.tt
Log:
Renaming OpenGuides::SuperSearch to OpenGuides::Search and supersearch.cgi to search.cgi -
bug #17.
Modified: trunk/Changes
===================================================================
--- trunk/Changes 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/Changes 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,4 +1,9 @@
-0.52 Fix missing bracket in node.tt.
+0.52
+ IMPORTANT CHANGE: "supersearch.cgi" is now simply
"search.cgi". If you
+ have customisations to your templates, you may need to make changes
+ to reflect this.
+ Rename OpenGuides::SuperSearch to OpenGuides::Search.
+ Fix missing bracket in node.tt.
Add custom_node template just below main content in node.tt.
0.51 15 November 2005
Modified: trunk/MANIFEST
===================================================================
--- trunk/MANIFEST 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/MANIFEST 2005-11-24 20:01:09 UTC (rev 716)
@@ -17,14 +17,14 @@
lib/OpenGuides/CGI.pm
lib/OpenGuides/Config.pm
lib/OpenGuides/RDF.pm
-lib/OpenGuides/SuperSearch.pm
+lib/OpenGuides/Search.pm
lib/OpenGuides/Template.pm
lib/OpenGuides/Test.pm
lib/OpenGuides/Utils.pm
lib/OpenGuides.pm
newpage.cgi
preferences.cgi
-supersearch.cgi
+search.cgi
templates/backlink_results.tt
templates/banner.tt
templates/delete_confirm.tt
@@ -49,7 +49,7 @@
templates/recent_changes.tt
templates/search_results.tt
templates/site_index.tt
-templates/supersearch.tt
+templates/search.tt
templates/userstats.tt
templates/wanted_pages.tt
t/01_load.t
@@ -64,16 +64,16 @@
t/25_write_geo_data.t
t/26_geo_data_search_form.t
t/27_geo_data_edit_form.t
-t/31_supersearch.t
-t/32_supersearch_simple_metadata.t
-t/33_supersearch_advanced_search.t
-t/33_supersearch_advanced_search_utm.t
-t/34_supersearch_paging.t
-t/35_supersearch_two_searches.t
-t/36_supersearch_order.t
-t/37_supersearch_summaries.t
-t/38_supersearch_params.t
-t/39_supersearch_form.t
+t/31_search.t
+t/32_search_simple_metadata.t
+t/33_search_advanced_search.t
+t/33_search_advanced_search_utm.t
+t/34_search_paging.t
+t/35_search_two_searches.t
+t/36_search_order.t
+t/37_search_summaries.t
+t/38_search_params.t
+t/39_search_form.t
t/41_deletion.t
t/51_display_node.t
t/52_display_diffs.t
Copied: trunk/lib/OpenGuides/Search.pm (from rev 715,
trunk/lib/OpenGuides/SuperSearch.pm)
===================================================================
--- trunk/lib/OpenGuides/SuperSearch.pm 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/lib/OpenGuides/Search.pm 2005-11-24 20:01:09 UTC (rev 716)
@@ -0,0 +1,746 @@
+package OpenGuides::Search;
+use strict;
+our $VERSION = '0.10';
+
+use CGI qw( :standard );
+use CGI::Wiki::Plugin::Locator::Grid;
+use File::Spec::Functions qw(:ALL);
+use OpenGuides::Template;
+use OpenGuides::Utils;
+use Parse::RecDescent;
+
+=head1 NAME
+
+OpenGuides::Search - Search form generation and processing for OpenGuides.
+
+=head1 DESCRIPTION
+
+Does search stuff for OpenGuides. Distributed and installed as part of
+the OpenGuides project, not intended for independent installation.
+This documentation is probably only useful to OpenGuides developers.
+
+=head1 SYNOPSIS
+
+ use CGI;
+ use OpenGuides::Config;
+ use OpenGuides::Search;
+
+ my $config = OpenGuides::Config->new( file => "wiki.conf" );
+ my $search = OpenGuides::Search->new( config => $config );
+ my %vars = CGI::Vars();
+ $search->run( vars => \%vars );
+
+=head1 METHODS
+
+=over 4
+
+=item B<new>
+
+ my $config = OpenGuides::Config->new( file => "wiki.conf" );
+ my $search = OpenGuides::Search->new( config => $config );
+
+=cut
+
+sub new {
+ my ($class, %args) = @_;
+ my $config = $args{config};
+ my $self = { config => $config };
+ bless $self, $class;
+
+ my $wiki = OpenGuides::Utils->make_wiki_object( config => $config );
+
+ $self->{wiki} = $wiki;
+ $self->{wikimain} = $config->script_url . $config->script_name;
+ $self->{css} = $config->stylesheet_url;
+ $self->{head} = $config->site_name . " Search";
+
+ my $geo_handler = $config->geo_handler;
+ my %locator_params;
+ if ( $geo_handler == 1 ) {
+ %locator_params = ( x => "os_x", y => "os_y" );
+ } elsif ( $geo_handler == 2 ) {
+ %locator_params = ( x => "osie_x", y => "osie_y" );
+ } elsif ( $geo_handler == 3 ) {
+ %locator_params = ( x => "easting", y => "northing" );
+ }
+
+ my $locator = CGI::Wiki::Plugin::Locator::Grid->new( %locator_params );
+ $wiki->register_plugin( plugin => $locator );
+ $self->{locator} = $locator;
+
+ return $self;
+}
+
+=item B<wiki>
+
+ my $wiki = $search->wiki;
+
+An accessor; returns the underlying L<CGI::Wiki> object.
+
+=cut
+
+sub wiki {
+ my $self = shift;
+ return $self->{wiki};
+}
+
+=item B<config>
+
+ my $config = $search->config;
+
+An accessor; returns the underlying L<OpenGuides::Config> object.
+
+=cut
+
+sub config {
+ my $self = shift;
+ return $self->{config};
+}
+
+=item B<run>
+
+ my %vars = CGI::Vars();
+ $search->run(
+ vars => \%vars,
+ return_output => 1, # defaults to 0
+ return_tt_vars => 1, # defaults to 0
+ );
+
+The C<return_output> parameter is optional. If supplied and true, the
+stuff that would normally be printed to STDOUT will be returned as a
+string instead.
+
+The C<return_tt_vars> parameter is also optional. If supplied and
+true, the template is not processed and the variables that would have
+been passed to it are returned as a hash. This parameter takes
+precedence over C<return_output>.
+
+These two parameters exist to make testing easier; you probably don't
+want to use them in production.
+
+=back
+
+=cut
+
+sub run {
+ my ($self, %args) = @_;
+ $self->{return_output} = $args{return_output} || 0;
+ $self->{return_tt_vars} = $args{return_tt_vars} || 0;
+
+ $self->process_params( $args{vars} );
+ if ( $self->{error} ) {
+ warn $self->{error};
+ my %tt_vars = ( error_message => $self->{error} );
+ $self->process_template( tt_vars => \%tt_vars );
+ return;
+ }
+
+ my %tt_vars = (
+ ss_version => $VERSION,
+ ss_info_url => 'http://openguides.org/page/search_help'
+ );
+
+ my $doing_search;
+
+ # Run a text search if we have a search string.
+ if ( $self->{search_string} ) {
+ $doing_search = 1;
+ $tt_vars{search_terms} = $self->{search_string};
+ $self->run_text_search;
+ }
+
+ # Run a distance search if we have sufficient criteria.
+ if ( defined $self->{distance_in_metres}
+ && defined $self->{x} && defined $self->{y} ) {
+ $doing_search = 1;
+ # Make sure to pass the criteria to the template.
+ $tt_vars{dist} = $self->{distance_in_metres};
+ $tt_vars{latitude} = $self->{latitude};
+ $tt_vars{longitude} = $self->{longitude};
+ if ( $self->config->geo_handler eq 1 ) {
+ $tt_vars{coord_field_1_value} = $self->{os_x};
+ $tt_vars{coord_field_2_value} = $self->{os_y};
+ } elsif ( $self->config->geo_handler eq 2 ) {
+ $tt_vars{coord_field_1_value} = $self->{osie_x};
+ $tt_vars{coord_field_2_value} = $self->{osie_y};
+ } elsif ( $self->config->geo_handler eq 3 ) {
+ $tt_vars{coord_field_1_value} = $self->{latitude};
+ $tt_vars{coord_field_2_value} = $self->{longitude};
+ }
+ $self->run_distance_search;
+ }
+
+ # If we're not doing a search then just print the search form.
+ unless ( $doing_search ) {
+ return $self->process_template( tt_vars => \%tt_vars );
+ }
+
+ # At this point either $self->{error} or $self->{results} will be filled.
+ if ( $self->{error} ) {
+ $tt_vars{error_message} = $self->{error};
+ $self->process_template( tt_vars => \%tt_vars );
+ return;
+ }
+
+ # So now we know that we have been asked to perform a search, and we
+ # have performed it.
+ #
+ # $self->{results} will be a hash of refs to hashes like so:
+ # 'Node Name' => {
+ # name => 'Node Name',
+ # distance => $distance_from_origin_if_any,
+ # score => $relevance_to_search_string
+ # }
+
+ my %results_hash = %{ $self->{results} || [] };
+ my @results = values %results_hash;
+ my $numres = scalar @results;
+
+ # If we only have a single hit, and the title is a good enough match
+ # to the search string, redirect to that node.
+ # (Don't try a fuzzy search on a blank search string - Plucene chokes.)
+ if ( $self->{search_string} && $numres == 1 &&
!$self->{return_tt_vars}) {
+ my %fuzzies = $self->wiki->fuzzy_title_match($self->{search_string});
+ if ( scalar keys %fuzzies ) {
+ my $node = $results[0]{name};
+ my $formatter = $self->wiki->formatter;
+ my $node_param = CGI::escape(
+ $formatter->node_name_to_node_param( $node )
+ );
+ my $output = CGI::redirect( $self->{wikimain} . "?$node_param"
);
+ return $output if $self->{return_output};
+ print $output;
+ return;
+ }
+ }
+
+ # If we had no hits then go straight to the template.
+ if ( $numres == 0 ) {
+ %tt_vars = (
+ %tt_vars,
+ first_num => 0,
+ results => [],
+ );
+ return $self->process_template( tt_vars => \%tt_vars );
+ }
+
+ # Otherwise, we browse through the results a page at a time.
+
+ # Figure out which results we're going to be showing on this
+ # page, and what the first one for the next page will be.
+ my $startpos = $args{vars}{next} || 0;
+ $tt_vars{first_num} = $numres ? $startpos + 1 : 0;
+ $tt_vars{last_num} = $numres > $startpos + 20 ? $startpos + 20 : $numres;
+ $tt_vars{total_num} = $numres;
+ if ( $numres > $startpos + 20 ) {
+ $tt_vars{next_page_startpos} = $startpos + 20;
+ }
+
+ # Sort the results - by distance if we're searching on that
+ # or by score otherwise.
+ if ( $self->{distance_in_metres} ) {
+ @results = sort { $a->{distance} <=> $b->{distance} } @results;
+ } else {
+ @results = sort { $b->{score} <=> $a->{score} } @results;
+ }
+
+ # Now snip out just the ones for this page. The -1 is because
+ # arrays index from 0 and people from 1.
+ my $from = $tt_vars{first_num} ? $tt_vars{first_num} - 1 : 0;
+ my $to = $tt_vars{last_num} - 1; # kludge to empty arr for no results
+ @results = @results[ $from .. $to ];
+
+ # Add the URL to each result hit.
+ my $formatter = $self->wiki->formatter;
+ foreach my $i ( 0 .. $#results ) {
+ my $name = $results[$i]{name};
+
+ # Add the one-line summary of the node, if there is one.
+ my %node = $self->wiki->retrieve_node($name);
+ $results[$i]{summary} = $node{metadata}{summary}[0];
+
+ my $node_param = $formatter->node_name_to_node_param( $name );
+ $results[$i]{url} = $self->{wikimain} . "?$node_param";
+ }
+
+ # Finally pass the results to the template.
+ $tt_vars{results} = \@results;
+ $self->process_template( tt_vars => \%tt_vars );
+}
+
+sub run_text_search {
+ my $self = shift;
+ my $searchstr = $self->{search_string};
+ my $wiki = $self->wiki;
+
+ # Create parser to parse the search string.
+ my $parser = Parse::RecDescent->new( q{
+
+ search: list eostring {$return = $item[1]}
+
+ list: comby(s)
+ {$return = (@{$item[1]}>1) ? ['AND', @{$item[1]}] : $item[1][0]}
+
+ comby: <leftop: term ',' term>
+ {$return = (@{$item[1]}>1) ? ['OR', @{$item[1]}] : $item[1][0]}
+
+ term: '(' list ')' {$return = $item[2]}
+ | '-' term {$return = ['NOT', @{$item[2]}]}
+ | '"' word(s) '"' {$return =
['phrase', join " ", @{$item[2]}]}
+ | word {$return = ['word', $item[1]]}
+ | '[' word(s) ']' {$return = ['title',
@{$item[2]}]}
+
+ word: /[\w'*%]+/ {$return = $item[1]}
+
+ eostring: /^\Z/
+
+ } );
+
+ unless ( $parser ) {
+ warn $@;
+ $self->{error} = "Can't create parse object - $@";
+ return $self;
+ }
+
+ # Run parser over search string.
+ my $tree = $parser->search( $searchstr );
+ unless ( $tree ) {
+ $self->{error} = "Syntax error in search: $searchstr";
+ return $self;
+ }
+
+ # Run the search over the generated search tree.
+ my %results = $self->_run_search_tree( tree => $tree );
+ $self->{results} = \%results;
+ return $self;
+}
+
+sub _run_search_tree {
+ my ($self, %args) = @_;
+ my $tree = $args{tree};
+ my @tree_arr = @$tree;
+ my $op = shift @tree_arr;
+ my $method = "_run_" . $op . "_search";
+ return $self->can($method) ? $self->$method(@tree_arr) : undef;
+}
+
+=head1 INPUT
+
+=over
+
+=item B<word>
+
+a single word will be matched as-is. For example, a search on
+
+ escalator
+
+will return all pages containing the word "escalator".
+
+=cut
+
+sub _run_word_search {
+ my ($self, $word) = @_;
+ # A word is just a small phrase.
+ return $self->_run_phrase_search( $word );
+}
+
+=item B<AND searches>
+
+A list of words with no punctuation will be ANDed, for example:
+
+ restaurant vegetarian
+
+will return all pages containing both the word "restaurant" and the word
+"vegetarian".
+
+=cut
+
+sub _run_AND_search {
+ my ($self, @subsearches) = @_;
+
+ # Do the first subsearch.
+ my %results = $self->_run_search_tree( tree => $subsearches[0] );
+
+ # Now do the rest one at a time and remove from the results anything
+ # that doesn't come up in each subsearch. Results that survive will
+ # have a score that's the sum of their score in each subsearch.
+ foreach my $tree ( @subsearches[ 1 .. $#subsearches ] ) {
+ my %subres = $self->_run_search_tree( tree => $tree );
+ my @pages = keys %results;
+ foreach my $page ( @pages ) {
+ if ( exists $subres{$page} ) {
+ $results{$page}{score} += $subres{$page}{score};
+ } else {
+ delete $results{$page};
+ }
+ }
+ }
+
+ return %results;
+}
+
+=item B<OR searches>
+
+A list of words separated by commas (and optional spaces) will be ORed,
+for example:
+
+ restaurant, cafe
+
+will return all pages containing either the word "restaurant" or the
+word "cafe".
+
+=cut
+
+sub _run_OR_search {
+ my ($self, @subsearches) = @_;
+
+ # Do all the searches. Results will have a score that's the sum
+ # of their score in each subsearch.
+ my %results;
+ foreach my $tree ( @subsearches ) {
+ my %subres = $self->_run_search_tree( tree => $tree );
+ foreach my $page ( keys %subres ) {
+ if ( $results{$page} ) {
+ $results{$page}{score} += $subres{$page}{score};
+ } else {
+ $results{$page} = $subres{$page};
+ }
+ }
+ }
+ return %results;
+}
+
+=item B<phrase searches>
+
+Enclose phrases in double quotes, for example:
+
+ "meat pie"
+
+will return all pages that contain the exact phrase "meat pie" - not pages
+that only contain, for example, "apple pie and meat sausage".
+
+=cut
+
+sub _run_phrase_search {
+ my ($self, $phrase) = @_;
+ my $wiki = $self->wiki;
+
+ # Search title and body.
+ my %contents_res = $wiki->search_nodes( $phrase );
+
+ # Rationalise the scores a little. The scores returned by
+ # CGI::Wiki::Search::Plucene are simply a ranking.
+ my $num_results = scalar keys %contents_res;
+ foreach my $node ( keys %contents_res ) {
+ $contents_res{$node} = int( $contents_res{$node} / $num_results ) + 1;
+ }
+
+ # It'll be a real phrase (as opposed to a word) if it has a space in it.
+ # In this case, dump out the nodes that don't match the search exactly.
+ # I don't know why the phrase searching isn't working properly. Fix later.
+ if ( $phrase =~ /\s/ ) {
+ my @tmp = keys %contents_res;
+ foreach my $node ( @tmp ) {
+ my $content = $wiki->retrieve_node( $node );
+ unless ( $content =~ /$phrase/i || $node =~ /$phrase/i ) {
+ delete $contents_res{$node};
+ }
+ }
+ }
+
+ my %results = map { $_ => { name => $_, score => $contents_res{$_} } }
+ keys %contents_res;
+
+ # Bump up the score if the title matches.
+ foreach my $node ( keys %results ) {
+ $results{$node}{score} += 10 if $node =~ /$phrase/i;
+ }
+
+ # Search categories.
+ my @catmatches = $wiki->list_nodes_by_metadata(
+ metadata_type => "category",
+ metadata_value => $phrase,
+ ignore_case => 1,
+ );
+
+ foreach my $node ( @catmatches ) {
+ if ( $results{$node} ) {
+ $results{$node}{score} += 3;
+ } else {
+ $results{$node} = { name => $node, score => 3 };
+ }
+ }
+
+ # Search locales.
+ my @locmatches = $wiki->list_nodes_by_metadata(
+ metadata_type => "locale",
+ metadata_value => $phrase,
+ ignore_case => 1,
+ );
+
+ foreach my $node ( @locmatches ) {
+ if ( $results{$node} ) {
+ $results{$node}{score} += 3;
+ } else {
+ $results{$node} = { name => $node, score => 3 };
+ }
+ }
+
+ return %results;
+}
+
+=back
+
+=head1 SEARCHING BY DISTANCE
+
+To perform a distance search, you need to supply one of the following
+sets of criteria to specify the distance to search within, and the
+origin (centre) of the search:
+
+=over
+
+=item B<os_dist, os_x, and os_y>
+
+Only works if you chose to use British National Grid in wiki.conf
+
+=item B<osie_dist, osie_x, and osie_y>
+
+Only works if you chose to use Irish National Grid in wiki.conf
+
+=item B<latlong_dist, latitude, and longitude>
+
+Should always work, but has a habit of "finding" things a couple of
+metres away from themselves.
+
+=back
+
+You can perform both pure distance searches and distance searches in
+combination with text searches.
+
+=cut
+
+# Note this is called after any text search is run, and it is only called
+# if there are sufficient criteria to perform the search.
+sub run_distance_search {
+ my $self = shift;
+ my $x = $self->{x};
+ my $y = $self->{y};
+ my $dist = $self->{distance_in_metres};
+
+ my @close = $self->{locator}->find_within_distance(
+ x => $x,
+ y => $y,
+ metres => $dist,
+ );
+
+ if ( $self->{results} ) {
+ my %close_hash = map { $_ => 1 } @close;
+ my %results = %{ $self->{results} };
+ my @candidates = keys %results;
+ foreach my $node ( @candidates ) {
+ if ( exists $close_hash{$node} ) {
+ my $distance = $self->_get_distance(
+ node => $node,
+ x => $x,
+ y => $y,
+ );
+ $results{$node}{distance} = $distance;
+ } else {
+ delete $results{$node};
+ }
+ }
+ $self->{results} = \%results;
+ } else {
+ my %results;
+ foreach my $node ( @close ) {
+ my $distance = $self->_get_distance (
+ node => $node,
+ x => $x,
+ y => $y,
+ );
+ $results{$node} = {
+ name => $node,
+ distance => $distance,
+ };
+ }
+ $self->{results} = \%results;
+ }
+ return $self;
+}
+
+sub _get_distance {
+ my ($self, %args) = @_;
+ my ($node, $x, $y) = @args{ qw( node x y ) };
+ return $self->{locator}->distance(
+ from_x => $x,
+ from_y => $y,
+ to_node => $node,
+ unit => "metres"
+ );
+}
+
+sub process_params {
+ my ($self, $vars_hashref) = @_;
+ my %vars = %{ $vars_hashref || {} };
+
+ # Make sure that we don't have any data left over from previous invocation.
+ # This is useful for testing purposes at the moment and will be essential
+ # for mod_perl implementations.
+ delete $self->{x};
+ delete $self->{y};
+ delete $self->{distance_in_metres};
+ delete $self->{search_string};
+
+ # Strip out any non-digits from distance and OS co-ords.
+ foreach my $param ( qw( os_x os_y osie_x osie_y
+ osie_dist os_dist latlong_dist ) ) {
+ if ( defined $vars{$param} ) {
+ $vars{$param} =~ s/[^0-9]//g;
+ # 0 is an allowed value but the empty string isn't.
+ delete $vars{$param} if $vars{$param} eq "";
+ }
+ }
+
+ # Latitude and longitude are also allowed '-' and '.'
+ foreach my $param( qw( latitude longitude ) ) {
+ if ( defined $vars{$param} ) {
+ $vars{$param} =~ s/[^-\.0-9]//g;
+ # 0 is an allowed value but the empty string isn't.
+ delete $vars{$param} if $vars{$param} eq "";
+ }
+ }
+
+ # Set $self->{distance_in_metres}, $self->{x}, $self->{y},
+ # depending on whether we got
+ # OS co-ords or lat/long. Only store parameters if they're complete,
+ # and supported by our method of distance calculation.
+ if ( defined $vars{os_x} && defined $vars{os_y} && defined
$vars{os_dist}
+ && $self->config->geo_handler eq 1 ) {
+ $self->{x} = $vars{os_x};
+ $self->{y} = $vars{os_y};
+ $self->{distance_in_metres} = $vars{os_dist};
+ } elsif ( defined $vars{osie_x} && defined $vars{osie_y}
+ && defined $vars{osie_dist}
+ && $self->config->geo_handler eq 2 ) {
+ $self->{x} = $vars{osie_x};
+ $self->{y} = $vars{osie_y};
+ $self->{distance_in_metres} = $vars{osie_dist};
+ } elsif ( defined $vars{latitude} && defined $vars{longitude}
+ && defined $vars{latlong_dist} ) {
+ # All handlers can do lat/long, but they all do it differently.
+ if ( $self->config->geo_handler eq 1 ) {
+ require Geography::NationalGrid::GB;
+ my $point = Geography::NationalGrid::GB->new(
+ Latitude => $vars{latitude},
+ Longitude => $vars{longitude},
+ );
+ $self->{x} = $point->easting;
+ $self->{y} = $point->northing;
+ } elsif ( $self->config->geo_handler eq 2 ) {
+ require Geography::NationalGrid::IE;
+ my $point = Geography::NationalGrid::IE->new(
+ Latitude => $vars{latitude},
+ Longitude => $vars{longitude},
+ );
+ $self->{x} = $point->easting;
+ $self->{y} = $point->northing;
+ } elsif ( $self->config->geo_handler eq 3 ) {
+ require Geo::Coordinates::UTM;
+ my ($zone, $x, $y) = Geo::Coordinates::UTM::latlon_to_utm(
+ $self->config->ellipsoid,
+ $vars{latitude},
+ $vars{longitude},
+ );
+ $self->{x} = $x;
+ $self->{y} = $y;
+ }
+ $self->{distance_in_metres} = $vars{latlong_dist};
+ }
+
+ # Store os_x etc so we can pass them to template.
+ foreach my $param ( qw( os_x os_y osie_x osie_y latitude longitude ) ) {
+ $self->{$param} = $vars{$param};
+ }
+
+ # Strip leading and trailing whitespace from search text.
+ $vars{search} ||= ""; # avoid uninitialised value warning
+ $vars{search} =~ s/^\s*//;
+ $vars{search} =~ s/\s*$//;
+
+ # Check for only valid characters in tainted search param
+ # (quoted literals are OK, as they are escaped)
+ # This regex copied verbatim from Ivor's old supersearch.
+ if ( $vars{search}
+ && $vars{search} !~ /^("[^"]*"|[\w
\-',()!*%\[\]])+$/i) {
+ $self->{error} = "Search expression $vars{search} contains invalid
character(s)";
+ return $self;
+ }
+ $self->{search_string} = $vars{search};
+
+ return $self;
+}
+
+# thin wrapper around OpenGuides::Template
+sub process_template {
+ my ($self, %args) = @_;
+
+ my $tt_vars = $args{tt_vars} || {};
+ $tt_vars->{not_editable} = 1;
+ $tt_vars->{not_deletable} = 1;
+ return %$tt_vars if $self->{return_tt_vars};
+ my $output = OpenGuides::Template->output(
+ wiki => $self->wiki,
+ config => $self->config,
+ template => "search.tt",
+ vars => $tt_vars,
+ );
+ return $output if $self->{return_output};
+
+ print $output;
+ return 1;
+}
+
+=head1 OUTPUT
+
+Results will be put into some form of relevance ordering. These are
+the rules we have tests for so far (and hence the only rules that can
+be relied on):
+
+=over
+
+=item *
+
+A match on page title will score higher than a match on page category
+or locale.
+
+=item *
+
+A match on page category or locale will score higher than a match on
+page content.
+
+=item *
+
+Two matches in the title beats one match in the title and one in the content.
+
+=back
+
+=cut
+
+=head1 AUTHOR
+
+The OpenGuides Project (openguides-dev(a)openguides.org)
+
+=head1 COPYRIGHT
+
+ Copyright (C) 2003-2004 The OpenGuides Project. All Rights Reserved.
+
+The OpenGuides distribution is free software; you can redistribute it
+and/or modify it under the same terms as Perl itself.
+
+=head1 SEE ALSO
+
+L<OpenGuides>
+
+=cut
+
+1;
Deleted: trunk/lib/OpenGuides/SuperSearch.pm
===================================================================
--- trunk/lib/OpenGuides/SuperSearch.pm 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/lib/OpenGuides/SuperSearch.pm 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,746 +0,0 @@
-package OpenGuides::SuperSearch;
-use strict;
-our $VERSION = '0.10';
-
-use CGI qw( :standard );
-use CGI::Wiki::Plugin::Locator::Grid;
-use File::Spec::Functions qw(:ALL);
-use OpenGuides::Template;
-use OpenGuides::Utils;
-use Parse::RecDescent;
-
-=head1 NAME
-
-OpenGuides::SuperSearch - Search form generation and processing for OpenGuides.
-
-=head1 DESCRIPTION
-
-Does search stuff for OpenGuides. Distributed and installed as part of
-the OpenGuides project, not intended for independent installation.
-This documentation is probably only useful to OpenGuides developers.
-
-=head1 SYNOPSIS
-
- use CGI;
- use OpenGuides::Config;
- use OpenGuides::SuperSearch;
-
- my $config = OpenGuides::Config->new( file => "wiki.conf" );
- my $search = OpenGuides::SuperSearch->new( config => $config );
- my %vars = CGI::Vars();
- $search->run( vars => \%vars );
-
-=head1 METHODS
-
-=over 4
-
-=item B<new>
-
- my $config = OpenGuides::Config->new( file => "wiki.conf" );
- my $search = OpenGuides::SuperSearch->new( config => $config );
-
-=cut
-
-sub new {
- my ($class, %args) = @_;
- my $config = $args{config};
- my $self = { config => $config };
- bless $self, $class;
-
- my $wiki = OpenGuides::Utils->make_wiki_object( config => $config );
-
- $self->{wiki} = $wiki;
- $self->{wikimain} = $config->script_url . $config->script_name;
- $self->{css} = $config->stylesheet_url;
- $self->{head} = $config->site_name . " Search";
-
- my $geo_handler = $config->geo_handler;
- my %locator_params;
- if ( $geo_handler == 1 ) {
- %locator_params = ( x => "os_x", y => "os_y" );
- } elsif ( $geo_handler == 2 ) {
- %locator_params = ( x => "osie_x", y => "osie_y" );
- } elsif ( $geo_handler == 3 ) {
- %locator_params = ( x => "easting", y => "northing" );
- }
-
- my $locator = CGI::Wiki::Plugin::Locator::Grid->new( %locator_params );
- $wiki->register_plugin( plugin => $locator );
- $self->{locator} = $locator;
-
- return $self;
-}
-
-=item B<wiki>
-
- my $wiki = $search->wiki;
-
-An accessor; returns the underlying L<CGI::Wiki> object.
-
-=cut
-
-sub wiki {
- my $self = shift;
- return $self->{wiki};
-}
-
-=item B<config>
-
- my $config = $search->config;
-
-An accessor; returns the underlying L<OpenGuides::Config> object.
-
-=cut
-
-sub config {
- my $self = shift;
- return $self->{config};
-}
-
-=item B<run>
-
- my %vars = CGI::Vars();
- $search->run(
- vars => \%vars,
- return_output => 1, # defaults to 0
- return_tt_vars => 1, # defaults to 0
- );
-
-The C<return_output> parameter is optional. If supplied and true, the
-stuff that would normally be printed to STDOUT will be returned as a
-string instead.
-
-The C<return_tt_vars> parameter is also optional. If supplied and
-true, the template is not processed and the variables that would have
-been passed to it are returned as a hash. This parameter takes
-precedence over C<return_output>.
-
-These two parameters exist to make testing easier; you probably don't
-want to use them in production.
-
-=back
-
-=cut
-
-sub run {
- my ($self, %args) = @_;
- $self->{return_output} = $args{return_output} || 0;
- $self->{return_tt_vars} = $args{return_tt_vars} || 0;
-
- $self->process_params( $args{vars} );
- if ( $self->{error} ) {
- warn $self->{error};
- my %tt_vars = ( error_message => $self->{error} );
- $self->process_template( tt_vars => \%tt_vars );
- return;
- }
-
- my %tt_vars = (
- ss_version => $VERSION,
- ss_info_url => 'http://openguides.org/page/search_help'
- );
-
- my $doing_search;
-
- # Run a text search if we have a search string.
- if ( $self->{search_string} ) {
- $doing_search = 1;
- $tt_vars{search_terms} = $self->{search_string};
- $self->run_text_search;
- }
-
- # Run a distance search if we have sufficient criteria.
- if ( defined $self->{distance_in_metres}
- && defined $self->{x} && defined $self->{y} ) {
- $doing_search = 1;
- # Make sure to pass the criteria to the template.
- $tt_vars{dist} = $self->{distance_in_metres};
- $tt_vars{latitude} = $self->{latitude};
- $tt_vars{longitude} = $self->{longitude};
- if ( $self->config->geo_handler eq 1 ) {
- $tt_vars{coord_field_1_value} = $self->{os_x};
- $tt_vars{coord_field_2_value} = $self->{os_y};
- } elsif ( $self->config->geo_handler eq 2 ) {
- $tt_vars{coord_field_1_value} = $self->{osie_x};
- $tt_vars{coord_field_2_value} = $self->{osie_y};
- } elsif ( $self->config->geo_handler eq 3 ) {
- $tt_vars{coord_field_1_value} = $self->{latitude};
- $tt_vars{coord_field_2_value} = $self->{longitude};
- }
- $self->run_distance_search;
- }
-
- # If we're not doing a search then just print the search form.
- unless ( $doing_search ) {
- return $self->process_template( tt_vars => \%tt_vars );
- }
-
- # At this point either $self->{error} or $self->{results} will be filled.
- if ( $self->{error} ) {
- $tt_vars{error_message} = $self->{error};
- $self->process_template( tt_vars => \%tt_vars );
- return;
- }
-
- # So now we know that we have been asked to perform a search, and we
- # have performed it.
- #
- # $self->{results} will be a hash of refs to hashes like so:
- # 'Node Name' => {
- # name => 'Node Name',
- # distance => $distance_from_origin_if_any,
- # score => $relevance_to_search_string
- # }
-
- my %results_hash = %{ $self->{results} || [] };
- my @results = values %results_hash;
- my $numres = scalar @results;
-
- # If we only have a single hit, and the title is a good enough match
- # to the search string, redirect to that node.
- # (Don't try a fuzzy search on a blank search string - Plucene chokes.)
- if ( $self->{search_string} && $numres == 1 &&
!$self->{return_tt_vars}) {
- my %fuzzies = $self->wiki->fuzzy_title_match($self->{search_string});
- if ( scalar keys %fuzzies ) {
- my $node = $results[0]{name};
- my $formatter = $self->wiki->formatter;
- my $node_param = CGI::escape(
- $formatter->node_name_to_node_param( $node )
- );
- my $output = CGI::redirect( $self->{wikimain} . "?$node_param"
);
- return $output if $self->{return_output};
- print $output;
- return;
- }
- }
-
- # If we had no hits then go straight to the template.
- if ( $numres == 0 ) {
- %tt_vars = (
- %tt_vars,
- first_num => 0,
- results => [],
- );
- return $self->process_template( tt_vars => \%tt_vars );
- }
-
- # Otherwise, we browse through the results a page at a time.
-
- # Figure out which results we're going to be showing on this
- # page, and what the first one for the next page will be.
- my $startpos = $args{vars}{next} || 0;
- $tt_vars{first_num} = $numres ? $startpos + 1 : 0;
- $tt_vars{last_num} = $numres > $startpos + 20 ? $startpos + 20 : $numres;
- $tt_vars{total_num} = $numres;
- if ( $numres > $startpos + 20 ) {
- $tt_vars{next_page_startpos} = $startpos + 20;
- }
-
- # Sort the results - by distance if we're searching on that
- # or by score otherwise.
- if ( $self->{distance_in_metres} ) {
- @results = sort { $a->{distance} <=> $b->{distance} } @results;
- } else {
- @results = sort { $b->{score} <=> $a->{score} } @results;
- }
-
- # Now snip out just the ones for this page. The -1 is because
- # arrays index from 0 and people from 1.
- my $from = $tt_vars{first_num} ? $tt_vars{first_num} - 1 : 0;
- my $to = $tt_vars{last_num} - 1; # kludge to empty arr for no results
- @results = @results[ $from .. $to ];
-
- # Add the URL to each result hit.
- my $formatter = $self->wiki->formatter;
- foreach my $i ( 0 .. $#results ) {
- my $name = $results[$i]{name};
-
- # Add the one-line summary of the node, if there is one.
- my %node = $self->wiki->retrieve_node($name);
- $results[$i]{summary} = $node{metadata}{summary}[0];
-
- my $node_param = $formatter->node_name_to_node_param( $name );
- $results[$i]{url} = $self->{wikimain} . "?$node_param";
- }
-
- # Finally pass the results to the template.
- $tt_vars{results} = \@results;
- $self->process_template( tt_vars => \%tt_vars );
-}
-
-sub run_text_search {
- my $self = shift;
- my $searchstr = $self->{search_string};
- my $wiki = $self->wiki;
-
- # Create parser to parse the search string.
- my $parser = Parse::RecDescent->new( q{
-
- search: list eostring {$return = $item[1]}
-
- list: comby(s)
- {$return = (@{$item[1]}>1) ? ['AND', @{$item[1]}] : $item[1][0]}
-
- comby: <leftop: term ',' term>
- {$return = (@{$item[1]}>1) ? ['OR', @{$item[1]}] : $item[1][0]}
-
- term: '(' list ')' {$return = $item[2]}
- | '-' term {$return = ['NOT', @{$item[2]}]}
- | '"' word(s) '"' {$return =
['phrase', join " ", @{$item[2]}]}
- | word {$return = ['word', $item[1]]}
- | '[' word(s) ']' {$return = ['title',
@{$item[2]}]}
-
- word: /[\w'*%]+/ {$return = $item[1]}
-
- eostring: /^\Z/
-
- } );
-
- unless ( $parser ) {
- warn $@;
- $self->{error} = "Can't create parse object - $@";
- return $self;
- }
-
- # Run parser over search string.
- my $tree = $parser->search( $searchstr );
- unless ( $tree ) {
- $self->{error} = "Syntax error in search: $searchstr";
- return $self;
- }
-
- # Run the search over the generated search tree.
- my %results = $self->_run_search_tree( tree => $tree );
- $self->{results} = \%results;
- return $self;
-}
-
-sub _run_search_tree {
- my ($self, %args) = @_;
- my $tree = $args{tree};
- my @tree_arr = @$tree;
- my $op = shift @tree_arr;
- my $method = "_run_" . $op . "_search";
- return $self->can($method) ? $self->$method(@tree_arr) : undef;
-}
-
-=head1 INPUT
-
-=over
-
-=item B<word>
-
-a single word will be matched as-is. For example, a search on
-
- escalator
-
-will return all pages containing the word "escalator".
-
-=cut
-
-sub _run_word_search {
- my ($self, $word) = @_;
- # A word is just a small phrase.
- return $self->_run_phrase_search( $word );
-}
-
-=item B<AND searches>
-
-A list of words with no punctuation will be ANDed, for example:
-
- restaurant vegetarian
-
-will return all pages containing both the word "restaurant" and the word
-"vegetarian".
-
-=cut
-
-sub _run_AND_search {
- my ($self, @subsearches) = @_;
-
- # Do the first subsearch.
- my %results = $self->_run_search_tree( tree => $subsearches[0] );
-
- # Now do the rest one at a time and remove from the results anything
- # that doesn't come up in each subsearch. Results that survive will
- # have a score that's the sum of their score in each subsearch.
- foreach my $tree ( @subsearches[ 1 .. $#subsearches ] ) {
- my %subres = $self->_run_search_tree( tree => $tree );
- my @pages = keys %results;
- foreach my $page ( @pages ) {
- if ( exists $subres{$page} ) {
- $results{$page}{score} += $subres{$page}{score};
- } else {
- delete $results{$page};
- }
- }
- }
-
- return %results;
-}
-
-=item B<OR searches>
-
-A list of words separated by commas (and optional spaces) will be ORed,
-for example:
-
- restaurant, cafe
-
-will return all pages containing either the word "restaurant" or the
-word "cafe".
-
-=cut
-
-sub _run_OR_search {
- my ($self, @subsearches) = @_;
-
- # Do all the searches. Results will have a score that's the sum
- # of their score in each subsearch.
- my %results;
- foreach my $tree ( @subsearches ) {
- my %subres = $self->_run_search_tree( tree => $tree );
- foreach my $page ( keys %subres ) {
- if ( $results{$page} ) {
- $results{$page}{score} += $subres{$page}{score};
- } else {
- $results{$page} = $subres{$page};
- }
- }
- }
- return %results;
-}
-
-=item B<phrase searches>
-
-Enclose phrases in double quotes, for example:
-
- "meat pie"
-
-will return all pages that contain the exact phrase "meat pie" - not pages
-that only contain, for example, "apple pie and meat sausage".
-
-=cut
-
-sub _run_phrase_search {
- my ($self, $phrase) = @_;
- my $wiki = $self->wiki;
-
- # Search title and body.
- my %contents_res = $wiki->search_nodes( $phrase );
-
- # Rationalise the scores a little. The scores returned by
- # CGI::Wiki::Search::Plucene are simply a ranking.
- my $num_results = scalar keys %contents_res;
- foreach my $node ( keys %contents_res ) {
- $contents_res{$node} = int( $contents_res{$node} / $num_results ) + 1;
- }
-
- # It'll be a real phrase (as opposed to a word) if it has a space in it.
- # In this case, dump out the nodes that don't match the search exactly.
- # I don't know why the phrase searching isn't working properly. Fix later.
- if ( $phrase =~ /\s/ ) {
- my @tmp = keys %contents_res;
- foreach my $node ( @tmp ) {
- my $content = $wiki->retrieve_node( $node );
- unless ( $content =~ /$phrase/i || $node =~ /$phrase/i ) {
- delete $contents_res{$node};
- }
- }
- }
-
- my %results = map { $_ => { name => $_, score => $contents_res{$_} } }
- keys %contents_res;
-
- # Bump up the score if the title matches.
- foreach my $node ( keys %results ) {
- $results{$node}{score} += 10 if $node =~ /$phrase/i;
- }
-
- # Search categories.
- my @catmatches = $wiki->list_nodes_by_metadata(
- metadata_type => "category",
- metadata_value => $phrase,
- ignore_case => 1,
- );
-
- foreach my $node ( @catmatches ) {
- if ( $results{$node} ) {
- $results{$node}{score} += 3;
- } else {
- $results{$node} = { name => $node, score => 3 };
- }
- }
-
- # Search locales.
- my @locmatches = $wiki->list_nodes_by_metadata(
- metadata_type => "locale",
- metadata_value => $phrase,
- ignore_case => 1,
- );
-
- foreach my $node ( @locmatches ) {
- if ( $results{$node} ) {
- $results{$node}{score} += 3;
- } else {
- $results{$node} = { name => $node, score => 3 };
- }
- }
-
- return %results;
-}
-
-=back
-
-=head1 SEARCHING BY DISTANCE
-
-To perform a distance search, you need to supply one of the following
-sets of criteria to specify the distance to search within, and the
-origin (centre) of the search:
-
-=over
-
-=item B<os_dist, os_x, and os_y>
-
-Only works if you chose to use British National Grid in wiki.conf
-
-=item B<osie_dist, osie_x, and osie_y>
-
-Only works if you chose to use Irish National Grid in wiki.conf
-
-=item B<latlong_dist, latitude, and longitude>
-
-Should always work, but has a habit of "finding" things a couple of
-metres away from themselves.
-
-=back
-
-You can perform both pure distance searches and distance searches in
-combination with text searches.
-
-=cut
-
-# Note this is called after any text search is run, and it is only called
-# if there are sufficient criteria to perform the search.
-sub run_distance_search {
- my $self = shift;
- my $x = $self->{x};
- my $y = $self->{y};
- my $dist = $self->{distance_in_metres};
-
- my @close = $self->{locator}->find_within_distance(
- x => $x,
- y => $y,
- metres => $dist,
- );
-
- if ( $self->{results} ) {
- my %close_hash = map { $_ => 1 } @close;
- my %results = %{ $self->{results} };
- my @candidates = keys %results;
- foreach my $node ( @candidates ) {
- if ( exists $close_hash{$node} ) {
- my $distance = $self->_get_distance(
- node => $node,
- x => $x,
- y => $y,
- );
- $results{$node}{distance} = $distance;
- } else {
- delete $results{$node};
- }
- }
- $self->{results} = \%results;
- } else {
- my %results;
- foreach my $node ( @close ) {
- my $distance = $self->_get_distance (
- node => $node,
- x => $x,
- y => $y,
- );
- $results{$node} = {
- name => $node,
- distance => $distance,
- };
- }
- $self->{results} = \%results;
- }
- return $self;
-}
-
-sub _get_distance {
- my ($self, %args) = @_;
- my ($node, $x, $y) = @args{ qw( node x y ) };
- return $self->{locator}->distance(
- from_x => $x,
- from_y => $y,
- to_node => $node,
- unit => "metres"
- );
-}
-
-sub process_params {
- my ($self, $vars_hashref) = @_;
- my %vars = %{ $vars_hashref || {} };
-
- # Make sure that we don't have any data left over from previous invocation.
- # This is useful for testing purposes at the moment and will be essential
- # for mod_perl implementations.
- delete $self->{x};
- delete $self->{y};
- delete $self->{distance_in_metres};
- delete $self->{search_string};
-
- # Strip out any non-digits from distance and OS co-ords.
- foreach my $param ( qw( os_x os_y osie_x osie_y
- osie_dist os_dist latlong_dist ) ) {
- if ( defined $vars{$param} ) {
- $vars{$param} =~ s/[^0-9]//g;
- # 0 is an allowed value but the empty string isn't.
- delete $vars{$param} if $vars{$param} eq "";
- }
- }
-
- # Latitude and longitude are also allowed '-' and '.'
- foreach my $param( qw( latitude longitude ) ) {
- if ( defined $vars{$param} ) {
- $vars{$param} =~ s/[^-\.0-9]//g;
- # 0 is an allowed value but the empty string isn't.
- delete $vars{$param} if $vars{$param} eq "";
- }
- }
-
- # Set $self->{distance_in_metres}, $self->{x}, $self->{y},
- # depending on whether we got
- # OS co-ords or lat/long. Only store parameters if they're complete,
- # and supported by our method of distance calculation.
- if ( defined $vars{os_x} && defined $vars{os_y} && defined
$vars{os_dist}
- && $self->config->geo_handler eq 1 ) {
- $self->{x} = $vars{os_x};
- $self->{y} = $vars{os_y};
- $self->{distance_in_metres} = $vars{os_dist};
- } elsif ( defined $vars{osie_x} && defined $vars{osie_y}
- && defined $vars{osie_dist}
- && $self->config->geo_handler eq 2 ) {
- $self->{x} = $vars{osie_x};
- $self->{y} = $vars{osie_y};
- $self->{distance_in_metres} = $vars{osie_dist};
- } elsif ( defined $vars{latitude} && defined $vars{longitude}
- && defined $vars{latlong_dist} ) {
- # All handlers can do lat/long, but they all do it differently.
- if ( $self->config->geo_handler eq 1 ) {
- require Geography::NationalGrid::GB;
- my $point = Geography::NationalGrid::GB->new(
- Latitude => $vars{latitude},
- Longitude => $vars{longitude},
- );
- $self->{x} = $point->easting;
- $self->{y} = $point->northing;
- } elsif ( $self->config->geo_handler eq 2 ) {
- require Geography::NationalGrid::IE;
- my $point = Geography::NationalGrid::IE->new(
- Latitude => $vars{latitude},
- Longitude => $vars{longitude},
- );
- $self->{x} = $point->easting;
- $self->{y} = $point->northing;
- } elsif ( $self->config->geo_handler eq 3 ) {
- require Geo::Coordinates::UTM;
- my ($zone, $x, $y) = Geo::Coordinates::UTM::latlon_to_utm(
- $self->config->ellipsoid,
- $vars{latitude},
- $vars{longitude},
- );
- $self->{x} = $x;
- $self->{y} = $y;
- }
- $self->{distance_in_metres} = $vars{latlong_dist};
- }
-
- # Store os_x etc so we can pass them to template.
- foreach my $param ( qw( os_x os_y osie_x osie_y latitude longitude ) ) {
- $self->{$param} = $vars{$param};
- }
-
- # Strip leading and trailing whitespace from search text.
- $vars{search} ||= ""; # avoid uninitialised value warning
- $vars{search} =~ s/^\s*//;
- $vars{search} =~ s/\s*$//;
-
- # Check for only valid characters in tainted search param
- # (quoted literals are OK, as they are escaped)
- # This regex copied verbatim from Ivor's old supersearch.
- if ( $vars{search}
- && $vars{search} !~ /^("[^"]*"|[\w
\-',()!*%\[\]])+$/i) {
- $self->{error} = "Search expression $vars{search} contains invalid
character(s)";
- return $self;
- }
- $self->{search_string} = $vars{search};
-
- return $self;
-}
-
-# thin wrapper around OpenGuides::Template
-sub process_template {
- my ($self, %args) = @_;
-
- my $tt_vars = $args{tt_vars} || {};
- $tt_vars->{not_editable} = 1;
- $tt_vars->{not_deletable} = 1;
- return %$tt_vars if $self->{return_tt_vars};
- my $output = OpenGuides::Template->output(
- wiki => $self->wiki,
- config => $self->config,
- template =>
"supersearch.tt",
- vars => $tt_vars,
- );
- return $output if $self->{return_output};
-
- print $output;
- return 1;
-}
-
-=head1 OUTPUT
-
-Results will be put into some form of relevance ordering. These are
-the rules we have tests for so far (and hence the only rules that can
-be relied on):
-
-=over
-
-=item *
-
-A match on page title will score higher than a match on page category
-or locale.
-
-=item *
-
-A match on page category or locale will score higher than a match on
-page content.
-
-=item *
-
-Two matches in the title beats one match in the title and one in the content.
-
-=back
-
-=cut
-
-=head1 AUTHOR
-
-The OpenGuides Project (openguides-dev(a)openguides.org)
-
-=head1 COPYRIGHT
-
- Copyright (C) 2003-2004 The OpenGuides Project. All Rights Reserved.
-
-The OpenGuides distribution is free software; you can redistribute it
-and/or modify it under the same terms as Perl itself.
-
-=head1 SEE ALSO
-
-L<OpenGuides>
-
-=cut
-
-1;
Copied: trunk/search.cgi (from rev 715, trunk/supersearch.cgi)
===================================================================
--- trunk/supersearch.cgi 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/search.cgi 2005-11-24 20:01:09 UTC (rev 716)
@@ -0,0 +1,14 @@
+#!/usr/local/bin/perl
+
+use warnings;
+use strict;
+
+use CGI;
+use OpenGuides::Config;
+use OpenGuides::Search;
+
+my $config_file = $ENV{OPENGUIDES_CONFIG_FILE} || "wiki.conf";
+my $config = OpenGuides::Config->new( file => $config_file );
+my $search = OpenGuides::Search->new( config => $config );
+my %vars = CGI::Vars();
+$search->run( vars => \%vars );
Deleted: trunk/supersearch.cgi
===================================================================
--- trunk/supersearch.cgi 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/supersearch.cgi 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,14 +0,0 @@
-#!/usr/local/bin/perl
-
-use warnings;
-use strict;
-
-use CGI;
-use OpenGuides::Config;
-use OpenGuides::SuperSearch;
-
-my $config_file = $ENV{OPENGUIDES_CONFIG_FILE} || "wiki.conf";
-my $config = OpenGuides::Config->new( file => $config_file );
-my $search = OpenGuides::SuperSearch->new( config => $config );
-my %vars = CGI::Vars();
-$search->run( vars => \%vars );
Modified: trunk/t/01_load.t
===================================================================
--- trunk/t/01_load.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/01_load.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -4,6 +4,6 @@
use_ok( "OpenGuides::CGI" );
use_ok( "OpenGuides::Config" );
use_ok( "OpenGuides::RDF" );
-use_ok( "OpenGuides::SuperSearch" );
+use_ok( "OpenGuides::Search" );
use_ok( "OpenGuides::Template" );
use_ok( "OpenGuides::Utils" );
Copied: trunk/t/31_search.t (from rev 715, trunk/t/31_supersearch.t)
Deleted: trunk/t/31_supersearch.t
===================================================================
--- trunk/t/31_supersearch.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/31_supersearch.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,154 +0,0 @@
-use strict;
-use CGI::Wiki::Setup::SQLite;
-use OpenGuides::SuperSearch;
-use OpenGuides::Test;
-use Test::More;
-
-eval { require DBD::SQLite; };
-if ( $@ ) {
- plan skip_all => "DBD::SQLite not installed";
-} else {
- plan tests => 18;
-
- # Clear out the database from any previous runs.
- unlink "t/node.db";
- unlink <t/indexes/*>;
-
- CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } );
- my $config = OpenGuides::Test->make_basic_config;
- $config->script_name( "wiki.cgi" );
- $config->script_url( "http://example.com/" );
-
- # Plucene is the recommended searcher now.
- eval { require CGI::Wiki::Search::Plucene; };
- if ( $@ ) { $config->use_plucene( 0 ) };
-
- my $search = OpenGuides::SuperSearch->new( config => $config );
- isa_ok( $search, "OpenGuides::SuperSearch" );
-
- my $output = $search->run( return_output => 1 );
- unlike( $output, qr/no items matched/i,
- "doesn't output 'no items matched' if no terms
supplied" );
- unlike( $output, qr/action=edit/,
- "doesn't offer edit link" );
-
- my %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "banana"
},
- );
- is( $tt_vars{first_num}, 0, "first_num set to 0 when no hits" );
- is( scalar @{ $tt_vars{results} }, 0, "...and results array empty" );
-
- $output = $search->run(
- return_output => 1,
- vars => { search => "banana" }
- );
- like( $output, qr/no items matched/i,
- "outputs 'no items matched' if term not found" );
- unlike( $output, qr/matches found, showing/i,
- "doesn't output 'matches found, showing' if term not
found" );
-
- # Pop some data in and search again.
- my $wiki = $search->{wiki}; # white boxiness
- $wiki->write_node( "Banana", "banana" );
- $wiki->write_node( "Monkey", "banana brains" );
- $wiki->write_node( "Monkey Brains", "BRANES" );
- $wiki->write_node( "Want Pie Now", "weebl" );
- $wiki->write_node( "Punctuation", "*" );
- $wiki->write_node( "Choice", "Eenie meenie minie mo");
-
- # Test with two hits first - simpler.
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "banana" },
- );
- my @found = map { $_->{name} } @{ $tt_vars{results} || [] };
- is( scalar @found, 2, "search finds single word twice" );
- is_deeply( [ sort @found ], [ "Banana", "Monkey" ],
- "...in the right places" );
- print "# Found in $_\n" foreach @found;
-
- # Make sure that $output matches too - we're testing the template here.
- $output = $search->run(
- return_output => 1,
- vars => { search => "banana" },
- );
- like( $output, qr/<a
href="http:\/\/example.com\/wiki.cgi\?Banana">/,
- "...and link is included in template output" );
-
- # One hit in body only should show result list.
- $output = $search->run(
- return_output => 1,
- vars => { search => "weebl" },
- );
- unlike( $output, qr/Status: 302 Moved/,
- "no redirect if match only in body");
-
- # One hit in title should redirect to that page.
- $output = $search->run(
- return_output => 1,
- vars => { search => "want pie now"
},
- );
- like( $output, qr/Status: 302 Moved/,
- "prints redirect on single hit and match in title" );
- # Old versions of CGI.pm mistakenly print location: instead of Location:
- like( $output,
- qr/[lL]ocation: http:\/\/example.com\/wiki.cgi\?Want_Pie_Now/,
- "...and node name munged correctly in URL" );
-
- # Test the AND search
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "monkey banana"
},
- );
- @found = map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "Monkey" ], "AND search returns right
results" );
-
- # Test the OR search
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "brains, pie"
},
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "Monkey", "Monkey Brains", "Want Pie
Now" ],
- "OR search returns right results" );
- print "# Found in $_\n" foreach @found;
-
- SKIP: {
- skip "NOT search not done yet", 1;
- # Test the NOT search
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "banana
-monkey" },
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "Banana" ], "NOT search returns right
results" );
- } # end of SKIP
-
- # Test the phrase search
- $output = $search->run(
- return_output => 1,
- vars => { search => '"monkey
brains"' },
- );
- like( $output,
- qr/[lL]ocation: http:\/\/example.com\/wiki.cgi\?Monkey_Brains/,
- "phrase search returns right results and redirects to page"
- );
-
- #####
- ##### Test numbering when we have more than a page of results.
- #####
-
- foreach my $i ( 1 .. 30 ) {
- $wiki->write_node( "Node $i", "wombat" ) or die
"Can't write Node $i";
- }
- $output = $search->run(
- return_output => 1,
- vars => {
- search => "wombat",
- next => 20,
- },
- );
- like( $output, qr/ol start="21"/,
- "second page of results starts with right numbering" );
-}
Copied: trunk/t/32_search_simple_metadata.t (from rev 715,
trunk/t/32_supersearch_simple_metadata.t)
Deleted: trunk/t/32_supersearch_simple_metadata.t
===================================================================
--- trunk/t/32_supersearch_simple_metadata.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/32_supersearch_simple_metadata.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,129 +0,0 @@
-use strict;
-use CGI::Wiki::Setup::SQLite;
-use OpenGuides::Config;
-use OpenGuides::SuperSearch;
-use Test::More tests => 10;
-
-eval { require DBD::SQLite; };
-my $have_sqlite = $@ ? 0 : 1;
-
-SKIP: {
- skip "DBD::SQLite not installed - no database to test with", 10
- unless $have_sqlite;
-
- # Clear out the database from any previous runs.
- unlink "t/node.db";
- unlink <t/indexes/*>;
-
- CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } );
- my $config = OpenGuides::Config->new(
- vars => {
- dbtype => "sqlite",
- dbname => "t/node.db",
- indexing_directory => "t/indexes",
- script_name => "wiki.cgi",
- script_url => "http://example.com/",
- site_name => "Test Site",
- template_path => "./templates",
- }
- );
-
- # Plucene is the recommended searcher now.
- eval { require CGI::Wiki::Search::Plucene; };
- if ( $@ ) { $config->use_plucene( 0 ) };
-
- my $search = OpenGuides::SuperSearch->new( config => $config );
-
- # Add some data. We write it twice to avoid hitting the redirect.
- my $wiki = $search->{wiki}; # white boxiness
- $wiki->write_node( "Calthorpe Arms", "Serves beer.", undef,
- { category => "Pubs", locale =>
"Holborn" } );
- $wiki->write_node( "Penderel's Oak", "Serves beer.",
undef,
- { category => "Pubs", locale =>
"Holborn" } );
- $wiki->write_node( "British Museum", "Huge museum, lots of
artifacts.", undef,
- { category => ["Museums", "Major
Attractions"]
- , locale => ["Holborn", "Bloomsbury"] } );
-
- # Check that a search on its category works.
- my %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "Pubs" },
- );
- my @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "Calthorpe Arms", "Penderel's Oak" ],
- "simple search looks in category" );
-
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "pubs" },
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "Calthorpe Arms", "Penderel's Oak" ],
- "...and is case-insensitive" );
-
- # Check that a search on its locale works.
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "Holborn" },
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "British Museum", "Calthorpe Arms",
"Penderel's Oak" ],
- "simple search looks in locale" );
-
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "holborn" },
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "British Museum", "Calthorpe Arms",
"Penderel's Oak" ],
- "...and is case-insensitive" );
-
- # Test AND search in various combinations.
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "Holborn Pubs"
},
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "Calthorpe Arms", "Penderel's Oak" ],
- "AND search works between category and locale" );
-
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "Holborn
Penderel" },
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "Penderel's Oak" ],
- "AND search works between title and locale" );
-
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "Pubs
Penderel" },
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "Penderel's Oak" ],
- "AND search works between title and category" );
-
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "Holborn beer"
},
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "Calthorpe Arms", "Penderel's Oak" ],
- "...and between body and locale" );
-
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "Pubs beer"
},
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "Calthorpe Arms", "Penderel's Oak" ],
- "...and between body and category" );
-
- %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => '"major
attractions"' },
- );
- @found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
- is_deeply( \@found, [ "British Museum", ],
- "Multi word category name" );
-}
Copied: trunk/t/33_search_advanced_search.t (from rev 715,
trunk/t/33_supersearch_advanced_search.t)
Copied: trunk/t/33_search_advanced_search_utm.t (from rev 715,
trunk/t/33_supersearch_advanced_search_utm.t)
Deleted: trunk/t/33_supersearch_advanced_search.t
===================================================================
--- trunk/t/33_supersearch_advanced_search.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/33_supersearch_advanced_search.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,182 +0,0 @@
-use strict;
-use CGI::Wiki::Plugin::Locator::Grid; # use directly to help debug
-use CGI::Wiki::Setup::SQLite;
-use OpenGuides::Config;
-use OpenGuides::SuperSearch;
-use OpenGuides::Test;
-use Test::More;
-
-eval { require DBD::SQLite; };
-if ( $@ ) {
- plan skip_all => "DBD::SQLite not installed";
-}
-
-eval { require Plucene; };
-if ( $@ ) {
- plan skip_all => "Plucene not installed";
-}
-
-eval { require Geography::NationalGrid::GB; };
-if ( $@ ) {
- plan skip_all => "Geography::NationalGrid::GB not installed";
-}
-
-plan tests => 8;
-
-# Clear out the database from any previous runs.
-unlink "t/node.db";
-unlink <t/indexes/*>;
-CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } );
-
-my $config = OpenGuides::Config->new(
- vars => {
- dbtype => "sqlite",
- dbname => "t/node.db",
- indexing_directory => "t/indexes",
- script_name => "wiki.cgi",
- script_url => "http://example.com/",
- site_name => "Test Site",
- template_path => "./templates",
- use_plucene => 1,
- geo_handler => 1,
- }
-);
-my $search = OpenGuides::SuperSearch->new( config => $config );
-my $guide = OpenGuides->new( config => $config );
-
-# Write some data.
-OpenGuides::Test->write_data(
- guide => $guide,
- node => "Crabtree Tavern",
- os_x => 523465,
- os_y => 177490,
- categories => "Pubs",
- );
-
-OpenGuides::Test->write_data(
- guide => $guide,
- node => "Blue Anchor",
- os_x => 522909,
- os_y => 178232,
- categories => "Pubs",
- );
-
-OpenGuides::Test->write_data(
- guide => $guide,
- node => "Star Tavern",
- os_x => 528107,
- os_y => 179347,
- categories => "Pubs",
- );
-
-OpenGuides::Test->write_data(
- guide => $guide,
- node => "Hammersmith Bridge",
- os_x => 522983,
- os_y => 178118,
- );
-
-# Sanity check.
-print "# Distances should be:\n";
-my $locator = CGI::Wiki::Plugin::Locator::Grid->new(x => "os_x", y =>
"os_y");
-my $wiki = $guide->wiki;
-$wiki->register_plugin( plugin => $locator );
-foreach my $node ( "Blue Anchor", "Crabtree Tavern",
"Hammersmith Bridge"){
- print "# $node: " . $locator->distance( from_x => 523450,
- from_y => 177650,
- to_node => $node ) . "\n";
-}
-
-# Check that a lat/long distance search finds them.
-my %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => {
- latitude => 51.484320,
- longitude => -0.223484,
- latlong_dist => 1000,
- },
- );
-my @ordered = map { $_->{name} } @{ $tt_vars{results} || [] };
-my @found = sort @ordered;
-is_deeply( \@found,
- [ "Blue Anchor", "Crabtree Tavern", "Hammersmith
Bridge" ],
- "distance search finds the right things" );
-is_deeply( \@ordered,
- [ "Crabtree Tavern", "Hammersmith Bridge", "Blue
Anchor" ],
- "...and returns them in the right order" );
-
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => {
- latitude => 51.484320,
- longitude => -0.223484,
- latlong_dist => 1000,
- search => " ",
- },
- );
-@ordered = map { $_->{name} } @{ $tt_vars{results} || [] };
-@found = sort @ordered;
-is_deeply( \@found,
- [ "Blue Anchor", "Crabtree Tavern", "Hammersmith
Bridge" ],
- "...still works if whitespace-only search text supplied" );
-
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => {
- os_x => 523450,
- os_y => 177650,
- os_dist => 1000,
- search => " ",
- },
- );
-@ordered = map { $_->{name} } @{ $tt_vars{results} || [] };
-@found = sort @ordered;
-is_deeply( \@found,
- [ "Blue Anchor", "Crabtree Tavern", "Hammersmith
Bridge" ],
- "...works with OS co-ords" );
-
-%tt_vars = eval {
- $search->run(
- return_tt_vars => 1,
- vars => {
- os_x => 523450,
- os_y => 177650,
- os_dist => 1000,
- search => " ",
- latitude => " ",
- longitude => " ",
- },
- );
-};
-is( $@, "", "...works with OS co-ords and whitespace-only lat/long"
);
-@ordered = map { $_->{name} } @{ $tt_vars{results} || [] };
-@found = sort @ordered;
-is_deeply( \@found,
- [ "Blue Anchor", "Crabtree Tavern", "Hammersmith
Bridge" ],
- "...returns the right stuff" );
-
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => {
- latitude => 51.484320,
- longitude => -0.223484,
- latlong_dist => 1000,
- search => "pubs",
- },
- );
-@found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
-is_deeply( \@found, [ "Blue Anchor", "Crabtree Tavern", ],
- "distance search in combination with text search works" );
-
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => {
- os_x => 523450,
- os_y => 177650,
- os_dist => 1000,
- search => "pubs",
- },
- );
-@found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
-is_deeply( \@found, [ "Blue Anchor", "Crabtree Tavern", ],
- "...works with OS co-ords too" );
Deleted: trunk/t/33_supersearch_advanced_search_utm.t
===================================================================
--- trunk/t/33_supersearch_advanced_search_utm.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/33_supersearch_advanced_search_utm.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,132 +0,0 @@
-use strict;
-use CGI::Wiki::Setup::SQLite;
-use OpenGuides::Config;
-use OpenGuides::SuperSearch;
-use OpenGuides::Test;
-use Test::More;
-
-eval { require DBD::SQLite; };
-if ( $@ ) {
- plan skip_all => "DBD::SQLite not installed";
-}
-
-eval { require Plucene; };
-if ( $@ ) {
- plan skip_all => "Plucene not installed";
-}
-
-eval { require Geo::Coordinates::UTM; };
-if ( $@ ) {
- plan skip_all => "Geo::Coordinates::UTM not installed";
-}
-
-plan tests => 4;
-
-# Clear out the database from any previous runs.
-unlink "t/node.db";
-unlink <t/indexes/*>;
-CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } );
-
-my $config = OpenGuides::Config->new(
- vars => {
- dbtype => "sqlite",
- dbname => "t/node.db",
- indexing_directory => "t/indexes",
- script_name => "wiki.cgi",
- script_url => "http://example.com/",
- site_name => "Test Site",
- template_path => "./templates",
- use_plucene => 1,
- geo_handler => 3,
- ellipsoid => "Airy",
- }
-);
-my $search = OpenGuides::SuperSearch->new( config => $config );
-my $guide = OpenGuides->new( config => $config );
-
-# Write some data.
-OpenGuides::Test->write_data(
- guide => $guide,
- node => "Crabtree Tavern",
- latitude => 51.482385,
- longitude => -0.221743,
- categories => "Pubs",
- );
-
-OpenGuides::Test->write_data(
- guide => $guide,
- node => "Blue Anchor",
- latitude => 51.489176,
- longitude => -0.229488,
- categories => "Pubs",
- );
-
-OpenGuides::Test->write_data(
- guide => $guide,
- node => "Star Tavern",
- latitude => 51.498043,
- longitude => -0.154247,
- categories => "Pubs",
- );
-
-OpenGuides::Test->write_data(
- guide => $guide,
- node => "Hammersmith Bridge",
- latitude => 51.488135,
- longitude => -0.228463,
- );
-
-# Sanity check.
-print "# Distances should be round about:\n";
-my $locator = $guide->locator;
-foreach my $node ( "Blue Anchor", "Crabtree Tavern",
"Hammersmith Bridge"){
- print "# $node: " . $locator->distance( from_x => 692756,
- from_y => 5706917,
- to_node => $node ) . "\n";
-}
-
-# Check that a lat/long distance search finds them.
-my %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => {
- latitude => 51.484320,
- longitude => -0.223484,
- latlong_dist => 1000,
- },
- );
-my @ordered = map { $_->{name} } @{ $tt_vars{results} || [] };
-my @found = sort @ordered;
-is_deeply( \@found,
- [ "Blue Anchor", "Crabtree Tavern", "Hammersmith
Bridge" ],
- "distance search finds the right things" );
-is_deeply( \@ordered,
- [ "Crabtree Tavern", "Hammersmith Bridge", "Blue
Anchor" ],
- "...and returns them in the right order" );
-
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => {
- latitude => 51.484320,
- longitude => -0.223484,
- latlong_dist => 1000,
- search => " ",
- },
- );
-@ordered = map { $_->{name} } @{ $tt_vars{results} || [] };
-@found = sort @ordered;
-is_deeply( \@found,
- [ "Blue Anchor", "Crabtree Tavern", "Hammersmith
Bridge" ],
- "...still works if whitespace-only search text supplied" );
-
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => {
- latitude => 51.484320,
- longitude => -0.223484,
- latlong_dist => 1000,
- search => "pubs",
- },
- );
-@found = sort map { $_->{name} } @{ $tt_vars{results} || [] };
-is_deeply( \@found, [ "Blue Anchor", "Crabtree Tavern", ],
- "distance search in combination with text search works" );
Copied: trunk/t/34_search_paging.t (from rev 715, trunk/t/34_supersearch_paging.t)
Deleted: trunk/t/34_supersearch_paging.t
===================================================================
--- trunk/t/34_supersearch_paging.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/34_supersearch_paging.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,130 +0,0 @@
-use strict;
-use CGI::Wiki::Setup::SQLite;
-use OpenGuides::Config;
-use OpenGuides::SuperSearch;
-use OpenGuides::Test;
-use Test::More;
-
-eval { require DBD::SQLite; };
-if ( $@ ) {
- plan skip_all => "DBD::SQLite not installed";
-}
-
-eval { require Plucene; };
-if ( $@ ) {
- plan skip_all => "Plucene not installed";
-}
-
-plan tests => 9;
-
-# Clear out the database from any previous runs.
-unlink "t/node.db";
-unlink <t/indexes/*>;
-CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } );
-
-my $config = OpenGuides::Test->make_basic_config;
-$config->use_plucene( 1 );
-my $search = OpenGuides::SuperSearch->new( config => $config );
-my $guide = OpenGuides->new( config => $config );
-
-# Test with OS co-ords.
-eval { require Geography::NationalGrid::GB; };
-SKIP: {
- skip "Geography::NationalGrid::GB not installed", 3 if $@;
- $config->geo_handler( 1 );
-
- foreach my $i ( 1 .. 30 ) {
- OpenGuides::Test->write_data(
- guide => $guide,
- node => "Crabtree Tavern $i",
- os_x => 523465,
- os_y => 177490,
- categories => "Pubs",
- );
- }
-
- my $output = $search->run(
- return_output => 1,
- vars => {
- os_dist => 1500,
- os_x => 523500,
- os_y => 177500,
- },
- );
- like( $output, qr/supersearch.cgi\?.*os_x=523500.*Next.*results/s,
- "os_x retained in next page link" );
- like( $output, qr/supersearch.cgi\?.*os_y=177500.*Next.*results/s,
- "os_y retained in next page link" );
- like( $output, qr/supersearch.cgi\?.*os_dist=1500.*Next.*results/s,
- "os_dist retained in next page link" );
-}
-
-# Test with OSIE co-ords.
-eval { require Geography::NationalGrid::IE; };
-SKIP: {
- skip "Geography::NationalGrid::IE not installed", 3 if $@;
-
- # We must create a new search object after changing the geo_handler
- # in order to force it to create a fresh locator.
- $config->geo_handler( 2 );
- my $search = OpenGuides::SuperSearch->new( config => $config );
-
- foreach my $i ( 1 .. 30 ) {
- OpenGuides::Test->write_data(
- guide => $guide,
- node => "I Made This Place Up
$i",
- osie_x => 100005,
- osie_y => 200005,
- );
- }
-
- my $output = $search->run(
- return_output => 1,
- vars => {
- osie_dist => 1500,
- osie_x => 100000,
- osie_y => 200000,
- },
- );
- like( $output, qr/supersearch.cgi\?.*osie_x=100000.*Next.*results/s,
- "osie_x retained in next page link" );
- like( $output, qr/supersearch.cgi\?.*osie_y=200000.*Next.*results/s,
- "osie_y retained in next page link" );
- like( $output, qr/supersearch.cgi\?.*osie_dist=1500.*Next.*results/s,
- "osie_dist retained in next page link" );
-}
-
-# Test with UTM.
-eval { require Geo::Coordinates::UTM; };
-SKIP: {
- skip "Geo::Coordinates::UTM not installed", 3 if $@;
-
- # We must create a new search object after changing the geo_handler
- # in order to force it to create a fresh locator.
- $config->geo_handler( 3 );
- my $search = OpenGuides::SuperSearch->new( config => $config );
-
- foreach my $i ( 1 .. 30 ) {
- OpenGuides::Test->write_data(
- guide => $guide,
- node => "London Aquarium $i",
- latitude => 51.502,
- longitude => -0.118,
- );
- }
-
- my $output = $search->run(
- return_output => 1,
- vars => {
- latlong_dist => 1500,
- latitude => 51.5,
- longitude => -0.12,
- },
- );
- like( $output, qr/supersearch.cgi\?.*latitude=51.5.*Next.*results/s,
- "latitude retained in next page link" );
- like( $output, qr/supersearch.cgi\?.*longitude=-0.12.*Next.*results/s,
- "longitude retained in next page link" );
- like( $output, qr/supersearch.cgi\?.*latlong_dist=1500.*Next.*results/s,
- "latlong_dist retained in next page link" );
-}
Copied: trunk/t/35_search_two_searches.t (from rev 715,
trunk/t/35_supersearch_two_searches.t)
Deleted: trunk/t/35_supersearch_two_searches.t
===================================================================
--- trunk/t/35_supersearch_two_searches.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/35_supersearch_two_searches.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,135 +0,0 @@
-use strict;
-use CGI::Wiki::Setup::SQLite;
-use OpenGuides::Config;
-use OpenGuides::SuperSearch;
-use Test::More;
-
-eval { require DBD::SQLite; };
-if ( $@ ) {
- plan skip_all => "DBD::SQLite not installed";
-}
-
-eval { require Plucene; };
-if ( $@ ) {
- plan skip_all => "Plucene not installed";
-}
-
-# Strictly speaking we don't need to skip _all_ tests if we don't have
-# the modules below. Revisit this when not in a hurry.
-# We only actually need the former for the National Grid tests and the
-# latter for the UTM tests.
-eval { require Geography::NationalGrid; };
-if ( $@ ) {
- plan skip_all => "Geography::NationalGrid not installed";
-}
-
-eval { require Geo::Coordinates::UTM; };
-if ( $@ ) {
- plan skip_all => "Geo::Coordinates::UTM not installed";
-}
-
-plan tests => 10;
-
-# Clear out the database from any previous runs.
-unlink "t/node.db";
-unlink <t/indexes/*>;
-
-CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } );
-my $config = OpenGuides::Config->new(
- vars => {
- dbtype => "sqlite",
- dbname => "t/node.db",
- indexing_directory => "t/indexes",
- script_name => "wiki.cgi",
- script_url => "http://example.com/",
- site_name => "Test Site",
- template_path => "./templates",
- geo_handler => 1,
- }
-);
-
-# Plucene is the recommended searcher now.
-eval { require CGI::Wiki::Search::Plucene; };
-if ( $@ ) { $config->use_plucene( 0 ) };
-
-my $search = OpenGuides::SuperSearch->new( config => $config );
-
-# Write some data.
-my $wiki = $search->{wiki};
-$wiki->write_node( "Wandsworth Common", "A common.", undef,
- { category => "Parks" } )
- or die "Can't write node";
-$wiki->write_node( "Hammersmith", "A page about Hammersmith." )
- or die "Can't write node";
-
-# Check that the search forgets input search term between invocations.
-$search->run(
- return_output => 1,
- vars => { search => "parks" },
- );
-ok( $search->{search_string}, "search_string set" );
-$search->run(
- return_output => 1,
- );
-ok( !$search->{search_string}, "...and forgotten" );
-
-# Sanity check.
-my (@results, %tt_vars);
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "parks" },
- );
-@results = sort map { $_->{name} } @{ $tt_vars{results} || [] };
-is_deeply( \@results, [ "Wandsworth Common" ],
- "first search returns expected results" );
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "hammersmith" },
- );
-@results = sort map { $_->{name} } @{ $tt_vars{results} || [] };
-is_deeply( \@results, [ "Hammersmith" ],
- "so does second" );
-
-# Check that the search forgets input geodata between invocations.
-# First with British National Grid.
-$search->run(
- return_output => 1,
- vars => { os_x => 500000, os_y => 100000, os_dist => 1000 },
- );
-ok( $search->{x}, "x-coord set" );
-$search->run(
- return_output => 1,
- vars => { search => "foo" },
- );
-ok( !$search->{x}, "...and forgotten" );
-
-# Now with Irish National Grid.
-$config->geo_handler( 2 );
-$search = OpenGuides::SuperSearch->new( config => $config );
-$search->run(
- return_output => 1,
- vars => { osie_x => 100000, osie_y => 200000, osie_dist => 100
},
- );
-ok( $search->{x}, "x-coord set" );
-$search->run(
- return_output => 1,
- vars => { search => "foo" },
- );
-ok( !$search->{x}, "...and forgotten" );
-
-# Now with UTM.
-$config->geo_handler( 3 );
-$config->ellipsoid( "Airy" );
-$search = OpenGuides::SuperSearch->new( config => $config );
-$search->run(
- return_output => 1,
- vars => { latitude => 10, longitude => 0, latlong_dist => 1000
},
- );
-ok( $search->{x}, "x-coord set" );
-$search->run(
- return_output => 1,
- vars => { search => "foo" },
- );
-ok( !$search->{x}, "...and forgotten" );
-
-
Copied: trunk/t/36_search_order.t (from rev 715, trunk/t/36_supersearch_order.t)
Deleted: trunk/t/36_supersearch_order.t
===================================================================
--- trunk/t/36_supersearch_order.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/36_supersearch_order.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,141 +0,0 @@
-use strict;
-use CGI::Wiki::Setup::SQLite;
-use OpenGuides::Config;
-use OpenGuides::SuperSearch;
-use Test::More;
-
-eval { require DBD::SQLite; };
-if ( $@ ) {
- plan skip_all => "DBD::SQLite not installed";
- exit 0;
-}
-
-eval { require CGI::Wiki::Search::Plucene; };
-if ( $@ ) {
- plan skip_all => "Plucene not installed";
- exit 0;
-}
-
-plan tests => 9;
-
-# Clear out the database from any previous runs.
-unlink "t/node.db";
-unlink <t/indexes/*>;
-
-CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } );
-my $config = OpenGuides::Config->new(
- vars => {
- dbtype => "sqlite",
- dbname => "t/node.db",
- indexing_directory => "t/indexes",
- script_name => "wiki.cgi",
- script_url => "http://example.com/",
- site_name => "Test Site",
- template_path => "./templates",
- use_plucene => 1
- }
-);
-
-my $search = OpenGuides::SuperSearch->new( config => $config );
-isa_ok( $search, "OpenGuides::SuperSearch" );
-
-# Write some data.
-my $wiki = $search->{wiki};
-$wiki->write_node( "Parks", "A page about parks." )
- or die "Can't write node";
-$wiki->write_node( "Wandsworth Common", "A common.", undef,
- { category => "Parks" } )
- or die "Can't write node";
-$wiki->write_node( "Kake", "I like walking in parks." )
- or die "Can't write node";
-
-my %tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "parks" },
- );
-foreach my $result ( @{ $tt_vars{results} || [] } ) {
- print "# $result->{name} scores $result->{score}\n";
-}
-my %scores = map { $_->{name} => $_->{score} } @{$tt_vars{results} || []};
-ok( $scores{Kake} < $scores{'Wandsworth Common'},
- "content match scores less than category match" );
-ok( $scores{'Wandsworth Common'} < $scores{Parks},
- "title match scores more than category match" );
-
-# Now test locales.
-$wiki->write_node( "Hammersmith", "A page about Hammersmith." )
- or die "Can't write node";
-$wiki->write_node( "The Gate", "A restaurant.", undef,
- { locale => "Hammersmith" } )
- or die "Can't write node";
-$wiki->write_node( "Kake Pugh", "I live in Hammersmith." )
- or die "Can't write node";
-
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "hammersmith" },
- );
-foreach my $result ( @{ $tt_vars{results} || [] } ) {
- print "# $result->{name} scores $result->{score}\n";
-}
-%scores = map { $_->{name} => $_->{score} } @{$tt_vars{results} || []};
-ok( $scores{'Kake Pugh'} < $scores{'The Gate'},
- "content match scores less than locale match" );
-ok( $scores{'The Gate'} < $scores{Hammersmith},
- "locale match scores less than title match" );
-
-# Check that two words in the title beats one in the title and
-# one in the content.
-$wiki->write_node( "Putney Tandoori", "Indian food" )
- or die "Couldn't write node";
-$wiki->write_node( "Putney", "There is a tandoori restaurant here"
)
- or die "Couldn't write node";
-
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "putney tandoori"
},
- );
-foreach my $result ( @{ $tt_vars{results} || [] } ) {
- print "# $result->{name} scores $result->{score}\n";
-}
-%scores = map { $_->{name} => $_->{score} } @{$tt_vars{results} || []};
-ok( $scores{Putney} < $scores{'Putney Tandoori'},
- "two words in title beats one in title and one in content" );
-
-SKIP: {
- skip "Word proximity not yet taken into account", 1;
-# Check that in an AND match words closer together get higher priority.
-$wiki->write_node( "Spitalfields Market",
- "Mango juice from the Indian stall" )
- or die "Can't write node";
-$wiki->write_node( "Borough Market", "dried mango and real apple
juice" )
- or die "Can't write node";
-
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "mango juice" },
- );
-foreach my $result ( @{ $tt_vars{results} || [] } ) {
- print "# $result->{name} scores $result->{score}\n";
-}
-%scores = map { $_->{name} => $_->{score} } @{$tt_vars{results} || []};
-ok( $scores{'Borough Market'} < $scores{'Spitalfields Market'},
- "words closer together gives higher score" );
-} # end of SKIP
-
-# Check that the number of occurrences of the search term is significant.
-
-$wiki->write_node( "Pub Crawls", "The basic premise of the pub crawl is
to visit a succession of pubs, rather than spending the entire evening or day in a single
establishment. London offers an excellent choice of themes for your pub crawl.",
undef, { category => "Pubs" } ) or die "Can't write node";
-$wiki->write_node( "The Pub", "A pub.", undef, { category =>
"Pubs" } ) or die "Can't write node";
-
-%tt_vars = $search->run(
- return_tt_vars => 1,
- vars => { search => "pub" }
- );
-foreach my $result ( @{ $tt_vars{results} || [] } ) {
- print "# $result->{name} scores $result->{score}\n";
-}
-is( $tt_vars{results}[0]{name}, "Pub Crawls",
- "node with two mentions of search term comes top" );
-ok( $tt_vars{results}[0]{score} > $tt_vars{results}[1]{score},
- "...with a score strictly greater than node with one mention" );
Copied: trunk/t/37_search_summaries.t (from rev 715, trunk/t/37_supersearch_summaries.t)
Deleted: trunk/t/37_supersearch_summaries.t
===================================================================
--- trunk/t/37_supersearch_summaries.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/37_supersearch_summaries.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,48 +0,0 @@
-use strict;
-use CGI::Wiki::Setup::SQLite;
-use OpenGuides::Config;
-use OpenGuides::SuperSearch;
-use Test::More;
-
-eval { require DBD::SQLite; };
-if ( $@ ) {
- plan skip_all => "DBD::SQLite not installed";
-} else {
- plan tests => 2;
-
- # Clear out the database from any previous runs.
- unlink "t/node.db";
- unlink <t/indexes/*>;
-
- CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } );
- my $config = OpenGuides::Config->new(
- vars => {
- dbtype => "sqlite",
- dbname => "t/node.db",
- indexing_directory => "t/indexes",
- script_name => "wiki.cgi",
- script_url => "http://example.com/",
- site_name => "Test Site",
- template_path => "./templates",
- }
- );
-
- # Plucene is the recommended searcher now.
- eval { require CGI::Wiki::Search::Plucene; };
- if ( $@ ) { $config->use_plucene( 0 ) };
-
- my $search = OpenGuides::SuperSearch->new( config => $config );
- isa_ok( $search, "OpenGuides::SuperSearch" );
- my $wiki = $search->wiki;
- $wiki->write_node( "Pub Crawls", "The basic premise of the pub
crawl is to visit a succession of pubs, rather than spending the entire evening or day in
a single establishment. London offers an excellent choice of themes for your pub
crawl.", undef, { category => "Pubs" } ) or die "Can't write
node";
-
- my $output = $search->run(
- return_output => 1,
- vars => { search => "pub" }
- );
- SKIP: {
- skip "TODO: summaries", 1;
- like( $output, qr|<b>pub</b>|i,
- "outputs at least one bolded occurence of 'pub'" );
- } # end of SKIP
-}
Copied: trunk/t/38_search_params.t (from rev 715, trunk/t/38_supersearch_params.t)
Deleted: trunk/t/38_supersearch_params.t
===================================================================
--- trunk/t/38_supersearch_params.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/38_supersearch_params.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,180 +0,0 @@
-use strict;
-use CGI;
-use CGI::Wiki::Setup::SQLite;
-use OpenGuides::Config;
-use OpenGuides::SuperSearch;
-use Test::More;
-
-eval { require DBD::SQLite; };
-if ( $@ ) {
- plan skip_all => "DBD::SQLite not installed";
- exit 0;
-}
-
-eval { require CGI::Wiki::Search::Plucene; };
-if ( $@ ) {
- plan skip_all => "Plucene not installed";
- exit 0;
-}
-
-# Strictly speaking we don't need to skip _all_ tests if we don't have
-# the modules below. Revisit this when not in a hurry.
-# We only actually need them for the tests where lat/long are converted.
-eval { require Geography::NationalGrid; };
-if ( $@ ) {
- plan skip_all => "Geography::NationalGrid not installed";
-}
-
-eval { require Geo::Coordinates::UTM; };
-if ( $@ ) {
- plan skip_all => "Geo::Coordinates::UTM not installed";
-}
-
-plan tests => 19;
-
-# Clear out the database from any previous runs.
-unlink "t/node.db";
-unlink <t/indexes/*>;
-
-CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } );
-my $config = OpenGuides::Config->new(
- vars => {
- dbtype => "sqlite",
- dbname => "t/node.db",
- indexing_directory => "t/indexes",
- script_name => "wiki.cgi",
- script_url => "http://example.com/",
- site_name => "Test Site",
- template_path => "./templates",
- use_plucene => 1,
- geo_handler => 1, # British National Grid
- }
-);
-
-# Check the British National Grid case.
-my $q = CGI->new( "" );
-$q->param( -name => "os_x", -value => 500000 );
-$q->param( -name => "os_y", -value => 200000 );
-$q->param( -name => "os_dist", -value => 500 );
-$q->param( -name => "osie_dist", -value => 600 );
-$q->param( -name => "latlong_dist", -value => 700 );
-my %vars = $q->Vars();
-my $search = OpenGuides::SuperSearch->new( config => $config );
-$search->run( vars => \%vars, return_output => 1 );
-is( $search->{distance_in_metres}, 500,
- "os_dist picked up when OS co-ords given and using British grid" );
-is( $search->{x}, 500000, "...x set from os_x" );
-is( $search->{y}, 200000, "...y set from os_y" );
-
-$q = CGI->new( "" );
-$q->param( -name => "osie_x", -value => 500000 );
-$q->param( -name => "osie_y", -value => 200000 );
-$q->param( -name => "os_dist", -value => 500 );
-$q->param( -name => "osie_dist", -value => 600 );
-$q->param( -name => "latlong_dist", -value => 700 );
-%vars = $q->Vars();
-$search = OpenGuides::SuperSearch->new( config => $config );
-$search->run( vars => \%vars, return_output => 1 );
-ok( !defined $search->{distance_in_metres},
- "OSIE co-ords ignored when using British grid" );
-
-$q = CGI->new( "" );
-$q->param( -name => "latitude", -value => 51 );
-$q->param( -name => "longitude", -value => 1 );
-$q->param( -name => "os_dist", -value => 500 );
-$q->param( -name => "osie_dist", -value => 600 );
-$q->param( -name => "latlong_dist", -value => 700 );
-%vars = $q->Vars();
-$search = OpenGuides::SuperSearch->new( config => $config );
-$search->run( vars => \%vars, return_output => 1 );
-is( $search->{distance_in_metres}, 700,
- "latlong_dist picked up when lat/long given and using British grid" );
-ok( defined $search->{x}, "...x set" );
-ok( defined $search->{y}, "...y set" );
-
-
-# Check the Irish National Grid case.
-$config->geo_handler( 2 );
-
-$q = CGI->new( "" );
-$q->param( -name => "osie_x", -value => 500000 );
-$q->param( -name => "osie_y", -value => 200000 );
-$q->param( -name => "os_dist", -value => 500 );
-$q->param( -name => "osie_dist", -value => 600 );
-$q->param( -name => "latlong_dist", -value => 700 );
-%vars = $q->Vars();
-$search = OpenGuides::SuperSearch->new( config => $config );
-$search->run( vars => \%vars, return_output => 1 );
-is( $search->{distance_in_metres}, 600,
- "osie_dist picked up when OS co-ords given and using Irish grid" );
-is( $search->{x}, 500000, "...x set from osie_x" );
-is( $search->{y}, 200000, "...y set from osie_y" );
-
-$q = CGI->new( "" );
-$q->param( -name => "os_x", -value => 500000 );
-$q->param( -name => "os_y", -value => 200000 );
-$q->param( -name => "os_dist", -value => 500 );
-$q->param( -name => "osie_dist", -value => 600 );
-$q->param( -name => "latlong_dist", -value => 700 );
-%vars = $q->Vars();
-$search = OpenGuides::SuperSearch->new( config => $config );
-$search->run( vars => \%vars, return_output => 1 );
-ok( !defined $search->{distance_in_metres},
- "OS co-ords ignored when using Irish grid" );
-
-$q = CGI->new( "" );
-$q->param( -name => "latitude", -value => 55 );
-$q->param( -name => "longitude", -value => -5 );
-$q->param( -name => "os_dist", -value => 500 );
-$q->param( -name => "osie_dist", -value => 600 );
-$q->param( -name => "latlong_dist", -value => 700 );
-%vars = $q->Vars();
-$search = OpenGuides::SuperSearch->new( config => $config );
-$search->run( vars => \%vars, return_output => 1 );
-is( $search->{distance_in_metres}, 700,
- "latlong_dist picked up when lat/long given and using Irish grid" );
-ok( defined $search->{x}, "...x set" );
-ok( defined $search->{y}, "...y set" );
-
-
-# Check the UTM case.
-$config->geo_handler( 3 );
-$config->ellipsoid( "Airy" );
-
-$q = CGI->new( "" );
-$q->param( -name => "os_x", -value => 500000 );
-$q->param( -name => "os_y", -value => 200000 );
-$q->param( -name => "os_dist", -value => 500 );
-$q->param( -name => "osie_dist", -value => 600 );
-$q->param( -name => "latlong_dist", -value => 700 );
-%vars = $q->Vars();
-$search = OpenGuides::SuperSearch->new( config => $config );
-$search->run( vars => \%vars, return_output => 1 );
-ok( !defined $search->{distance_in_metres},
- "OS co-ords ignored when using UTM" );
-
-$q = CGI->new( "" );
-$q->param( -name => "osie_x", -value => 500000 );
-$q->param( -name => "osie_y", -value => 200000 );
-$q->param( -name => "os_dist", -value => 500 );
-$q->param( -name => "osie_dist", -value => 600 );
-$q->param( -name => "latlong_dist", -value => 700 );
-%vars = $q->Vars();
-$search = OpenGuides::SuperSearch->new( config => $config );
-$search->run( vars => \%vars, return_output => 1 );
-ok( !defined $search->{distance_in_metres},
- "OSIE co-ords ignored when using UTM" );
-
-$q = CGI->new( "" );
-$q->param( -name => "latitude", -value => 51 );
-$q->param( -name => "longitude", -value => 1 );
-$q->param( -name => "os_dist", -value => 500 );
-$q->param( -name => "osie_dist", -value => 600 );
-$q->param( -name => "latlong_dist", -value => 700 );
-%vars = $q->Vars();
-$search = OpenGuides::SuperSearch->new( config => $config );
-$search->run( vars => \%vars, return_output => 1 );
-is( $search->{distance_in_metres}, 700,
- "latlong_dist picked up when lat/long given and using UTM" );
-ok( defined $search->{x}, "...x set" );
-ok( defined $search->{y}, "...y set" );
Copied: trunk/t/39_search_form.t (from rev 715, trunk/t/39_supersearch_form.t)
Deleted: trunk/t/39_supersearch_form.t
===================================================================
--- trunk/t/39_supersearch_form.t 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/t/39_supersearch_form.t 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,121 +0,0 @@
-use strict;
-use CGI::Wiki::Setup::SQLite;
-use OpenGuides::SuperSearch;
-use OpenGuides::Test;
-use Test::More;
-
-eval { require DBD::SQLite; };
-if ( $@ ) {
- plan skip_all => "DBD::SQLite not installed";
-}
-
-eval { require Plucene; };
-if ( $@ ) {
- plan skip_all => "Plucene not installed";
-}
-
-eval { require Test::HTML::Content; };
-if ( $@ ) {
- plan skip_all => "Test::HTML::Content not installed";
- exit 0;
-}
-
-# Strictly speaking we don't need to skip _all_ tests if we don't have
-# the modules below. Revisit this when not in a hurry.
-# We only actually need the former for the National Grid tests and the
-# latter for the UTM tests.
-eval { require Geography::NationalGrid; };
-if ( $@ ) {
- plan skip_all => "Geography::NationalGrid not installed";
-}
-
-eval { require Geo::Coordinates::UTM; };
-if ( $@ ) {
- plan skip_all => "Geo::Coordinates::UTM not installed";
-}
-
-plan tests => 27;
-
-# Clear out the database from any previous runs.
-unlink "t/node.db";
-unlink <t/indexes/*>;
-
-CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } );
-my $config = OpenGuides::Test->make_basic_config;
-$config->use_plucene( 1 );
-
-# British National Grid guides should have os and latlong search fields.
-my $search = OpenGuides::SuperSearch->new( config => $config );
-my $output = $search->run( return_output => 1 );
-# Strip Content-Type header to stop Test::HTML::Content getting confused.
-$output =~ s/^Content-Type.*[\r\n]+//m;
-
-Test::HTML::Content::tag_ok( $output, "input", { name => "os_dist"
},
- "search page includes os_dist input with BNG" );
-Test::HTML::Content::tag_ok( $output, "input", { name => "os_x"
},
- "...and os_x" );
-Test::HTML::Content::tag_ok( $output, "input", { name => "os_y"
},
- "...and os_y" );
-Test::HTML::Content::tag_ok( $output, "input", { name =>
"latlong_dist" },
- "...and latlong_dist" );
-Test::HTML::Content::tag_ok( $output, "input", { name =>
"latitude" },
- "...and latitude" );
-Test::HTML::Content::tag_ok( $output, "input", { name =>
"longitude" },
- "...and longitude" );
-Test::HTML::Content::no_tag( $output, "input", { name =>
"osie_dist" },
- "...but not osie_dist" );
-Test::HTML::Content::no_tag( $output, "input", { name => "osie_x"
},
- "...nor osie_x" );
-Test::HTML::Content::no_tag( $output, "input", { name => "osie_y"
},
- "...nor osie_y" );
-
-# Irish National Grid guides should have osie and latlong.
-$config->geo_handler( 2 );
-$search = OpenGuides::SuperSearch->new( config => $config );
-$output = $search->run( return_output => 1 );
-$output =~ s/^Content-Type.*[\r\n]+//m;
-
-Test::HTML::Content::tag_ok( $output, "input", { name =>
"osie_dist" },
- "search page includes os_dist input with ING" );
-Test::HTML::Content::tag_ok( $output, "input", { name => "osie_x"
},
- "...and osie_x" );
-Test::HTML::Content::tag_ok( $output, "input", { name => "osie_y"
},
- "...and osie_y" );
-Test::HTML::Content::tag_ok( $output, "input", { name =>
"latlong_dist" },
- "...and latlong_dist" );
-Test::HTML::Content::tag_ok( $output, "input", { name =>
"latitude" },
- "...and latitude" );
-Test::HTML::Content::tag_ok( $output, "input", { name =>
"longitude" },
- "...and longitude" );
-Test::HTML::Content::no_tag( $output, "input", { name => "os_dist"
},
- "...but not os_dist" );
-Test::HTML::Content::no_tag( $output, "input", { name => "os_x"
},
- "...nor os_x" );
-Test::HTML::Content::no_tag( $output, "input", { name => "os_y"
},
- "...nor os_y" );
-
-# UTM guides should have latitude/longitude/latlong_dist only.
-$config->geo_handler( 3 );
-$config->ellipsoid( "Airy" );
-$search = OpenGuides::SuperSearch->new( config => $config );
-$output = $search->run( return_output => 1 );
-$output =~ s/^Content-Type.*[\r\n]+//m;
-
-Test::HTML::Content::tag_ok( $output, "input", { name =>
"latlong_dist" },
- "includes latlong_dist with UTM" );
-Test::HTML::Content::tag_ok( $output, "input", { name =>
"latitude" },
- "...and latitude" );
-Test::HTML::Content::tag_ok( $output, "input", { name =>
"longitude" },
- "...and longitude" );
-Test::HTML::Content::no_tag( $output, "input", { name => "os_dist"
},
- "...but not os_dist" );
-Test::HTML::Content::no_tag( $output, "input", { name => "os_x"
},
- "...nor os_x" );
-Test::HTML::Content::no_tag( $output, "input", { name => "os_y"
},
- "...nor os_y" );
-Test::HTML::Content::no_tag( $output, "input", { name => "osie_x"
},
- "...but not osie_x" );
-Test::HTML::Content::no_tag( $output, "input", { name => "osie_y"
},
- "...nor osie_y" );
-Test::HTML::Content::no_tag( $output, "input", { name =>
"osie_dist" },
- "...nor osie_dist" );
Modified: trunk/templates/differences.tt
===================================================================
--- trunk/templates/differences.tt 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/templates/differences.tt 2005-11-24 20:01:09 UTC (rev 716)
@@ -32,7 +32,7 @@
<a href="[% cgi_url %]?action=list_all_versions;id=[% node_param %]">List
all versions</a><br />
<p>
-<form action="supersearch.cgi" method="get">
+<form action="search.cgi" method="get">
<input type="text" size="50" name="search" />
<input type="submit" name="Go" value="Search"
class="form_button" />
</form>
Modified: trunk/templates/footer.tt
===================================================================
--- trunk/templates/footer.tt 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/templates/footer.tt 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,7 +1,7 @@
<br clear="all" />
<div id="search_form">
- <form action="supersearch.cgi" method="get">
+ <form action="search.cgi" method="get">
<strong><label for="search">Search [% site_name
%]:</label></strong> <input type="text" size="50"
name="search" id="search" value="Search text"
onclick="this.value=''" />
<input type="submit" name="Go" value="Go"
id="go" class="form_button" />
</form>
Modified: trunk/templates/navbar.tt
===================================================================
--- trunk/templates/navbar.tt 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/templates/navbar.tt 2005-11-24 20:01:09 UTC (rev 716)
@@ -41,13 +41,13 @@
<ul>
<li>
- <form method="post" action="supersearch.cgi"
enctype="application/x-www-form-urlencoded">
+ <form method="post" action="search.cgi"
enctype="application/x-www-form-urlencoded">
<input type="hidden" name="action"
value="search" />
<input type="text" size="15" name="search"
id="nav_search" value="Search text"
onfocus="this.value=''" /> <label for="nav_search"
class="hidden">Search text</label>
<input type="submit" value="Go"
class="form_button" />
</form>
</li>
- <li><a href="supersearch.cgi">Advanced
Search</a></li>
+ <li><a href="search.cgi">Advanced Search</a></li>
</ul>
[% UNLESS not_editable %]
Modified: trunk/templates/node.tt
===================================================================
--- trunk/templates/node.tt 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/templates/node.tt 2005-11-24 20:01:09 UTC (rev 716)
@@ -39,7 +39,7 @@
[% IF coord_field_1_value AND coord_field_2_value %]
<br clear="all" />
<div id="find_within_distance">
- <form action="supersearch.cgi">
+ <form action="search.cgi">
<label for="distance">Find all things within</label>
<select name="[% dist_field %]" id="distance">
<option value="500">500 metres</option>
Copied: trunk/templates/search.tt (from rev 715, trunk/templates/supersearch.tt)
===================================================================
--- trunk/templates/supersearch.tt 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/templates/search.tt 2005-11-24 20:01:09 UTC (rev 716)
@@ -0,0 +1,111 @@
+[% IF search_terms %]
+[% node_name = "Search results for $search_terms" %]
+[% ELSE %]
+[% node_name = "Search" %]
+[% END %]
+[% INCLUDE header.tt %]
+[% INCLUDE banner.tt %]
+<div id="content">
+[% INCLUDE navbar.tt %]
+<div id="maincontent">
+ [% IF search_terms %]
+ <h2>Search Results for <em>[% search_terms %]</em></h2>
+ [% IF results.size %]
+ <h3>[% total_num %] matches found, showing [% first_num %] - [% last_num
%]</h3>
+ [% END %]
+ [% ELSE %]
+ <h2>Search [% site_name %]</h2>
+ [% END %]
+
+ <p><small>
+ Version [% ss_version %]. See the
+ <a href="[% ss_info_url %]">information page</a> for help and
more details.
+ </small></p>
+
+ <form method="get" action="search.cgi">
+ <table border="1">
+ <tr>
+ <th>
+ <label for="search_upper">Pages containing
text:</label>
+ </th>
+ <td>
+ <input type="text" name="search" value="[% IF
search_terms %][% search_terms %][% END %]" size="50"
maxlength="80" id="search_upper" />
+ </td>
+ </tr>
+ <tr>
+ <th>Location:</th>
+ <td>
+ [% IF coord_field_1 != 'latitude' %]
+ <p>
+ within <input type="text" name="[% dist_field %]"
value="[% dist %]" size="5" maxlength="5" /> metres
of<br />
+ [% coord_field_1_name %] <input type="text" name="[%
coord_field_1 %]" value="[% coord_field_1_value %]" size="10"
maxlength="10" />,<br />
+ [% coord_field_2_name %] <input type="text" name="[%
coord_field_2 %]" value="[% coord_field_2_value %]" size="10"
maxlength="10" />
+ </p>
+ [% END %]
+ <p>
+ within <input type="text" name="latlong_dist"
value="[% dist %]" size="5" maxlength="5" /> metres
of<br />
+ latitude (decimal) <input type="text" name="latitude"
value="[% latitude %]" size="10" maxlength="10" />,<br
/>
+ longitude (decimal) <input type="text"
name="longitude" value="[% longitude %]" size="10"
maxlength="10" />
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2" align="right">
+ <input type="submit" name="go"
class="form_button" value="Go" />
+ </td>
+ </tr>
+ </table>
+ </form>
+
+ [% IF search_terms OR dist %]
+
+ <hr />
+
+ [% IF results.size %]
+
+ <ol start="[% first_num %]">
+ [% FOREACH result = results %]
+ <li>
+ <a href="[% result.url %]"><b>[% result.name
%]</b></a> (score: [% result.score %])
+ [% IF result.distance %]
+ ([% result.distance %] metres away)
+ [% END %][% IF result.summary %]
+ <div class="hit_summary">
+ [% result.summary %]
+ </div>[% END %]
+ </li>
+ [% END %]
+ </ol>
+
+ <p>
+ Matches [% first_num %] - [% last_num %] of [% total_num %].
+ [% IF (first_num > 20) %]
+ <a href="search.cgi?search=[% search_terms %]&next=[% first_num - 21
%]">Previous 20 results</a>
+ [% END %]
+ [% IF ((first_num > 20) and next_page_startpos) %]
+ /
+ [% END %]
+ [% IF next_page_startpos %]
+ <a href="search.cgi?search=[% search_terms %];[% dist_field %]=[% dist
%];[% coord_field_1 %]=[% coord_field_1_value %];[% coord_field_2 %]=[%
coord_field_2_value %];next=[% next_page_startpos %]">Next
+ [% IF ((total_num - last_num >= 20)) %]
+ 20
+ [% ELSE %]
+ [% total_num - last_num %]
+ [% END %]
+ results</a>
+ [% END %]
+ </p>
+
+ [% ELSE %]
+ <h2>No Items Matched</h2>
+ [% END %]
+
+ <form method="get" action="search.cgi">
+ <label for="search_lower">Search:</label>
+ <input type="text" name="search" id="search_lower"
value="[% search_terms %]" size="50" maxlength="80"
value="Search text" onclick="this.value=''" />
+ <input type="submit" name="go" class="form_button"
value="Go" />
+ </form>
+ [% END %]
+
+</div>
+[% INCLUDE footer.tt %]
Deleted: trunk/templates/supersearch.tt
===================================================================
--- trunk/templates/supersearch.tt 2005-11-21 08:54:03 UTC (rev 715)
+++ trunk/templates/supersearch.tt 2005-11-24 20:01:09 UTC (rev 716)
@@ -1,111 +0,0 @@
-[% IF search_terms %]
-[% node_name = "Search results for $search_terms" %]
-[% ELSE %]
-[% node_name = "Search" %]
-[% END %]
-[% INCLUDE header.tt %]
-[% INCLUDE banner.tt %]
-<div id="content">
-[% INCLUDE navbar.tt %]
-<div id="maincontent">
- [% IF search_terms %]
- <h2>Search Results for <em>[% search_terms %]</em></h2>
- [% IF results.size %]
- <h3>[% total_num %] matches found, showing [% first_num %] - [% last_num
%]</h3>
- [% END %]
- [% ELSE %]
- <h2>Search [% site_name %]</h2>
- [% END %]
-
- <p><small>
- Version [% ss_version %]. See the
- <a href="[% ss_info_url %]">information page</a> for help and
more details.
- </small></p>
-
- <form method="get" action="supersearch.cgi">
- <table border="1">
- <tr>
- <th>
- <label for="search_upper">Pages containing
text:</label>
- </th>
- <td>
- <input type="text" name="search" value="[% IF
search_terms %][% search_terms %][% END %]" size="50"
maxlength="80" id="search_upper" />
- </td>
- </tr>
- <tr>
- <th>Location:</th>
- <td>
- [% IF coord_field_1 != 'latitude' %]
- <p>
- within <input type="text" name="[% dist_field %]"
value="[% dist %]" size="5" maxlength="5" /> metres
of<br />
- [% coord_field_1_name %] <input type="text" name="[%
coord_field_1 %]" value="[% coord_field_1_value %]" size="10"
maxlength="10" />,<br />
- [% coord_field_2_name %] <input type="text" name="[%
coord_field_2 %]" value="[% coord_field_2_value %]" size="10"
maxlength="10" />
- </p>
- [% END %]
- <p>
- within <input type="text" name="latlong_dist"
value="[% dist %]" size="5" maxlength="5" /> metres
of<br />
- latitude (decimal) <input type="text" name="latitude"
value="[% latitude %]" size="10" maxlength="10" />,<br
/>
- longitude (decimal) <input type="text"
name="longitude" value="[% longitude %]" size="10"
maxlength="10" />
- </p>
- </td>
- </tr>
- <tr>
- <td colspan="2" align="right">
- <input type="submit" name="go"
class="form_button" value="Go" />
- </td>
- </tr>
- </table>
- </form>
-
- [% IF search_terms OR dist %]
-
- <hr />
-
- [% IF results.size %]
-
- <ol start="[% first_num %]">
- [% FOREACH result = results %]
- <li>
- <a href="[% result.url %]"><b>[% result.name
%]</b></a> (score: [% result.score %])
- [% IF result.distance %]
- ([% result.distance %] metres away)
- [% END %][% IF result.summary %]
- <div class="hit_summary">
- [% result.summary %]
- </div>[% END %]
- </li>
- [% END %]
- </ol>
-
- <p>
- Matches [% first_num %] - [% last_num %] of [% total_num %].
- [% IF (first_num > 20) %]
- <a href="supersearch.cgi?search=[% search_terms %]&next=[% first_num
- 21 %]">Previous 20 results</a>
- [% END %]
- [% IF ((first_num > 20) and next_page_startpos) %]
- /
- [% END %]
- [% IF next_page_startpos %]
- <a href="supersearch.cgi?search=[% search_terms %];[% dist_field %]=[%
dist %];[% coord_field_1 %]=[% coord_field_1_value %];[% coord_field_2 %]=[%
coord_field_2_value %];next=[% next_page_startpos %]">Next
- [% IF ((total_num - last_num >= 20)) %]
- 20
- [% ELSE %]
- [% total_num - last_num %]
- [% END %]
- results</a>
- [% END %]
- </p>
-
- [% ELSE %]
- <h2>No Items Matched</h2>
- [% END %]
-
- <form method="get" action="supersearch.cgi">
- <label for="search_lower">Search:</label>
- <input type="text" name="search" id="search_lower"
value="[% search_terms %]" size="50" maxlength="80"
value="Search text" onclick="this.value=''" />
- <input type="submit" name="go" class="form_button"
value="Go" />
- </form>
- [% END %]
-
-</div>
-[% INCLUDE footer.tt %]