38fd4e4334233283fa30ab2e4c128b8298b37088
[koha-eprints] / EPrints / Plugin / Import / MARC.pm
1 package EPrints::Plugin::Import::MARC;
2
3 =head1 NAME
4
5 EPrints::Plugin::Import::MARC -- allows to import MARC records
6
7 =head1 DESCRIPTION
8
9 This plugin allows you to import MARC and MARC XML records into GNU EPrints.
10
11 =head1 CONFIGURATION
12
13 Configuration might be changed in cfg.d/marc.pl. Webserver needs to be restarted after any configuration changes.
14
15 =head1 COPYRIGHT AND LICENSE
16
17 (C) 2008 Jose Miguel Parrella Romero <bureado@cpan.org>
18 (C) 2013 Dobrica Pavlinušić <dpavlin@rot13.org>
19 This module is free software under the same terms of Perl.
20
21 =cut
22
23 use Data::Dump qw(dump);
24
25 use Encode;
26 use strict;
27
28 our @ISA = qw/EPrints::Plugin::Import/;
29
30 sub new
31 {
32         my( $class, %params ) = @_;
33
34         my $self = $class->SUPER::new( %params );
35
36         $self->{name} = "MARC";
37         $self->{visible} = "all";
38         $self->{produce} = [ 'list/eprint' ];
39
40         my $rc = EPrints::Utils::require_if_exists("MARC::Record") and EPrints::Utils::require_if_exists("MARC::File::USMARC");
41         unless( $rc ) 
42         {
43                 $self->{visible} = "";
44                 $self->{error} = "Failed to load required modules.";
45         }
46
47         warn "XXX marc import with callbacks";
48
49         return $self;
50 }
51
52 sub input_fh
53 {
54         my( $plugin, %opts ) = @_;
55         
56         my @ids;
57         my $file = MARC::File::USMARC->in( $opts{fh} );
58
59         while ( my $marc = $file->next() ) {
60                 my $epdata = $plugin->convert_input( $marc );
61                 next unless( defined $epdata );
62
63                 my $dataobj = $plugin->epdata_to_dataobj( $opts{dataset}, $epdata );
64                 if( defined $dataobj )
65                 {
66                         push @ids, $dataobj->get_id;
67                 }
68         }
69
70         return EPrints::List->new( 
71                 dataset => $opts{dataset}, 
72                 session => $plugin->{session},
73                 ids=>\@ids );
74
75         return undef;
76 }
77
78 sub input_file
79 {
80         my( $plugin, %opts ) = @_;
81
82         if( $opts{filename} eq '-' )
83         {
84                 $plugin->error("Does not support input from STDIN");
85
86                 return undef;
87         }
88
89         my @ids;
90         my $file = MARC::File::USMARC->in( $opts{filename} );
91
92         while ( my $marc = $file->next() ) {
93                 my $epdata = $plugin->convert_input( $marc );
94                 next unless( defined $epdata );
95
96                 my $dataobj = $plugin->epdata_to_dataobj( $opts{dataset}, $epdata );
97                 if( defined $dataobj )
98                 {
99                         # Callback
100                         if ( my $code = $plugin->{session}->get_repository->get_conf( "marc" )->{dataobj_callback} ) {
101                                 $epdata = $code->($dataobj);
102                         }
103
104                         push @ids, $dataobj->get_id;
105                 }
106         }
107
108         return EPrints::List->new( 
109                 dataset => $opts{dataset}, 
110                 session => $plugin->{session},
111                 ids=>\@ids );
112 }
113
114 our $debug;
115
116 sub convert_input 
117 {
118
119         my ( $plugin, $marc ) = @_;
120         my $epdata = (); # to be returned
121
122         # Taken from cfg.d/marc.pl
123         my %mappings = %{$plugin->{session}->get_repository->get_conf( "marc" )->{marc2ep}};
124
125         my $dataset = $plugin->{session}->get_dataset('archive');
126
127         foreach my $field ( $marc->fields() ) {             # each field of the record
128                 my $t = $field->tag();
129                 my @list = grep ( /^$t/, keys %mappings );  # lookup for mappings
130                 foreach my $i ( sort @list ) {
131                         ( my $s ) = $i =~ /$t(.)/;          # mapped subfield
132                         my $ts = $t . $s;                   # complete tag+subfield
133                         my $value = $field->as_string($s);
134
135                         my $field = $mappings{$ts} || $plugin->error("no mapping for $ts");
136                         my $metafield = $dataset->get_field($field);
137
138                         $plugin->error("no filed $field") unless $metafield;
139
140                         if ($metafield->get_property('multiple')) {
141                                 warn "# multiple $field in ",ref( $metafield ), "inserting name" if ! $debug->{$field}++;
142                                 $epdata->{$field} = [ { name => $value } ];
143                         } elsif ( defined $epdata->{$field} ) {
144                                 $epdata->{$field} .= "\n" . $value;
145                         } else {
146                                 $epdata->{$field} = $value; # bye!
147                         }
148                 }
149         }
150
151         # Authors
152         my $field = $marc->field('100');
153         if ( defined $field ) {
154                 foreach my $i ( $field->subfield('a') ) {
155                         my $name;
156                         ( $name->{family}, $name->{given} ) = split ( "," , $i );
157                         push @{ $epdata->{creators_name} }, $name if defined $name;
158                 }
159         }
160
161         # Subjects
162         if ( $plugin->{session}->get_repository->get_conf( "marc" )->{importSubjects} ) {
163
164                 if ( $field = $marc->field('650') ) {
165                         foreach my $i ( $field->subfield('a') ) {
166                                 push @{ $epdata->{subjects} }, $i;
167                         }
168                 }
169
170         }
171
172         # Callback
173         if ( my $code = $plugin->{session}->get_repository->get_conf( "marc" )->{epdata_callback} ) {
174                 $epdata = $code->($epdata);
175         }
176
177         return $epdata;
178
179 }
180
181 1;