]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/support-scripts/marc_stream_importer.pl
small net::server process to read MARC data from a raw socket and import the data...
[Evergreen.git] / Open-ILS / src / support-scripts / marc_stream_importer.pl
1 #!/usr/bin/perl
2 # Copyright (C) 2008 Equinox Software, Inc.
3 # Author: Bill Erickson <erickson@esilibrary.com>
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14
15 # ----------------------------------------------------------------------------
16 # WARNING:  This script provides no security layer.  Any client that has 
17 # access to the server+port can inject MARC records into the system.  
18 # ----------------------------------------------------------------------------
19
20 # ----------------------------------------------------------------------------
21 # marc_stream_importer.pl -- Import MARC records via bare socket connection
22 #
23 # Usage:
24 # ./marc_stream_importer.pl /openils/conf/opensrf_core.xml \
25 #   <eg_username> <eg_password> <bib_source> --port <port> --min_servers 2 \
26 #   --max_servers 20 --log_file /openils/var/log/marc_net_importer.log &
27 #
28 # Note: this script has to be run in the same directory as $oils_header.pl
29
30
31 # ----------------------------------------------------------------------------
32 # To use this script with OCLC Connexion:
33 #
34 # Under Tools -> Options -> Export (tab)
35 #   Create -> Choose Connection -> OK -> Leave translation at "None" 
36 #       -> Create -> Create -> choose TCP/IP (internet) 
37 #       -> Enter hostname and Port, leave 'Use Telnet Protocol' checked 
38 #       -> Create/OK your way out of the dialogs
39 #   Record Characteristics (button) -> Choose 'UTF-8 Unicode' for 
40 #   the Character Set
41 #
42 # OCLC and Connexion are trademark/service marks of OCLC Online Computer 
43 # Library Center, Inc.
44 # ----------------------------------------------------------------------------
45
46 use strict; use warnings;
47 use Net::Server::PreFork;
48 use base qw/Net::Server::PreFork/;
49 use MARC::Record;
50 use MARC::Batch;
51 use MARC::File::XML;
52 use MARC::File::USMARC;
53 use OpenSRF::Utils::Logger qw/$logger/;
54 require 'oils_header.pl';
55 use vars qw/$apputils/;
56
57 my $bufsize = 4096;
58 my $wait_time = 5;
59 my $osrf_config = shift;
60 my $oils_username = shift;
61 my $oils_password = shift;
62 my $bib_source = shift;
63 my $authtoken;
64
65 print <<WARNING;
66
67 WARNING:  This script provides no security layer.  Any client that has 
68 access to the server+port can inject MARC records into the system.  
69
70 WARNING
71
72 $0 = 'Evergreen MARC Stream Listener';
73
74 sub process_request {
75     my $self = shift;
76     my $socket = $self->{server}->{client};
77     my $data = '';
78     my $buf;
79
80     # Reading <STDIN> blocks until the client is closed.  Instead of waiting 
81     # for that, give each inbound record $wait_time seconds to fully arrive
82     # and pull the data directly from the socket
83     eval {
84         local $SIG{ALRM} = sub { die "alarm\n" }; 
85         alarm $wait_time;
86         while(my $n = $socket->sysread($buf, $bufsize)) {
87             $data .= $buf;
88         }
89         alarm 0;
90     };
91
92     my $handle;
93     open $handle, '<', \$data; 
94     my $batch = MARC::Batch->new('USMARC', $handle);
95     $batch->strict_off;
96
97     my $index = 0;
98     while(1) {
99
100         my $rec;
101         $index++;
102
103         eval { $rec = $batch->next; };
104
105         if($@) {
106             $logger->error("Failed parsing MARC record $index");
107             next;
108         }
109
110         last unless $rec;
111
112         my $resp = $apputils->simplereq(
113             'open-ils.cat', 
114             'open-ils.cat.biblio.record.xml.import',
115             $authtoken, 
116             $rec->as_xml_record, 
117             $bib_source
118         );
119
120         # has the session timed out?
121         if(oils_event_equals($resp, 'NO_SESSION')) {
122             set_auth_token();
123             my $resp = $apputils->simplereq(
124                 'open-ils.cat', 
125                 'open-ils.cat.biblio.record.xml.import',
126                 $authtoken, 
127                 $rec->as_xml_record, 
128                 $bib_source
129             );
130             oils_event_die($resp);
131         } else {
132             oils_event_die($resp);
133         }
134     }
135 }
136
137
138 # the authtoken will timeout after the configured inactivity period.
139 # When that happens, get a new one.
140 sub set_auth_token {
141     $authtoken = oils_login($oils_username, $oils_password, 'staff') 
142         or die "Unable to login to Evergreen";
143 }
144
145 osrf_connect($osrf_config);
146 set_auth_token();
147 __PACKAGE__->run();
148