rename
[migration-tools.git] / ils-specific / unicorn / unicorn_patron_xml2text.pl
1 #!/usr/bin/perl
2 use strict;
3 use warnings;
4
5 use DateTime;
6 use Time::HiRes qw/time/;
7 use XML::LibXML;
8
9 my %s_map;
10
11 my $doc = XML::LibXML->new->parse_file($ARGV[0]);
12
13 my $starttime = time;
14 my $count = 1;
15
16 my @base_elements = (
17     "user_id",
18     "user_altid",
19 #    "user_pin",
20     "user_profile",
21     "user_status",
22     "user_library",
23     "user_priv_granted",
24     "user_priv_expires",
25     "user_mailingaddr",
26     "birthdate",
27     "last_name",
28     "first_name",
29     "middle_name",
30     "suffix_name",
31     "note",
32 #    "note1",
33     "patron",
34     "comment",
35 #    "staff",
36 #    "webcatpref",
37     "user_category1",
38 #    "user_category2",
39     "user_category3",
40 #    "user_category4",
41 #    "dept",
42 #    "guardian",
43 #    "license",
44  #   "aup",
45 #    "photo",
46 #    "notify_via",
47 #    "user_claims_ret",
48 #    "user_environment",
49 #    "user_department",
50     "ums_id",
51     "user_last_activity",
52     "placcard",
53     "user_email",
54 );
55
56 my @addr_elements = (
57     "std_line1",
58     "std_line2",
59     "std_city",
60     "std_state",
61     "std_zip",
62 #    "phone",
63 #    "dayphone",
64     "homephone",
65 #    "workphone",
66 #    "cellphone",
67 #    "email",
68 #    "location",
69 #    "usefor",
70 #    "care_of",
71 #    "known_bad",
72      "ums_addrid",
73 );
74
75 print STDOUT join("\t", @base_elements);
76 foreach my $addr ( 1..3 ) {
77     print STDOUT "\t" . join("\t", @addr_elements);
78 }
79 print STDOUT "\tuserid_active\tinactive_barcode1\tinactive_barcode2";
80 print STDOUT "\n";
81
82 for my $patron ( $doc->documentElement->childNodes ) {
83     next if ($patron->nodeType == 3);
84
85     my $bc = $patron->findvalue( 'user_id' ); $bc =~ s/^\s+//; $bc =~ s/\s+$//;
86     if (exists($s_map{$bc})) {
87         $count++;
88         warn "\n!!! already saw barcode $bc, skipping\n";
89         next;
90     } else {
91         $s_map{$bc} = 1;
92     }
93     
94     unless (defined($bc)) {
95         my $xml = $patron->toString;
96         warn "\n!!! no barcode found in UMS data, user number $count, xml => $xml \n";
97         $count++;
98         next;
99     }
100     
101     foreach my $e ( @base_elements ) {
102         my $v = $patron->findvalue( $e ); $v =~ s/^\s+//; $v =~ s/\s+$//;
103         if ( $v && ( $e eq 'birthdate' || $e eq 'user_priv_granted' || $e eq 'user_priv_expires' ) ) { $v = parse_date($v); }
104         print STDOUT ( $v ? $v : '' ) . "\t";
105     }
106
107     my %addresses;
108     
109     for my $addr ( $patron->findnodes( "Address" ) ) {
110         my $addr_type = $addr->getAttribute('addr_type');
111         $addresses{$addr_type} = $addr;
112     }
113     
114     foreach my $t ( 1..3 ) {
115         if ($addresses{$t}) {
116             foreach my $e ( @addr_elements ) {
117                 my $v;
118                 if ($e eq "known_bad") {
119                     $v = $addresses{$t}->getAttribute( $e ); if ($v) { $v =~ s/^\s+//; $v =~ s/\s+$//; }
120                 } else {
121                     $v = $addresses{$t}->findvalue( $e ); $v =~ s/^\s+//; $v =~ s/\s+$//;
122                 }
123                 print STDOUT ( $v ? $v : '' ) . "\t";
124             }
125         } else {
126             foreach ( @addr_elements ) { print STDOUT "\t"; }
127         }
128     }
129     
130     my $inactive_barcode1 = '';
131     my $inactive_barcode2 = '';
132     my $userid_active = 't';
133     my @barcodes = $patron->findnodes( "barcodes" );
134     for my $i_bc ( $barcodes[0]->findnodes( "barcode" ) ) {
135         my $active = $i_bc->getAttribute('active');
136         if ($active eq "0" && $i_bc->textContent eq $bc) {
137             $userid_active = 'f';
138         }
139         if ($active eq "0" && $i_bc->textContent ne $bc) {
140             if (! $inactive_barcode1 ) {
141                 $inactive_barcode1 = $i_bc->textContent;
142                 $inactive_barcode1 =~ s/^\s+//;
143                 $inactive_barcode1 =~ s/\s+$//;
144             } else {
145                 if (! $inactive_barcode2 ) {
146                     $inactive_barcode2 = $i_bc->textContent;
147                     $inactive_barcode2 =~ s/^\s+//;
148                     $inactive_barcode2 =~ s/\s+$//;
149                 } else {
150                     warn "Extra barcode (" . $i_bc->textContent . ") for user with id = " . $bc . "\n";
151                 }
152             }
153         }
154     }
155     print STDOUT "$userid_active\t$inactive_barcode1\t$inactive_barcode2";
156
157     print STDOUT "\n";
158         $count++;
159 }
160
161 sub parse_date {
162     my $string = shift;
163     my $group = shift;
164
165     my ($y,$m,$d);
166
167     if ($string eq 'NEVER') {
168         my (undef,undef,undef,$d,$m,$y) = localtime();
169         return sprintf('%04d-%02d-%02d', $y + 1920, $m + 1, $d);
170     } elsif (length($string) == 8 && $string =~ /^(\d{4})(\d{2})(\d{2})$/o) {
171         ($y,$m,$d) = ($1,$2,$3);
172     } elsif ($string =~ /(\d+)\D(\d+)\D(\d+)/o) { #looks like it's parsable
173         if ( length($3) > 2 )  { # looks like mm.dd.yyyy
174             if ( $1 < 99 && $2 < 99 && $1 > 0 && $2 > 0 && $3 > 0) {
175                 if ($1 > 12 && $1 < 31 && $2 < 13) { # well, actually it looks like dd.mm.yyyy
176                     ($y,$m,$d) = ($3,$2,$1);
177                 } elsif ($2 > 12 && $2 < 31 && $1 < 13) {
178                     ($y,$m,$d) = ($3,$1,$2);
179                 }
180             }
181         } elsif ( length($1) > 3 ) { # format probably yyyy.mm.dd
182             if ( $3 < 99 && $2 < 99 && $1 > 0 && $2 > 0 && $3 > 0) {
183                 if ($2 > 12 && $2 < 32 && $3 < 13) { # well, actually it looks like yyyy.dd.mm -- why, I don't konw
184                     ($y,$m,$d) = ($1,$3,$2);
185                 } elsif ($3 > 12 && $3 < 31 && $2 < 13) {
186                     ($y,$m,$d) = ($1,$2,$3);
187                 }
188             }
189         } elsif ( $1 < 99 && $2 < 99 && $3 < 99 && $1 > 0 && $2 > 0 && $3 > 0) {
190             if ($3 < 7) { # probably 2000 or greater, mm.dd.yy
191                 $y = $3 + 2000;
192                 if ($1 > 12 && $1 < 32 && $2 < 13) { # well, actually it looks like dd.mm.yyyy
193                     ($m,$d) = ($2,$1);
194                 } elsif ($2 > 12 && $2 < 32 && $1 < 13) {
195                     ($m,$d) = ($1,$2);
196                 }
197             } else { # probably before 2000, mm.dd.yy
198                 $y = $3 + 1900;
199                 if ($1 > 12 && $1 < 32 && $2 < 13) { # well, actually it looks like dd.mm.yyyy
200                     ($m,$d) = ($2,$1);
201                 } elsif ($2 > 12 && $2 < 32 && $1 < 13) {
202                     ($m,$d) = ($1,$2);
203                 }
204             }
205         }
206     }
207
208     my $date = $string;
209     if ($y && $m && $d) {
210         eval {
211             $date = sprintf('%04d-%02d-%-2d',$y, $m, $d)
212               if (new DateTime ( year => $y, month => $m, day => $d ));
213         }
214     }
215     
216     return $date;
217 }
218