]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Search/Authority.pm
Whitespace. gah.
[working/Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Search / Authority.pm
1 package OpenILS::Application::Search::Authority;
2 use base qw/OpenILS::Application/;
3 use strict; use warnings;
4
5 use OpenILS::Utils::Fieldmapper;
6 use OpenILS::Application::AppUtils;
7 use XML::LibXML;
8 use XML::LibXSLT;
9 use OpenILS::Utils::Editor q/:funcs/;
10 use OpenSRF::Utils::Logger qw/$logger/;
11
12 use OpenSRF::Utils::JSON;
13
14 use Time::HiRes qw(time);
15 use OpenSRF::EX qw(:try);
16 use Digest::MD5 qw(md5_hex);
17
18 my $cache;
19
20
21 sub validate_authority {
22         my $self = shift;
23         my $client = shift;
24
25         my $session = OpenSRF::AppSession->create("open-ils.storage");
26         return $session->request( 'open-ils.storage.authority.validate.tag' => @_ )->gather(1);
27 }
28 __PACKAGE__->register_method(
29         method          => "validate_authority",
30         api_name        => "open-ils.search.authority.validate.tag",
31         argc            => 4, 
32         note            => "Validates authority data from existing controlled terms",
33 );              
34
35 sub validate_authority_return_records_by_id {
36         my $self = shift;
37         my $client = shift;
38
39         my $session = OpenSRF::AppSession->create("open-ils.storage");
40         return $session->request( 'open-ils.storage.authority.validate.tag.id_list' => @_ )->gather(1);
41 }
42 __PACKAGE__->register_method(
43         method          => "validate_authority_return_records_by_id",
44         api_name        => "open-ils.search.authority.validate.tag.id_list",
45         argc            => 4, 
46         note            => "Validates authority data from existing controlled terms",
47 );              
48
49 sub search_authority {
50         my $self = shift;
51         my $client = shift;
52
53         my $session = OpenSRF::AppSession->create("open-ils.storage");
54         return $session->request( 'open-ils.storage.authority.search.marc.atomic' => @_ )->gather(1);
55 }
56 __PACKAGE__->register_method(
57         method          => "search_authority",
58         api_name        => "open-ils.search.authority.fts",
59         argc            => 2, 
60         note            => "Searches authority data for existing controlled terms and crossrefs",
61 );              
62
63
64 sub crossref_authority {
65         my $self = shift;
66         my $client = shift;
67         my $class = shift;
68         my $term = shift;
69         my $limit = shift || 10;
70
71         my $session = OpenSRF::AppSession->create("open-ils.storage");
72
73         # Avoid generating spurious errors for more granular indexes, like author|personal
74         $class =~ s/^(.*?)\|.*?$/$1/;
75
76         $logger->info("authority xref search for $class=$term, limit=$limit");
77         my $fr = $session->request(
78                 "open-ils.storage.authority.$class.see_from.controlled.atomic",$term, $limit)->gather(1);
79         my $al = $session->request(
80                 "open-ils.storage.authority.$class.see_also_from.controlled.atomic",$term, $limit)->gather(1);
81
82         my $data = _auth_flatten( $term, $fr, $al, 1 );
83
84         return $data;
85 }
86
87 sub _auth_flatten {
88         my $term = shift;
89         my $fr = shift;
90         my $al = shift;
91         my $limit = shift;
92
93         my %hash = ();
94         for my $x (@$fr) {
95                 my $string = $$x[0];
96                 for my $i (1..10) {
97                         last unless ($$x[$i]);
98                         if ($string =~ /\W$/o) {
99                                 $string .= ' '.$$x[$i];
100                         } else {
101                                 $string .= ' -- '.$$x[$i];
102                         }
103                 }
104                 next if (lc($string) eq lc($term));
105                 $hash{$string}++;
106                 $hash{$string}++ if (lc($$x[0]) eq lc($term));
107         }
108         my $from = [keys %hash]; #[ sort { $hash{$b} <=> $hash{$a} || $a cmp $b } keys %hash ];
109
110 #       $from = [ @$from[0..4] ] if $limit;
111
112         %hash = ();
113         for my $x (@$al) {
114                 my $string = $$x[0];
115                 for my $i (1..10) {
116                         last unless ($$x[$i]);
117                         if ($string =~ /\W$/o) {
118                                 $string .= ' '.$$x[$i];
119                         } else {
120                                 $string .= ' -- '.$$x[$i];
121                         }
122                 }
123                 next if (lc($string) eq lc($term));
124                 $hash{$string}++;
125                 $hash{$string}++ if (lc($$x[0]) eq lc($term));
126         }
127         my $also = [keys %hash]; #[ sort { $hash{$b} <=> $hash{$a} || $a cmp $b } keys %hash ];
128
129 #       $also = [ @$also[0..4] ] if $limit;
130
131         #warn Dumper( { from => $from, also => $also } );
132
133         return { from => $from, also => $also };
134 }
135
136 __PACKAGE__->register_method(
137         method          => "crossref_authority",
138         api_name        => "open-ils.search.authority.crossref",
139         argc            => 2, 
140         note            => "Searches authority data for existing controlled terms and crossrefs",
141 );              
142
143 __PACKAGE__->register_method(
144         #method         => "new_crossref_authority_batch",
145         method          => "crossref_authority_batch2",
146         api_name        => "open-ils.search.authority.crossref.batch",
147         argc            => 1, 
148         note            => <<"  NOTE");
149         Takes an array of class,term pair sub-arrays and performs an authority lookup for each
150
151         PARAMS( [ ["subject", "earth"], ["author","shakespeare"] ] );
152
153         Returns an object like so:
154         {
155                 "classname" : {
156                         "term" : { "from" : [ ...], "also" : [...] }
157                         "term2" : { "from" : [ ...], "also" : [...] }
158                 }
159         }
160         NOTE
161
162 sub new_crossref_authority_batch {
163         my( $self, $client, $reqs ) = @_;
164
165         my $response = {};
166         my $lastr = [];
167         my $session = OpenSRF::AppSession->create("open-ils.storage");
168
169         for my $req (@$reqs) {
170
171                 my $class = $req->[0];
172                 my $term = $req->[1];
173                 next unless $class and $term;
174                 $logger->info("Sending authority request for $class : $term");
175                 my $fr = $session->request("open-ils.storage.authority.$class.see_from.controlled.atomic",$term, 10)->gather(1);
176                 my $al = $session->request("open-ils.storage.authority.$class.see_also_from.controlled.atomic",$term, 10)->gather(1);
177
178                 $response->{$class} = {} unless exists $response->{$class};
179                 $response->{$class}->{$term} = _auth_flatten( $term, $fr, $al, 1 );
180
181         }
182
183         #warn Dumper( $response );
184         return $response;
185 }
186
187 sub crossref_authority_batch {
188         my( $self, $client, $reqs ) = @_;
189
190         my $response = {};
191         my $lastr = [];
192         my $session = OpenSRF::AppSession->create("open-ils.storage");
193
194         for my $req (@$reqs) {
195
196                 my $class = $req->[0];
197                 my $term = $req->[1];
198                 next unless $class and $term;
199                 $logger->info("Sending authority request for $class : $term");
200                 my $freq = $session->request("open-ils.storage.authority.$class.see_from.controlled.atomic",$term, 10);
201                 my $areq = $session->request("open-ils.storage.authority.$class.see_also_from.controlled.atomic",$term, 10);
202
203                 if( $lastr->[0] ) { #process old data while waiting on new data
204                         my $cls = $lastr->[0];
205                         my $trm = $lastr->[1];
206                         my $fr  = $lastr->[2];
207                         my $al  = $lastr->[3];
208                         $response->{$cls} = {} unless exists $response->{$cls};
209                         $response->{$cls}->{$trm} = _auth_flatten( $trm, $fr, $al, 1 );
210                 }
211
212                 $lastr->[0] = $class;
213                 $lastr->[1] = $term; 
214                 $lastr->[2] = $freq->gather(1);
215                 $lastr->[3] = $areq->gather(1);
216         }
217
218         if( $lastr->[0] ) { #process old data while waiting on new data
219                 my $cls = $lastr->[0];
220                 my $trm = $lastr->[1];
221                 my $fr  = $lastr->[2];
222                 my $al  = $lastr->[3];
223                 $response->{$cls} = {} unless exists $response->{$cls};
224                 $response->{$cls}->{$trm} = _auth_flatten( $trm, $fr, $al, 1);
225         }
226
227         return $response;
228 }
229
230
231
232
233 sub crossref_authority_batch2 {
234         my( $self, $client, $reqs ) = @_;
235
236         my $response = {};
237         my $lastr = [];
238         my $session = OpenSRF::AppSession->create("open-ils.storage");
239
240         $cache = OpenSRF::Utils::Cache->new('global') unless $cache;
241
242         for my $req (@$reqs) {
243
244                 my $class = $req->[0];
245                 my $term = $req->[1];
246                 next unless $class and $term;
247
248                 my $t = $term;
249                 $t =~ s/\s//og;
250                 my $cdata = $cache->get_cache("oils_authority_${class}_$t");
251
252                 if( $cdata ) {
253                         $logger->debug("returning authority response from cache..");
254                         $response->{$class} = {} unless exists $response->{$class};
255                         $response->{$class}->{$term} = $cdata;
256                         next;
257                 }
258
259                 $logger->debug("authority data not found in cache.. fetching from storage");
260
261                 $logger->info("Sending authority request for $class : $term");
262                 my $freq = $session->request("open-ils.storage.authority.$class.see_from.controlled.atomic",$term, 10);
263                 my $areq = $session->request("open-ils.storage.authority.$class.see_also_from.controlled.atomic",$term, 10);
264                 my $fr = $freq->gather(1);      
265                 my $al = $areq->gather(1);
266                 $response->{$class} = {} unless exists $response->{$class};
267                 my $auth = _auth_flatten( $term, $fr, $al, 1 );
268
269                 my $timeout = 7200; #two hours
270                 $timeout = 300 if @{$auth->{from}} or @{$auth->{also}}; # 5 minutes
271                 $response->{$class}->{$term} = $auth;
272                 $logger->debug("adding authority lookup to cache with timeout $timeout");
273                 $cache->put_cache("oils_authority_${class}_$t", $auth, $timeout);
274         }
275         return $response;
276 }
277
278
279
280 1;