1 package OpenILS::Application::Search;
2 use base qw/OpenSRF::Application/;
3 use strict; use warnings;
5 use OpenILS::Utils::Fieldmapper;
6 use Time::HiRes qw(time);
7 use OpenILS::Application::Cat::Utils;
9 use OpenSRF::EX qw(:try);
11 # used for cat search classes
12 my $cat_search_hash = {
15 { tag => "100", subfield => "a"} ,
16 { tag => "700", subfield => "a"},
20 { tag => "245", subfield => "a"},
21 { tag => "242", subfield => "a"},
22 { tag => "240", subfield => "a"},
23 { tag => "210", subfield => "a"},
27 { tag => "650", subfield => "_" },
31 { tag => "035", subfield => "_" },
37 __PACKAGE__->register_method(
38 method => "cat_biblio_search_tcn",
39 api_name => "open-ils.search.cat.biblio.tcn",
41 note => "Searches biblio information by search class",
44 sub cat_biblio_search_tcn {
46 my( $self, $client, $org_id, $tcn ) = @_;
48 $tcn =~ s/.*?(\w+)\s*$/$1/o;
49 warn "Searching TCN $tcn\n";
51 my $session = OpenSRF::AppSession->create( "open-ils.storage" );
52 my $request = $session->request(
53 "open-ils.storage.biblio.record_entry.search.tcn_value", $tcn );
54 my $response = $request->recv();
57 unless ($response) { return []; }
59 if($response->isa("OpenSRF::EX")) {
60 throw $response ($response->stringify);
63 my $record_entry = $response->content;
65 for my $record (@$record_entry) {
66 push @ids, $record->id;
70 my $record_list = _records_to_mods( @ids );
72 for my $rec (@$record_list) {
73 $client->respond($rec);
75 #return _records_to_mods( @ids );
82 __PACKAGE__->register_method(
83 method => "cat_biblio_search_class",
84 api_name => "open-ils.search.cat.biblio.class",
86 note => "Searches biblio information by search class",
89 sub cat_biblio_search_class {
91 my( $self, $client, $org_id, $class, $sort, $string ) = @_;
93 throw OpenSRF::EX::InvalidArg
94 ("Not enough args to open-ils.search.cat.biblio.class")
95 unless( defined($org_id) and $class and $sort and $string );
100 my $method = $self->method_lookup("open-ils.search.biblio.marc");
102 throw OpenSRF::EX::PANIC
103 ("Can't lookup method 'open-ils.search.biblio.marc'");
106 my ($records) = $method->run( $cat_search_hash->{$class}, $string );
109 for my $i (@$records) { push @ids, $i->[0]; }
111 my $mods_list = _records_to_mods( @ids );
113 # ---------------------------------------------------------------
114 # append copy count information to the mods objects
115 my $session = OpenSRF::AppSession->create("open-ils.storage");
117 my $request = $session->request(
118 "open-ils.storage.biblio.record_copy_count.batch", $org_id, @ids );
122 warn "receiving copy counts for doc $id\n";
124 my $response = $request->recv();
125 next unless $response;
127 if( $response and UNIVERSAL::isa($response, "Error")) {
128 throw $response ($response->stringify);
131 my $count = $response->content;
132 my $mods_obj = undef;
133 for my $m (@$mods_list) {
134 $mods_obj = $m if ($m->{doc_id} == $id)
137 $mods_obj->{copy_count} = $count;
140 $client->respond( $mods_obj );
146 $session->disconnect();
148 # ---------------------------------------------------------------
157 __PACKAGE__->register_method(
158 method => "cat_biblio_search_class_stream",
159 api_name => "open-ils.search.cat.biblio.class.stream",
161 note => "Searches biblio information by search class",
164 sub cat_biblio_search_class_stream {
166 my( $self, $client, $org_id, $class, $sort, $string ) = @_;
168 throw OpenSRF::EX::InvalidArg
169 ("Not enough args to open-ils.search.cat.biblio.class")
170 unless( defined($org_id) and $class and $sort and $string );
175 my $method = $self->method_lookup("open-ils.search.biblio.marc");
177 throw OpenSRF::EX::PANIC
178 ("Can't lookup method 'open-ils.search.biblio.marc'");
181 my ($records) = $method->run( $cat_search_hash->{$class}, $string );
184 for my $i (@$records) { push @ids, $i->[0]; }
186 my $mods_list = _records_to_mods( @ids );
188 # ---------------------------------------------------------------
189 # append copy count information to the mods objects
190 my $session = OpenSRF::AppSession->create("open-ils.storage");
192 my $request = $session->request(
193 "open-ils.storage.biblio.record_copy_count.batch", $org_id, @ids );
197 warn "receiving copy counts for doc $id\n";
199 my $response = $request->recv();
200 next unless $response;
202 if( $response and UNIVERSAL::isa($response, "Error")) {
203 throw $response ($response->stringify);
206 my $count = $response->content;
207 my $mods_obj = undef;
208 for my $m (@$mods_list) {
209 $mods_obj = $m if ($m->{doc_id} == $id)
212 $mods_obj->{copy_count} = $count;
215 $client->respond( $mods_obj );
221 $session->disconnect();
223 # ---------------------------------------------------------------
228 __PACKAGE__->register_method(
229 method => "biblio_search_marc",
230 api_name => "open-ils.search.biblio.marc",
232 note => "Searches biblio information by marc tag",
235 sub biblio_search_marc {
237 my( $self, $client, $search_hash, $string ) = @_;
239 my $session = OpenSRF::AppSession->create("open-ils.storage");
240 my $request = $session->request(
241 "open-ils.storage.metabib.full_rec.search_fts.index_vector", $search_hash, $string );
243 my $response = $request->recv();
244 if($response and $response->isa("OpenSRF::EX")) {
245 throw $response ($response->stringify);
248 my $data = $response->content;
252 $session->disconnect();
262 __PACKAGE__->register_method(
263 method => "get_org_tree",
264 api_name => "open-ils.search.actor.org_tree.retrieve",
266 note => "Returns the entire org tree structure",
271 my( $self, $client, $user_session ) = @_;
273 if( $user_session ) {
276 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
279 my $session = OpenSRF::AppSession->create("open-ils.storage");
280 my $request = $session->request(
281 "open-ils.storage.actor.org_unit.retrieve", $user_obj->home_ou );
282 my $response = $request->recv();
285 throw OpenSRF::EX::ERROR (
286 "No response from storage for org_unit retrieve");
288 if(UNIVERSAL::isa($response,"Error")) {
289 throw $response ($response->stringify);
292 my $home_ou = $response->content;
294 # XXX grab descendants and build org tree from them
296 my $request = $session->request(
297 "open-ils.storage.actor.org_unit_descendants" );
298 my $response = $request->recv();
300 throw OpenSRF::EX::ERROR (
301 "No response from storage for org_unit retrieve");
303 if(UNIVERSAL::isa($response,"Error")) {
304 throw $response ($response->stringify);
307 my $descendants = $response->content;
310 $session->disconnect();
316 return OpenILS::Application::AppUtils->get_org_tree();
321 __PACKAGE__->register_method(
322 method => "copy_count_by_org_unit",
323 api_name => "open-ils.search.copy_count_by_location",
325 note => "Searches biblio information by marc tag",
328 sub copy_count_by_org_unit {
329 my( $self, $client, $org_id, @record_ids ) = @_;
331 my $session = OpenSRF::AppSession->create("open-ils.storage");
332 my $request = $session->request(
333 "open-ils.storage.biblio.record_copy_count.batch", $org_id, @record_ids );
335 for my $id (@record_ids) {
337 my $response = $request->recv();
338 next unless $response;
340 if( $response and UNIVERSAL::isa($response, "Error")) {
341 throw $response ($response->stringify);
344 my $count = $response->content;
345 $client->respond( { record => $id, count => $count } );
349 $session->disconnect();
361 # ---------------------------------------------------------------------------
362 # takes a list of record id's and turns the docs into friendly
364 # ---------------------------------------------------------------------------
365 sub _records_to_mods {
371 my $session = OpenSRF::AppSession->create("open-ils.storage");
372 my $request = $session->request(
373 "open-ils.storage.biblio.record_marc.batch.retrieve", @ids );
375 my $last_content = undef;
377 while( my $response = $request->recv() ) {
379 if( $last_content ) {
380 my $u = OpenILS::Application::Cat::Utils->new();
381 $u->start_mods_batch( $last_content->marc );
382 my $mods = $u->finish_mods_batch();
383 $mods->{doc_id} = $last_content->id();
384 warn "Turning doc " . $mods->{doc_id} . " into MODS\n";
385 $last_content = undef;
386 push @results, $mods;
389 next unless $response;
391 if($response->isa("OpenSRF::EX")) {
392 throw $response ($response->stringify);
395 $last_content = $response->content;
399 if( $last_content ) {
400 my $u = OpenILS::Application::Cat::Utils->new();
401 $u->start_mods_batch( $last_content->marc );
402 my $mods = $u->finish_mods_batch();
403 $mods->{doc_id} = $last_content->id();
404 push @results, $mods;
409 $session->disconnect();