more better err file
[migration-tools.git] / fingerprints.pl
1 #!/usr/bin/perl
2 use strict;
3 use warnings;
4
5 use open ':utf8';
6 use MARC::Batch;
7 use MARC::File::XML ( BinaryEncoding => 'utf-8' );
8 use MARC::Field;
9 use Unicode::Normalize;
10
11 my $count = 0;
12 my $runtype = shift;
13 my $id_tag = shift;
14 my $id_subfield = shift;
15
16 binmode(STDOUT, ':utf8');
17 binmode(STDIN, ':utf8');
18
19 for my $file (@ARGV) {
20
21     print STDERR "Processing $file\n";
22
23     open my $M, '<:utf8', $file;
24
25     my $batch = MARC::Batch->new('XML',$M);
26     $batch->strict_off();
27     $batch->warnings_off();
28
29     while ( my $record = $batch->next ) {
30         $count++;
31
32         my $id = $record->field($id_tag);
33         if (!$id) {
34             print STDERR "ERROR: This record is missing a $id_tag field.\n"
35               . $record->as_formatted() . "\n=====\n";
36             next;
37         }
38         $id = $id->as_string($id_subfield);
39
40         my $leader = $record->leader();
41         my $record_type = substr($leader,6,1);
42         my $bib_lvl = substr($leader,7,1);
43
44         my $my_008 = $record->field('008');
45         $my_008 = $my_008->as_string() if ($my_008);
46         my $date1 = substr($my_008,7,4) if ($my_008);
47         my $date2 = substr($my_008,11,4) if ($my_008);
48
49         my $item_form;
50         if ( $record_type =~ /[gkroef]/ ) { # MAP, VIS
51             $item_form = substr($my_008,29,1) if ($my_008);
52         } else {
53             $item_form = substr($my_008,23,1) if ($my_008);
54         }
55
56         my $title = $record->field('245');
57         $title = $title->subfield('a') if $title;
58
59         my @isbns = ();
60         my @isbns_020;
61         if ($record->field('020')) { @isbns_020 = $record->field('020'); }
62         foreach my $f ( @isbns_020 ) {
63             if ($f->subfield('a')) {
64                 if ( $f->subfield('a')=~/(\S+)/ ) {
65                     push @isbns, $1;
66                 }
67             }
68         }
69         my @isbns_024;
70         if ($record->field('024')) { @isbns_024 = $record->field('024'); }
71         foreach my $f ( @isbns_024 ) {
72             if ($f->subfield('a')) {
73                 if ( $f->subfield('a')=~/(\S+)/ ) {
74                     push @isbns, $1;
75                 }
76             }
77         }
78
79         my $issn = $record->field('022');
80         $issn = $issn->subfield('a') if $issn;
81
82         my $lccn = $record->field('010');
83         $lccn = $lccn->subfield('a') if $lccn;
84
85         my $author;
86         if ($record->field('100'))
87           { $author = $record->field('100')->subfield('a'); }
88         unless ( $author ) {
89             $author = $record->field('110')->subfield('a')
90               if ($record->field('110'));
91             $author = $record->field('111')->subfield('a')
92               if ($record->field('111'));
93         }
94
95         my $desc = $record->field('300');
96         $desc = $desc->subfield('a') if $desc;
97
98         my $pages;
99         $pages = $1 if (defined $desc and $desc =~ /(\d+)/);
100
101         my $my_260 = $record->field('260');
102         my $publisher = $my_260->subfield('b') if $my_260;
103         my $pubyear = $my_260->subfield('c') if $my_260;
104         if ( $pubyear ) {
105             if ( $pubyear =~ /(\d\d\d\d)/ )
106               { $pubyear = $1; }
107             else
108               { $pubyear = ''; }
109         }
110
111         my $edition = $record->field('250');
112         $edition = $edition->subfield('a') if $edition;
113
114         # NORMALIZE
115         $record_type = 'a' if ($record_type eq ' ');
116         if ($title) {
117             $title = NFD($title); $title =~ s/[\x{80}-\x{ffff}]//go;
118             $title = lc($title);
119             $title =~ s/\W+$//go;
120         }
121         if ($author) {
122             $author = NFD($author); $author =~ s/[\x{80}-\x{ffff}]//go;
123             $author = lc($author);
124             $author =~ s/\W+$//go;
125             if ($author =~ /^(\w+)/) {
126                 $author = $1;
127             }
128         }
129         if ($publisher) {
130             $publisher = NFD($publisher); $publisher =~ s/[\x{80}-\x{ffff}]//go;
131             $publisher = lc($publisher);
132             $publisher =~ s/\W+$//go;
133             if ($publisher =~ /^(\w+)/) {
134                 $publisher = $1;
135             }
136         }
137
138         # SPIT OUT FINGERPRINTS FROM THE "LOIS ALGORITHM"
139         # If we're not getting good matches, we may want to change this.
140         # The same thing goes for some other fields.
141         if ($item_form && ($date1 =~ /\d\d\d\d/)
142             && $record_type && $bib_lvl && $title) {
143             if ($runtype eq "primary") {
144                 print STDOUT
145                   join("\t",$id,$item_form,$date1,$record_type,$bib_lvl,$title)
146                     ,"\n";
147             } else {
148                 # case a : isbn and pages
149                 if (scalar(@isbns)>0 && $pages) {
150                     foreach my $isbn ( @isbns ) {
151                         print STDOUT
152                           join("\t", $id, "case a", $item_form, $date1,
153                                $record_type, $bib_lvl, $title, $isbn, $pages)
154                             ,"\n";
155                     }
156                 }
157                 # case b : edition
158                 if ($edition) {
159                     print STDOUT
160                       join("\t", $id, "case b", $item_form, $date1,
161                            $record_type, $bib_lvl, $title,$edition), "\n";
162                 }
163                 # case c : issn
164                 if ($issn) {
165                     print STDOUT join("\t", $id, "case c", $item_form, $date1,
166                                       $record_type, $bib_lvl, $title, $issn)
167                       ,"\n"; 
168                 }
169                 # case d : lccn
170                 if ($lccn) {
171                     print STDOUT join("\t", $id, "case d", $item_form, $date1,
172                                       $record_type, $bib_lvl, $title, $lccn)
173                       ,"\n";
174                 }
175                 # case e : author, publisher, pubyear, pages
176                 if ($author && $publisher && $pubyear && $pages) {
177                     print STDOUT join("\t", $id, "case e", $item_form, $date1,
178                                       $record_type, $bib_lvl, $title, $author,
179                                       $publisher, $pubyear, $pages), "\n";
180                 }
181             }
182         } else {
183             print STDERR "Record " . $id . " did not make the cut: ";
184             print STDERR "Missing item_form. " unless ($item_form);
185             print STDERR "Missing valid date1. " unless ($date1 =~ /\d\d\d\d/);
186             print STDERR "Missing record_type. " unless ($record_type);
187             print STDERR "Missing bib_lvl. " unless ($bib_lvl);
188             print STDERR "Missing title. " unless ($title);
189             print STDERR "\n";
190         }
191     }
192     print STDERR "Processed $count records\n";
193 }