]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Application/Search/Authority.pm
94b5fe7eb001baa076334233981d2ae7f010fdaf
[Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Application / Search / Authority.pm
1 package OpenILS::Application::Search::Authority;
2 use base qw/OpenSRF::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 search_authority {
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.search.marc.atomic' => @_ )->gather(1);
41 }
42 __PACKAGE__->register_method(
43         method          => "search_authority",
44         api_name        => "open-ils.search.authority.fts",
45         argc            => 2, 
46         note            => "Searches authority data for existing controlled terms and crossrefs",
47 );              
48
49
50 sub crossref_authority {
51         my $self = shift;
52         my $client = shift;
53         my $class = shift;
54         my $term = shift;
55         my $limit = shift || 10;
56
57         my $session = OpenSRF::AppSession->create("open-ils.storage");
58
59         $logger->info("authority xref search for $class=$term, limit=$limit");
60         my $fr = $session->request(
61                 "open-ils.storage.authority.$class.see_from.controlled.atomic",$term, $limit)->gather(1);
62         my $al = $session->request(
63                 "open-ils.storage.authority.$class.see_also_from.controlled.atomic",$term, $limit)->gather(1);
64
65         my $data = _auth_flatten( $term, $fr, $al, 1 );
66
67         return $data;
68 }
69
70 sub _auth_flatten {
71         my $term = shift;
72         my $fr = shift;
73         my $al = shift;
74         my $limit = shift;
75
76         my %hash = ();
77         for my $x (@$fr) {
78                 my $string = $$x[0];
79                 for my $i (1..10) {
80                         last unless ($$x[$i]);
81                         if ($string =~ /\W$/o) {
82                                 $string .= ' '.$$x[$i];
83                         } else {
84                                 $string .= ' -- '.$$x[$i];
85                         }
86                 }
87                 next if (lc($string) eq lc($term));
88                 $hash{$string}++;
89                 $hash{$string}++ if (lc($$x[0]) eq lc($term));
90         }
91         my $from = [keys %hash]; #[ sort { $hash{$b} <=> $hash{$a} || $a cmp $b } keys %hash ];
92
93 #       $from = [ @$from[0..4] ] if $limit;
94
95         %hash = ();
96         for my $x (@$al) {
97                 my $string = $$x[0];
98                 for my $i (1..10) {
99                         last unless ($$x[$i]);
100                         if ($string =~ /\W$/o) {
101                                 $string .= ' '.$$x[$i];
102                         } else {
103                                 $string .= ' -- '.$$x[$i];
104                         }
105                 }
106                 next if (lc($string) eq lc($term));
107                 $hash{$string}++;
108                 $hash{$string}++ if (lc($$x[0]) eq lc($term));
109         }
110         my $also = [keys %hash]; #[ sort { $hash{$b} <=> $hash{$a} || $a cmp $b } keys %hash ];
111
112 #       $also = [ @$also[0..4] ] if $limit;
113
114         #warn Dumper( { from => $from, also => $also } );
115
116         return { from => $from, also => $also };
117 }
118
119 __PACKAGE__->register_method(
120         method          => "crossref_authority",
121         api_name        => "open-ils.search.authority.crossref",
122         argc            => 2, 
123         note            => "Searches authority data for existing controlled terms and crossrefs",
124 );              
125
126 __PACKAGE__->register_method(
127         #method         => "new_crossref_authority_batch",
128         method          => "crossref_authority_batch2",
129         api_name        => "open-ils.search.authority.crossref.batch",
130         argc            => 1, 
131         note            => <<"  NOTE");
132         Takes an array of class,term pair sub-arrays and performs an authority lookup for each
133
134         PARAMS( [ ["subject", "earth"], ["author","shakespeare"] ] );
135
136         Returns an object like so:
137         {
138                 "classname" : {
139                         "term" : { "from" : [ ...], "also" : [...] }
140                         "term2" : { "from" : [ ...], "also" : [...] }
141                 }
142         }
143         NOTE
144
145 sub new_crossref_authority_batch {
146         my( $self, $client, $reqs ) = @_;
147
148         my $response = {};
149         my $lastr = [];
150         my $session = OpenSRF::AppSession->create("open-ils.storage");
151
152         for my $req (@$reqs) {
153
154                 my $class = $req->[0];
155                 my $term = $req->[1];
156                 next unless $class and $term;
157                 warn "Sending authority request for $class : $term\n";
158                 my $fr = $session->request("open-ils.storage.authority.$class.see_from.controlled.atomic",$term, 10)->gather(1);
159                 my $al = $session->request("open-ils.storage.authority.$class.see_also_from.controlled.atomic",$term, 10)->gather(1);
160
161                 warn "Flattening $class : $term\n";
162                 $response->{$class} = {} unless exists $response->{$class};
163                 $response->{$class}->{$term} = _auth_flatten( $term, $fr, $al, 1 );
164
165         }
166
167         #warn Dumper( $response );
168         return $response;
169 }
170
171 sub crossref_authority_batch {
172         my( $self, $client, $reqs ) = @_;
173
174         my $response = {};
175         my $lastr = [];
176         my $session = OpenSRF::AppSession->create("open-ils.storage");
177
178         for my $req (@$reqs) {
179
180                 my $class = $req->[0];
181                 my $term = $req->[1];
182                 next unless $class and $term;
183                 warn "Sending authority request for $class : $term\n";
184                 my $freq = $session->request("open-ils.storage.authority.$class.see_from.controlled.atomic",$term, 10);
185                 my $areq = $session->request("open-ils.storage.authority.$class.see_also_from.controlled.atomic",$term, 10);
186
187                 if( $lastr->[0] ) { #process old data while waiting on new data
188                         my $cls = $lastr->[0];
189                         my $trm = $lastr->[1];
190                         my $fr  = $lastr->[2];
191                         my $al  = $lastr->[3];
192                         warn "Flattening $class : $term\n";
193                         $response->{$cls} = {} unless exists $response->{$cls};
194                         $response->{$cls}->{$trm} = _auth_flatten( $trm, $fr, $al, 1 );
195                 }
196
197                 $lastr->[0] = $class;
198                 $lastr->[1] = $term; 
199                 $lastr->[2] = $freq->gather(1);
200                 $lastr->[3] = $areq->gather(1);
201         }
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                 warn "Flattening $cls : $trm\n";
209                 $response->{$cls} = {} unless exists $response->{$cls};
210                 $response->{$cls}->{$trm} = _auth_flatten( $trm, $fr, $al, 1);
211         }
212
213         return $response;
214 }
215
216
217
218
219 sub crossref_authority_batch2 {
220         my( $self, $client, $reqs ) = @_;
221
222         my $response = {};
223         my $lastr = [];
224         my $session = OpenSRF::AppSession->create("open-ils.storage");
225
226         $cache = OpenSRF::Utils::Cache->new('global') unless $cache;
227
228         for my $req (@$reqs) {
229
230                 my $class = $req->[0];
231                 my $term = $req->[1];
232                 next unless $class and $term;
233
234                 my $t = $term;
235                 $t =~ s/\s//og;
236                 my $cdata = $cache->get_cache("oils_authority_${class}_$t");
237
238                 if( $cdata ) {
239                         $logger->debug("returning authority response from cache..");
240                         $response->{$class} = {} unless exists $response->{$class};
241                         $response->{$class}->{$term} = $cdata;
242                         next;
243                 }
244
245                 $logger->debug("authority data not found in cache.. fetching from storage");
246
247                 warn "Sending authority request for $class : $term\n";
248                 my $freq = $session->request("open-ils.storage.authority.$class.see_from.controlled.atomic",$term, 10);
249                 my $areq = $session->request("open-ils.storage.authority.$class.see_also_from.controlled.atomic",$term, 10);
250                 my $fr = $freq->gather(1);      
251                 my $al = $areq->gather(1);
252                 $response->{$class} = {} unless exists $response->{$class};
253                 my $auth = _auth_flatten( $term, $fr, $al, 1 );
254
255                 my $timeout = 7200; #two hours
256                 $timeout = 300 if @{$auth->{from}} or @{$auth->{also}}; # 5 minutes
257                 $response->{$class}->{$term} = $auth;
258                 $logger->debug("adding authority lookup to cache with timeout $timeout");
259                 $cache->put_cache("oils_authority_${class}_$t", $auth, $timeout);
260         }
261         return $response;
262 }
263
264
265
266
267
268 __PACKAGE__->register_method(
269         method  => "authority_to_html",
270         api_name        => "open-ils.search.authority.to_html" );
271
272 my $parser              = XML::LibXML->new();
273 my $xslt                        = XML::LibXSLT->new();
274 my $stylesheet;
275
276
277 sub authority_to_html {
278         my( $self, $client, $id ) = @_;
279
280
281         if( !$stylesheet ) {
282                 my $sclient = OpenSRF::Utils::SettingsClient->new();
283                 my $dir = $sclient->config_value( "dirs", "xsl" );
284                 my $xsl = $sclient->config_value(
285                         "apps", "open-ils.search", "app_settings", "marc_html_xsl" );
286                 $xsl = $parser->parse_file("$dir/$xsl");
287                 $stylesheet = $xslt->parse_stylesheet( $xsl );
288         }
289
290         my $e = new_editor();
291         my $rec = $e->retrieve_authority_record_entry($id) or return $e->event;
292         my $xmldoc = $parser->parse_string($rec->marc);
293         my $html = $stylesheet->transform($xmldoc);
294
295         return $html->toString();
296 }
297
298
299
300
301 1;