]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/extras/import/marc2sre.pl
Teach marc2sre.pl MFHD record ingest script to read a mapping of library names to...
[working/Evergreen.git] / Open-ILS / src / extras / import / marc2sre.pl
1 #!/usr/bin/perl
2 use strict;
3 use warnings;
4
5 use lib '/openils/lib/perl5/';
6
7 use OpenSRF::System;
8 use OpenSRF::Application;
9 use OpenSRF::EX qw/:try/;
10 use OpenSRF::AppSession;
11 use OpenSRF::MultiSession;
12 use OpenSRF::Utils::SettingsClient;
13 use OpenILS::Application::AppUtils;
14 use OpenILS::Utils::Fieldmapper;
15 use Digest::MD5 qw/md5_hex/;
16 use OpenSRF::Utils::JSON;
17 use Data::Dumper;
18 use Unicode::Normalize;
19
20 use Time::HiRes qw/time/;
21 use Getopt::Long;
22 use MARC::Batch;
23 use MARC::File::XML ( BinaryEncoding => 'utf-8' );
24 use MARC::Charset;
25
26 MARC::Charset->ignore_errors(1);
27
28 my ($idfield, $count, $user, $password, $config, $marctype, $idsubfield, @files, @trash_fields, $quiet, $libmap) =
29         ('001', 1, 'admin', 'open-ils', '/openils/conf/opensrf_core.xml', 'USMARC');
30
31 GetOptions(
32         'idfield=s'     => \$idfield,
33         'idsubfield=s'  => \$idsubfield,
34         'startid=i'     => \$count,
35         'user=s'        => \$user,
36         'password=s'    => \$password,
37         'config=s'      => \$config,
38         'marctype=s'    => \$marctype,
39         'file=s'        => \@files,
40         'libmap=s'      => \$libmap,
41         'quiet'         => \$quiet,
42 );
43
44 @files = @ARGV if (!@files);
45
46 my @ses;
47 my @req;
48 my %processing_cache;
49 my $lib_id_map;
50 if ($libmap) {
51         $lib_id_map = map_libraries_to_ID($libmap);
52 }
53
54 OpenSRF::System->bootstrap_client( config_file => $config );
55 Fieldmapper->import(IDL => OpenSRF::Utils::SettingsClient->new->config_value("IDL"));
56
57 $user = OpenILS::Application::AppUtils->check_user_session( login($user,$password) )->id;
58
59 select STDERR; $| = 1;
60 select STDOUT; $| = 1;
61
62 my $batch = new MARC::Batch ( $marctype, @files );
63 $batch->strict_off();
64 $batch->warnings_off();
65
66 my $starttime = time;
67 my $rec;
68 while ( try { $rec = $batch->next } otherwise { $rec = -1 } ) {
69         next if ($rec == -1);
70         my $id = $count;
71         my $record_field;
72         if ($idsubfield) {
73                 $record_field = $rec->field($idfield, $idsubfield);
74         } else {
75                 $record_field = $rec->field($idfield);
76         }
77         my $record = $count;
78
79         # On some systems, the 001 actually points to the record ID
80         # We need to attach to the call number to handle holdings in different libraries
81         # but we can work out call numbers later in SQL by the record ID + call number text
82         if ($record_field) {
83                 $record = $record_field->data;
84                 $record =~ s/^.*?(\d+).*?$/$1/o;
85         }
86
87         (my $xml = $rec->as_xml_record()) =~ s/\n//sog;
88         $xml =~ s/^<\?xml.+\?\s*>//go;
89         $xml =~ s/>\s+</></go;
90         $xml =~ s/\p{Cc}//go;
91         $xml = OpenILS::Application::AppUtils->entityize($xml);
92         $xml =~ s/[\x00-\x1f]//go;
93
94         my $bib = new Fieldmapper::serial::record_entry;
95         $bib->id($id);
96         $bib->record($record);
97         $bib->active('t');
98         $bib->deleted('f');
99         $bib->marc($xml);
100         $bib->creator($user);
101         $bib->create_date('now');
102         $bib->editor($user);
103         $bib->edit_date('now');
104         $bib->last_xact_id('IMPORT-'.$starttime);
105
106         if ($libmap) {
107                 my $lib_id = get_library_id($rec);
108                 if ($lib_id) {
109                         $bib->owning_lib($lib_id);
110                 }
111         }
112
113         print OpenSRF::Utils::JSON->perl2JSON($bib)."\n";
114
115         $count++;
116
117         if (!$quiet && !($count % 20)) {
118                 print STDERR "\r$count\t". $count / (time - $starttime);
119         }
120 }
121
122 sub login {        
123         my( $username, $password, $type ) = @_;
124
125         $type |= "staff"; 
126
127         my $seed = OpenILS::Application::AppUtils->simplereq(
128                 'open-ils.auth',
129                 'open-ils.auth.authenticate.init',
130                 $username
131         );
132
133         die("No auth seed. Couldn't talk to the auth server") unless $seed;
134
135         my $response = OpenILS::Application::AppUtils->simplereq(
136                 'open-ils.auth',
137                 'open-ils.auth.authenticate.complete',
138                 {       username => $username,
139                         password => md5_hex($seed . md5_hex($password)),
140                         type => $type });
141
142         die("No auth response returned on login.") unless $response;
143
144         my $authtime = $response->{payload}->{authtime};
145         my $authtoken = $response->{payload}->{authtoken};
146
147         die("Login failed for user $username!") unless $authtoken;
148
149         return $authtoken;
150 }       
151
152 =head2
153
154 map_libraries_to_ID
155
156 Parses a file to return a hash of library names to integers representing
157 the actor.org_unit.id value of the library. This enables us to generate
158 an ingest file that does not subsequently need to manually manipulated.
159
160 The library name must correspond to the 'b' subfield of the 852 field.
161 Well, it does not have to, but you will have to modify this script
162 accordingly.
163
164 The format of the map file should be the name of the library, followed
165 by a tab, followed by the desired numeric ID of the library. For example:
166
167 BR1     4
168 BR2     5
169
170 =cut
171
172 sub map_libraries_to_ID {
173         my $map_filename = shift;
174
175         my %lib_id_map;
176
177         open(MAP_FH, '<', $map_filename) or die "Could not load [$map_filename] $!";
178         while (<MAP_FH>) {
179                 my ($lib, $id) = $_ =~ /^(.*?)\t(.*?)$/;
180                 $lib_id_map{$lib} = $id;
181         }
182
183         return \%lib_id_map;
184 }
185
186 sub get_library_id {
187         my $record = shift;
188
189         my $lib_name = $record->field('852')->subfield('b');
190         my $lib_id = $lib_id_map->{$lib_name};
191
192         return $lib_id;
193 }