From 2f37bc763fcc58df65ed6b40e619b49309e32462 Mon Sep 17 00:00:00 2001 From: erickson Date: Mon, 29 Mar 2010 20:45:57 +0000 Subject: [PATCH] added support for using alternate context-specific spell-check dictionaries w/ sample config. now de-duping suggestions that only differ by case. added a new boolean value to the response object to indicate if the original word was found in the dictionary, but still return alternate suggestions git-svn-id: svn://svn.open-ils.org/ILS/trunk@16050 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/examples/opensrf.xml.example | 14 +++++++ .../src/perlmods/OpenILS/Application/Search.pm | 49 +++++++++++++++++++--- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/Open-ILS/examples/opensrf.xml.example b/Open-ILS/examples/opensrf.xml.example index 951f194d12..20fbdc71a0 100644 --- a/Open-ILS/examples/opensrf.xml.example +++ b/Open-ILS/examples/opensrf.xml.example @@ -390,6 +390,20 @@ vim:et:ts=4:sw=4: oilsMARC21slim2HTML.xsl oilsMARC21slim2HTMLslim.xsl + + + + + true diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Search.pm b/Open-ILS/src/perlmods/OpenILS/Application/Search.pm index 6f33951beb..3e7d15d1e6 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Search.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Search.pm @@ -47,28 +47,67 @@ sub child_init { __PACKAGE__->register_method( method => "spellcheck", - api_name => "open-ils.search.spellcheck"); + api_name => "open-ils.search.spellcheck", + signature => { + desc => 'Returns alternate spelling suggestions', + param => [ + {name => 'phrase', desc => 'Word or phrase to return alternate spelling suggestions for', type => 'string'}, + {name => 'Dictionary class', desc => 'Used to specify an alternate configured dictiony to use for suggestions', type => 'string'}, + ], + return => { + desc => q/ + Suggestions for each word in the phrase. + [ { word : original_word, suggestions : [sug1, sug2, ...], found : 1 if the word was found in the dictionary, 0 otherwise }, ... ] + /, + type => 'array', + } + } +); my $speller = Text::Aspell->new(); sub spellcheck { - my( $self, $client, $phrase ) = @_; + my( $self, $client, $phrase, $class ) = @_; my $conf = OpenSRF::Utils::SettingsClient->new; + $class ||= 'default'; - if( my $dict = $conf->config_value( - "apps", "open-ils.search", "app_settings", "spelling_dictionary")) { + my @conf_path = (apps => 'open-ils.search' => app_settings => spelling_dictionary => $class); + push(@conf_path, $class) if $class; + + if( my $dict = $conf->config_value(@conf_path) ) { $speller->set_option('master', $dict); $logger->debug("spelling dictionary set to $dict"); } my @resp; return \@resp unless $phrase; + for my $word (split(/\s+/,$phrase) ) { + + my @suggestions = $speller->suggest($word); + my @trimmed; + + for my $sug (@suggestions) { + + # suggestion matches alternate case of original word + next if lc($sug) eq lc($word); + + # suggestion matches alternate case of already suggested word + next if grep { lc($sug) eq lc($_) } @trimmed; + + push(@trimmed, $sug); + } + + # remove alternate-cased duplicates and versions of the origin word + @suggestions = grep { lc($_) ne $word } @suggestions; + my %sugs = map { lc($_) => 1 } @suggestions; + push( @resp, { word => $word, - suggestions => ($speller->check($word)) ? undef : [$speller->suggest($word)] + suggestions => (@trimmed) ? [@trimmed] : undef, + found => $speller->check($word) } ); } -- 2.11.0