]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Search.pm
added support for using alternate context-specific spell-check dictionaries w/ sample...
[working/Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Search.pm
1 package OpenILS::Application::Search;
2 use OpenILS::Application;
3 use base qw/OpenILS::Application/;
4 use strict; use warnings;
5 use OpenSRF::Utils::JSON;
6 use OpenSRF::Utils::Logger qw(:logger);
7
8 use OpenILS::Utils::Fieldmapper;
9 use OpenILS::Utils::ModsParser;
10 use OpenSRF::Utils::SettingsClient;
11 use OpenSRF::Utils::Cache;
12
13 use OpenILS::Application::Search::Biblio;
14 use OpenILS::Application::Search::Authority;
15 use OpenILS::Application::Search::Z3950;
16 use OpenILS::Application::Search::Zips;
17 use OpenILS::Application::Search::CNBrowse;
18 use OpenILS::Application::Search::Serial;
19
20
21 use OpenILS::Application::AppUtils;
22
23 use Time::HiRes qw(time);
24 use OpenSRF::EX qw(:try);
25
26 use Text::Aspell; 
27
28 # Houses generic search utilites 
29
30 sub initialize {
31         OpenILS::Application::Search::Z3950->initialize();
32         OpenILS::Application::Search::Zips->initialize();
33         OpenILS::Application::Search::Biblio->initialize();
34 }
35
36 sub child_init {
37         OpenILS::Application::Search::Z3950->child_init;
38 }
39         
40
41
42 # ------------------------------------------------------------------
43 # Create custom dictionaries like so:
44 # aspell --lang=en create  master ./oils_authority.dict < /tmp/words
45 # where /tmp/words is a space separated list of words
46 # ------------------------------------------------------------------
47
48 __PACKAGE__->register_method(
49         method  => "spellcheck",
50         api_name        => "open-ils.search.spellcheck",
51     signature => {
52         desc   => 'Returns alternate spelling suggestions',
53         param  => [
54             {name => 'phrase', desc => 'Word or phrase to return alternate spelling suggestions for', type => 'string'},
55             {name => 'Dictionary class', desc => 'Used to specify an alternate configured dictiony to use for suggestions', type => 'string'},
56         ],
57         return => {
58             desc => q/
59                 Suggestions for each word in the phrase.  
60                 [ { word : original_word, suggestions : [sug1, sug2, ...], found : 1 if the word was found in the dictionary, 0 otherwise }, ... ]
61             /,
62             type => 'array', 
63         }
64     }
65 );
66
67 my $speller = Text::Aspell->new();
68
69 sub spellcheck {
70         my( $self, $client, $phrase, $class ) = @_;
71
72         my $conf = OpenSRF::Utils::SettingsClient->new;
73     $class ||= 'default';
74
75     my @conf_path = (apps => 'open-ils.search' => app_settings => spelling_dictionary => $class);
76     push(@conf_path, $class) if $class;
77
78         if( my $dict = $conf->config_value(@conf_path) ) {
79                 $speller->set_option('master', $dict);
80                 $logger->debug("spelling dictionary set to $dict");
81         }
82
83         my @resp;
84         return \@resp unless $phrase;
85
86         for my $word (split(/\s+/,$phrase) ) {
87
88         my @suggestions = $speller->suggest($word);
89         my @trimmed;
90
91         for my $sug (@suggestions) {
92
93             # suggestion matches alternate case of original word
94             next if lc($sug) eq lc($word); 
95
96             # suggestion matches alternate case of already suggested word
97             next if grep { lc($sug) eq lc($_) } @trimmed;
98
99             push(@trimmed, $sug);
100         }
101
102         # remove alternate-cased duplicates and versions of the origin word
103         @suggestions = grep { lc($_) ne $word } @suggestions;
104         my %sugs = map { lc($_) => 1 } @suggestions;
105
106                 push( @resp, 
107                         {
108                                 word => $word, 
109                                 suggestions => (@trimmed) ? [@trimmed] : undef,
110                 found => $speller->check($word)
111                         } 
112                 ); 
113         }
114         return \@resp;
115 }
116
117
118
119 1;