2 package OpenILS::Application::Search::Z3950;
3 use strict; use warnings;
4 use base qw/OpenSRF::Application/;
10 use OpenSRF::Utils::SettingsClient;
12 use OpenILS::Utils::FlatXML;
13 use OpenILS::Application::Cat::Utils;
14 use OpenILS::Application::AppUtils;
16 use OpenSRF::EX qw(:try);
18 my $utils = "OpenILS::Application::Cat::Utils";
19 my $apputils = "OpenILS::Application::AppUtils";
21 use OpenILS::Utils::ModsParser;
24 my $output = "USMARC"; # only support output for now
35 $settings_client = OpenSRF::Utils::SettingsClient->new();
36 $host = $settings_client->config_value("z3950", "oclc", "host");
37 $port = $settings_client->config_value("z3950", "oclc", "port");
38 $database = $settings_client->config_value("z3950", "oclc", "db");
39 $attr = $settings_client->config_value("z3950", "oclc", "attr");
40 $username = $settings_client->config_value("z3950", "oclc", "username");
41 $password = $settings_client->config_value("z3950", "oclc", "password");
45 __PACKAGE__->register_method(
46 method => "z39_search_by_string",
47 api_name => "open-ils.search.z3950.raw_string",
50 sub z39_search_by_string {
52 my( $self, $client, $server,
53 $port, $db, $search, $user, $pw ) = @_;
55 throw OpenSRF::EX::InvalidArg unless(
56 $server and $port and $db and $search);
59 warn "Z39.50 search for $search\n";
64 my $conn = new Net::Z3950::Connection(
69 preferredRecordSyntax => $output,
73 my $rs = $conn->search( $search );
75 throw OpenSRF::EX::ERROR ("z39 search failed");
81 $hash->{count} = $rs->size();
82 warn "Z3950 Search recovered " . $hash->{count} . " records\n";
84 # until there is a more graceful way to handle this
85 if($hash->{count} > 20) { return $hash; }
88 for( my $x = 0; $x != $hash->{count}; $x++ ) {
89 warn "Churning on z39 record count $x\n";
91 my $rec = $rs->record($x+1);
92 my $marc = MARC::Record->new_from_usmarc($rec->rawdata());
94 my $marcxml = $marc->as_xml();
95 my $flat = OpenILS::Utils::FlatXML->new( xml => $marcxml );
96 my $doc = $flat->xml_to_doc();
99 if( $doc->documentElement->nodeName =~ /collection/io ) {
100 $doc->setDocumentElement( $doc->documentElement->firstChild );
101 $doc->documentElement->setNamespace(
102 "http://www.loc.gov/MARC21/slim", undef, 1);
105 warn "Z3950 XML doc:\n" . $doc->toString . "\n";
107 warn "Turning doc into a nodeset...\n";
113 my $nodes = OpenILS::Utils::FlatXML->new->xmldoc_to_nodeset($doc);
116 warn "turning nodeset into tree\n";
117 $tree = $utils->nodeset2tree( $nodes->nodeset );
123 warn "Error turning doc into nodeset/node tree: $err\n";
125 push @$records, $tree;
131 warn "Returning marc tree " . Dumper($records) . "\n";
133 $hash->{records} = $records;
139 __PACKAGE__->register_method(
140 method => "import_search",
141 api_name => "open-ils.search.z3950.import",
145 my($self, $client, $user_session, $string) = @_;
148 $apputils->check_user_session( $user_session ); #throws EX on error
150 return $self->z39_search_by_string(
151 $client, $host, $port, $database,
152 "\@attr 1=$attr \"$string\"", $username, $password );