added support for using alternate context-specific spell-check dictionaries w/ sample...
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 29 Mar 2010 20:45:57 +0000 (20:45 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 29 Mar 2010 20:45:57 +0000 (20:45 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@16050 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/examples/opensrf.xml.example
Open-ILS/src/perlmods/OpenILS/Application/Search.pm

index 951f194..20fbdc7 100644 (file)
@@ -390,6 +390,20 @@ vim:et:ts=4:sw=4:
                     <marc_html_xsl>oilsMARC21slim2HTML.xsl</marc_html_xsl>
                     <marc_html_xsl_slim>oilsMARC21slim2HTMLslim.xsl</marc_html_xsl_slim>
 
+                    <spelling_dictionary>
+                        <!-- 
+                            Optionally configure different dictionaries depending on search context.  
+                            If no dictionaries are defined, the default Aspell dictionary is used.
+                        -->
+                        <!--
+                        <default>LOCALSTATEDIR/data/default_dict.txt</default>
+                        <title>LOCALSTATEDIR/data/title_dict.txt</title>
+                        <author>LOCALSTATEDIR/data/author_dict.txt</author>
+                        <subject>LOCALSTATEDIR/data/subject_dict.txt</subject>
+                        <series>LOCALSTATEDIR/data/series_dict.txt</series>
+                        -->
+                    </spelling_dictionary>
+
                     <!-- Default to using staged search -->
                     <use_staged_search>true</use_staged_search>
 
index 6f33951..3e7d15d 100644 (file)
@@ -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)
                        } 
                ); 
        }