1 package OpenILS::Application::Search;
2 use base qw/OpenSRF::Application/;
3 use strict; use warnings;
6 use OpenILS::Utils::Fieldmapper;
7 use OpenILS::Utils::ModsParser;
8 use OpenSRF::Utils::SettingsClient;
9 use OpenSRF::Utils::Cache;
12 use OpenILS::Application::Search::StaffClient;
13 use OpenILS::Application::Search::Web;
15 use OpenILS::Application::AppUtils;
17 use Time::HiRes qw(time);
18 use OpenSRF::EX qw(:try);
20 # Houses generic search utilites
23 OpenILS::Application::SearchCache->child_init();
28 __PACKAGE__->register_method(
29 method => "biblio_search_marc",
30 api_name => "open-ils.search.biblio.marc",
32 note => "Searches biblio information by marc tag",
35 sub biblio_search_marc {
37 my( $self, $client, $search_hash, $string ) = @_;
39 warn "Building biblio marc session\n";
40 my $session = OpenSRF::AppSession->create("open-ils.storage");
42 warn "Sending biblio marc request\n";
43 my $request = $session->request(
44 "open-ils.storage.metabib.full_rec.search_fts.index_vector",
45 $search_hash, $string );
47 warn "Waiting complete\n";
48 $request->wait_complete();
50 warn "Calling recv\n";
51 my $response = $request->recv(20);
54 if($response and UNIVERSAL::isa($response,"OpenSRF::EX")) {
55 throw $response ($response->stringify);
60 if($response and UNIVERSAL::can($response,"content")) {
61 $data = $response->content;
63 warn "finishing request\n";
67 $session->disconnect();
75 __PACKAGE__->register_method(
76 method => "get_org_tree",
77 api_name => "open-ils.search.actor.org_tree.retrieve",
79 note => "Returns the entire org tree structure",
84 my( $self, $client, $user_session ) = @_;
86 if( $user_session ) { # keep for now for backwards compatibility
89 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
91 my $session = OpenSRF::AppSession->create("open-ils.storage");
92 my $request = $session->request(
93 "open-ils.storage.actor.org_unit.retrieve", $user_obj->home_ou );
94 my $response = $request->recv();
97 throw OpenSRF::EX::ERROR (
98 "No response from storage for org_unit retrieve");
100 if(UNIVERSAL::isa($response,"Error")) {
101 throw $response ($response->stringify);
104 my $home_ou = $response->content;
106 $session->disconnect();
111 return OpenILS::Application::AppUtils->get_org_tree();
116 __PACKAGE__->register_method(
117 method => "get_org_sub_tree",
118 api_name => "open-ils.search.actor.org_subtree.retrieve",
120 note => "Returns the entire org tree structure",
123 sub get_sub_org_tree {
125 my( $self, $client, $user_session ) = @_;
128 throw OpenSRF::EX::InvalidArg
129 ("No User session provided to org_subtree.retrieve");
132 if( $user_session ) {
135 OpenILS::Application::AppUtils->check_user_session( $user_session ); #throws EX on error
138 my $session = OpenSRF::AppSession->create("open-ils.storage");
139 my $request = $session->request(
140 "open-ils.storage.actor.org_unit.retrieve", $user_obj->home_ou );
141 my $response = $request->recv();
144 throw OpenSRF::EX::ERROR (
145 "No response from storage for org_unit retrieve");
147 if(UNIVERSAL::isa($response,"Error")) {
148 throw $response ($response->stringify);
151 my $home_ou = $response->content;
153 # XXX grab descendants and build org tree from them
155 my $request = $session->request(
156 "open-ils.storage.actor.org_unit_descendants" );
157 my $response = $request->recv();
159 throw OpenSRF::EX::ERROR (
160 "No response from storage for org_unit retrieve");
162 if(UNIVERSAL::isa($response,"Error")) {
163 throw $response ($response->stringify);
166 my $descendants = $response->content;
170 $session->disconnect();
182 # ---------------------------------------------------------------------------
183 # takes a list of record id's and turns the docs into friendly
184 # mods structures. Creates one MODS structure for each doc id.
185 # ---------------------------------------------------------------------------
186 sub _records_to_mods {
192 my $session = OpenSRF::AppSession->create("open-ils.storage");
193 my $request = $session->request(
194 "open-ils.storage.biblio.record_marc.batch.retrieve", @ids );
196 my $last_content = undef;
198 while( my $response = $request->recv() ) {
200 if( $last_content ) {
201 my $u = OpenILS::Utils::ModsParser->new();
202 $u->start_mods_batch( $last_content->marc );
203 my $mods = $u->finish_mods_batch();
204 $mods->{doc_id} = $last_content->id();
205 warn "Turning doc " . $mods->{doc_id} . " into MODS\n";
206 $last_content = undef;
207 push @results, $mods;
210 next unless $response;
212 if($response->isa("OpenSRF::EX")) {
213 throw $response ($response->stringify);
216 $last_content = $response->content;
220 if( $last_content ) {
221 my $u = OpenILS::Utils::ModsParser->new();
222 $u->start_mods_batch( $last_content->marc );
223 my $mods = $u->finish_mods_batch();
224 $mods->{doc_id} = $last_content->id();
225 push @results, $mods;
230 $session->disconnect();
236 __PACKAGE__->register_method(
237 method => "record_id_to_mods",
238 api_name => "open-ils.search.biblio.record.mods.retrieve",
240 note => "Provide ID, we provide the mods"
243 # converts a record into a mods object with copy counts attached
244 sub record_id_to_mods {
246 my( $self, $client, $org_id, $id ) = @_;
248 my $mods_list = _records_to_mods( $id );
249 my $mods_obj = $mods_list->[0];
251 # --------------------------------------------------------------- # append copy count information to the mods objects
252 my $session = OpenSRF::AppSession->create("open-ils.storage");
254 warn "mods retrieve $id\n";
256 my $request = $session->request(
257 "open-ils.storage.biblio.record_copy_count", $org_id, $id );
258 warn "mods retrieve wait $id\n";
259 $request->wait_complete;
260 warn "mods retrieve recv $id\n";
261 my $response = $request->recv();
262 return undef unless $response;
263 warn "mods retrieve after recv $id\n";
265 if( $response and UNIVERSAL::isa($response, "Error")) {
266 throw $response ($response->stringify);
269 my $count = $response->content;
270 $mods_obj->{copy_count} = $count;
274 $session->disconnect();
280 package OpenILS::Application::SearchCache;
281 use strict; use warnings;
287 warn "initing searchcache child\n";
289 my $config_client = OpenSRF::Utils::SettingsClient->new();
290 my $memcache_servers =
291 $config_client->config_value(
292 "apps","open-ils.search", "app_settings","memcache" );
296 if( !$memcache_servers ) {
297 throw OpenSRF::EX::Config ("
298 No Memcache servers specified for open-ils.search!");
302 if(!ref($memcache_servers)) {
303 $memcache_servers = [$memcache_servers];
307 warn Dumper $memcache_servers;
308 $cache_handle = OpenSRF::Utils::Cache->new( "open-ils.search", 0, $memcache_servers );
312 sub new {return bless({},shift());}
315 my($self, $key, $data, $timeout) = @_;
316 warn "putting into cache $key\n";
317 return undef unless( $key and $data );
319 $cache_handle->put_cache( "_open-ils.search_$key", JSON->perl2JSON($data), $timeout );
323 my( $self, $key ) = @_;
324 my $json = $cache_handle->get_cache("_open-ils.search_$key");
325 warn "retrieving from cache $key\n =>>> $json";
326 return JSON->JSON2perl($json);