31301e120cd921161735ed069e7589e656106ab9
[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         eval {
30             $count++;
31             $record = $batch->next();
32
33             my $id = $record->field($id_tag);
34             if (!$id) {
35                 print STDERR "ERROR: This record is missing a $id_tag field.\n" . $record->as_formatted() . "\n=====\n";
36                 next;
37             }
38             $id = $id->as_string($id_subfield);
39             print STDERR "WARNINGS: Record id " . $id . " : " .  join(":",@warnings) . " : continuing...\n" if ( @warnings );
40
41             my $leader = $record->leader();
42             my $record_type = substr($leader,6,1);
43             my $bib_lvl = substr($leader,7,1);
44
45             my $my_008 = $record->field('008');
46                 $my_008 = $my_008->as_string() if ($my_008);
47             my $date1 = substr($my_008,7,4) if ($my_008);
48             my $date2 = substr($my_008,11,4) if ($my_008);
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                 if ( $title ) { $title = $title->subfield('a'); }
58             
59             my @isbns = ();
60             my @isbns_020; if ($record->field('020')) { @isbns_020 = $record->field('020'); }
61             foreach my $f ( @isbns_020 ) { if ($f->subfield('a')) { if ( $f->subfield('a')=~/(\S+)/ ) { push @isbns, $1; } } }
62             my @isbns_024; if ($record->field('024')) { @isbns_024 = $record->field('024'); }
63             foreach my $f ( @isbns_024 ) { if ($f->subfield('a')) { if ( $f->subfield('a')=~/(\S+)/ ) { push @isbns, $1; } } }
64
65             my $issn = $record->field('022');
66                 if ( $issn ) { $issn = $issn->subfield('a'); }
67             my $lccn = $record->field('010');
68                 if ( $lccn ) { $lccn = $lccn->subfield('a'); }
69             my $author;
70                 if ($record->field('100')) { $author = $record->field('100')->subfield('a'); }
71                 if (! $author ) {
72                     if ($record->field('110')) { $author = $record->field('110')->subfield('a'); }
73                 }
74                 if (! $author ) {
75                     if ($record->field('111')) { $author = $record->field('111')->subfield('a'); }
76                 }
77             my $desc = $record->field('300');
78                 if ( $desc ) { $desc = $desc->subfield('a'); }
79             my $pages;
80                 if ($desc =~ /(\d+)/) { $pages = $1; }
81             my $my_260 = $record->field('260');
82             my $publisher = $my_260->subfield('b') if ( $my_260 );
83             my $pubyear = $my_260->subfield('c') if ( $my_260 );
84                 if ( $pubyear ) { 
85                     if ( $pubyear =~ /(\d\d\d\d)/ ) { $pubyear = $1; } else { $pubyear = ''; }
86                 }
87             my $edition = $record->field('250');
88                 if ( $edition ) { $edition = $edition->subfield('a'); }
89
90             # NORMALIZE
91             if ($record_type == ' ') { $record_type = 'a'; }
92             if ($title) {
93                 $title = NFD($title); $title =~ s/[\x{80}-\x{ffff}]//go;
94                 $title = lc($title);
95                 $title =~ s/\W+$//go;
96             }
97             if ($author) {
98                 $author = NFD($author); $author =~ s/[\x{80}-\x{ffff}]//go;
99                 $author = lc($author);
100                 $author =~ s/\W+$//go;
101                 if ($author =~ /^(\w+)/) {
102                     $author = $1;
103                 }
104             }
105             if ($publisher) {
106                 $publisher = NFD($publisher); $publisher =~ s/[\x{80}-\x{ffff}]//go;
107                 $publisher = lc($publisher);
108                 $publisher =~ s/\W+$//go;
109                 if ($publisher =~ /^(\w+)/) {
110                     $publisher = $1;
111                 }
112             }
113
114             # SPIT OUT FINGERPRINTS FROM THE "LOIS ALGORITHM"
115             # If we're not getting good matches, we may want to change this.  The same thing goes for some other fields.
116             if ($item_form && ($date1 =~ /\d\d\d\d/) && $record_type && $bib_lvl && $title) {
117
118                 if ($which eq "primary") {
119                     print STDOUT join("\t",$id,$item_form,$date1,$record_type,$bib_lvl,$title) . "\n"; 
120                 } else {
121                 
122                     # case a : isbn and pages
123                     if (scalar(@isbns)>0 && $pages) {
124                         foreach my $isbn ( @isbns ) {
125                             print STDOUT join("\t",$id,"case a",$item_form,$date1,$record_type,$bib_lvl,$title,$isbn,$pages) . "\n"; 
126                         }
127                     }
128
129                     # case b : edition
130                     if ($edition) {
131                         print STDOUT join("\t",$id,"case b",$item_form,$date1,$record_type,$bib_lvl,$title,$edition) . "\n"; 
132                     }
133
134                     # case c : issn
135                     if ($issn) {
136                         print STDOUT join("\t",$id,"case c",$item_form,$date1,$record_type,$bib_lvl,$title,$issn) . "\n"; 
137                     }
138
139                     # case d : lccn
140                     if ($lccn) {
141                         print STDOUT join("\t",$id,"case d",$item_form,$date1,$record_type,$bib_lvl,$title,$lccn) . "\n"; 
142                     }
143
144                     # case e : author, publisher, pubyear, pages
145                     if ($author && $publisher && $pubyear && $pages) {
146                         print STDOUT join("\t",$id,"case e",$item_form,$date1,$record_type,$bib_lvl,$title,$author,$publisher,$pubyear,$pages) . "\n"; 
147                     }
148
149                 }
150
151             } else {
152                 print STDERR "Record " . $id . " did not make the cut: ";
153                 print STDERR "Missing item_form. " unless ($item_form);
154                 print STDERR "Missing valid date1. " unless ($date1 =~ /\d\d\d\d/);
155                 print STDERR "Missing record_type. " unless ($record_type);
156                 print STDERR "Missing bib_lvl. " unless ($bib_lvl);
157                 print STDERR "Missing title. " unless ($title);
158                 print STDERR "\n";
159
160             }
161         }
162         print STDERR "Trapped exception for MARC::Batch->next on record $count: $@\n" if ($@);
163         }
164     print STDERR "Processed $count records\n";
165 }