File: fixlocal.pl

package info (click to toggle)
libmarc-perl 1.07-4
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 408 kB
  • ctags: 122
  • sloc: perl: 3,525; makefile: 45
file content (137 lines) | stat: -rw-r--r-- 4,124 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/perl

  # The following example is an expanded version of "addlocal.pl" that
  # checks and fixes existing records in addition to processing new ones.
  # It first looks for a call number subfield 'h' of the 852 field (#852.h).
  # If missing, it then checks #900.a and #999.f for the data. It puts the
  # call number found into all of these locations including any repeated
  # fields. It will create the locations if necessary.

use MARC 0.95;
my $infile = "specials.001";
my $outfile = "output.003";
my $outtext = "output3.txt";
my $outtext2 = "output4.txt";
unlink $outfile, $outtext, $outtext2;

sub fix_update {
    my $subfield = shift;
    my $value = shift;
    my @f = ();
    my $ff;
    my $altered = 0;
    my $fixed = 0;
    while (@_) {
	last unless defined ($ff = shift);
	if ($ff eq "\036") {
	    unless ($fixed) {
	        push @f, $subfield, $value;
	        $altered++;
	    }
	    push @f, $ff;
    	    $fixed = 0;
	    next;
	}
	push @f, $ff;
	unless ($subfield eq $ff) {
	    push @f, shift;
	    next;
	}
	last unless defined ($ff = shift);
	push @f, $value;
	$fixed++;
	if ($value ne $ff) { $altered++; }
    }
    return ($altered,@f);
}

my $loc852 = {record=>1, field=>'852', ordered=>'y'};
my $loc900 = {record=>1, field=>'900', ordered=>'y'}; 
my $loc999 = {record=>1, field=>'999', ordered=>'n'}; 

$x = MARC->new;
$x->openmarc({file=>$infile,'format'=>"usmarc"}) || die;

  # We process records one at a time for this operation. Multiple 852 fields
  # are legal (for multiple copies) - the 'h' subfield should be the same.
  # But a few percent of incoming materials do not include this subfield.

while ($x->nextmarc(1)) {
    my $from999 = "";
    my $from900 = "";
    my ($callno) = $x->getvalue($loc852,'subfield','h');
    my $from852 = (1 == scalar $x->getvalue($loc852)) ? $callno : "";
    unless ($callno) {
	    # "" and '0' are not legal call numbers
        $callno = "";
        ($from900) = $x->getvalue($loc900,'subfield','a');
	if ($from900) {
	    $callno = $from900;
	}
	else {
            ($from999) = $x->getvalue($loc999,'subfield','f');
	    if ($from999) {
	        $callno = $from999;
	    }
	}
    }
    my $change = 0;

    my ($found) = $x->searchmarc($loc999);
    if (defined $found) {
        my @m999 = $x->getupdate($loc999);
	my @f999 = fix_update('f', $callno, @m999);
	if (shift @f999) {
	    $change++;
	    $x->updaterecord ($loc999, @f999) || warn "999 update failed\n";
	}
    }
    else {
        $x->addfield($loc999,'i1',' ','i2',' ', 
                     'c','wL70','d','AR Clinton PL','f',"$callno");
	$change++;
    }

    ($found) = $x->searchmarc($loc900);
    if (defined $found) {
        my @m900 = $x->getupdate($loc900);
	my @f900 = fix_update('a', $callno, @m900);
	if (shift @f900) {
	    $change++;
	    $x->updaterecord ($loc900, @f900) || warn "900 update failed\n";
	}
    }
    else {
        $x->addfield($loc900,'i1',' ','i2',' ','a',"$callno");
	$change++;
    }

    if ($callno && not $from852) {
        ($found) = $x->searchmarc($loc852);
        if (defined $found) {
            my @m852 = $x->getupdate($loc852);
	    my @f852 = fix_update('h', $callno, @m852);
	    if (shift @f852) {
	        $change++;
	        $x->updaterecord ($loc852, @f852) || warn "852 update failed\n";
	    }
        }
        else {
            $x->addfield($loc852,'i1','1','i2',' ','h',"$callno");
	    $change++;
        }
    }

    $x->output({file=>">>$outfile",'format'=>"usmarc"});
    $x->output({file=>">>$outtext",'format'=>"ascii"}) unless $callno;
    $x->output({file=>">>$outtext2",'format'=>"ascii"}) if $change;
    $x->deletemarc(); #empty the object for reading in another
}

  # We write all the records to the output file in MARC format. Even the
  # incomplete ones at least have added the fixed data. The ascii output
  # in $outtext gives the librarian both a list of records requiring manual
  # call number assignment and all the Title, Author, Publication and
  # related data needed to assign location based on standard references.
  # For checking, we write all the modified records to $outtext2.