]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/support-scripts/marc_stream_importer.pl
reset the alarm with each socket read so that we only time out after a period of...
[working/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         do {
86             alarm $wait_time;
87             last unless $socket->sysread($buf, $bufsize);
88             $data .= $buf;
89         } while(1);
90         alarm 0;
91     };
92
93     my $handle;
94     open $handle, '<', \$data; 
95     my $batch = MARC::Batch->new('USMARC', $handle);
96     $batch->strict_off;
97
98     my $index = 0;
99     while(1) {
100
101         my $rec;
102         $index++;
103
104         eval { $rec = $batch->next; };
105
106         if($@) {
107             $logger->error("Failed parsing MARC record $index");
108             next;
109         }
110
111         last unless $rec;
112
113         my $resp = $apputils->simplereq(
114             'open-ils.cat', 
115             'open-ils.cat.biblio.record.xml.import',
116             $authtoken, 
117             $rec->as_xml_record, 
118             $bib_source
119         );
120
121         # has the session timed out?
122         if(oils_event_equals($resp, 'NO_SESSION')) {
123             set_auth_token();
124             my $resp = $apputils->simplereq(
125                 'open-ils.cat', 
126                 'open-ils.cat.biblio.record.xml.import',
127                 $authtoken, 
128                 $rec->as_xml_record, 
129                 $bib_source
130             );
131             oils_event_die($resp);
132         } else {
133             oils_event_die($resp);
134         }
135     }
136 }
137
138
139 # the authtoken will timeout after the configured inactivity period.
140 # When that happens, get a new one.
141 sub set_auth_token {
142     $authtoken = oils_login($oils_username, $oils_password, 'staff') 
143         or die "Unable to login to Evergreen";
144 }
145
146 osrf_connect($osrf_config);
147 set_auth_token();
148 __PACKAGE__->run();
149