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