fingerprinter tweak
[migration-tools.git] / 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_priv_granted",
23     "user_priv_expires",
24     "user_mailingaddr",
25     "birthdate",
26     "last_name",
27     "first_name",
28     "middle_name",
29     "suffix_name",
30     "note",
31     "comment"
32 );
33
34 my @addr_elements = (
35     "std_line1",
36     "std_line2",
37     "std_city",
38     "std_state",
39     "std_zip",
40     "dayphone",
41     "homephone",
42     "workphone",
43     "email"
44 );
45
46 print STDOUT join("\t", @base_elements);
47 foreach my $addr ( 1..3 ) {
48     print STDOUT "\t" . join("\t", @addr_elements);
49 }
50 print STDOUT "\n";
51
52 for my $patron ( $doc->documentElement->childNodes ) {
53         next if ($patron->nodeType == 3);
54
55         my $bc = $patron->findvalue( 'user_id' );
56         if (exists($s_map{$bc})) {
57                 $count++;
58                 warn "\n!!! already saw barcode $bc, skipping\n";
59                 next;
60         } else {
61                 $s_map{$bc} = 1;
62         }
63
64         unless (defined($bc)) {
65                 my $xml = $patron->toString;
66                 warn "\n!!! no barcode found in UMS data, user number $count, xml => $xml \n";
67                 $count++;
68                 next;
69         }
70
71     foreach my $e ( @base_elements ) {
72         my $v = $patron->findvalue( $e );
73         if ( $v && ( $e eq 'birthdate' || $e eq 'user_priv_granted' || $e eq 'user_priv_expires' ) ) { $v = parse_date($v); }
74         print STDOUT ( $v ? $v : '' ) . "\t";
75     }
76
77         my %addresses;
78
79         for my $addr ( $patron->findnodes( "Address" ) ) {
80                 my $addr_type = $addr->getAttribute('addr_type');
81                 $addresses{$addr_type} = $addr;
82         }
83
84     foreach my $t ( 1..3 ) {
85         if ($addresses{$t}) {
86             foreach my $e ( @addr_elements ) {
87                 my $v = $addresses{$t}->findvalue( $e );
88                 print STDOUT ( $v ? $v : '' ) . "\t";
89             }
90         } else {
91             foreach ( @addr_elements ) { print STDOUT "\t"; }
92         }
93     }
94
95     print STDOUT "\n";
96         $count++;
97 }
98
99 sub parse_date {
100         my $string = shift;
101         my $group = shift;
102
103         my ($y,$m,$d);
104
105         if ($string eq 'NEVER') {
106                 my (undef,undef,undef,$d,$m,$y) = localtime();
107                 return sprintf('%04d-%02d-%02d', $y + 1920, $m + 1, $d);
108         } elsif (length($string) == 8 && $string =~ /^(\d{4})(\d{2})(\d{2})$/o) {
109                 ($y,$m,$d) = ($1,$2,$3);
110         } elsif ($string =~ /(\d+)\D(\d+)\D(\d+)/o) { #looks like it's parsable
111                 if ( length($3) > 2 )  { # looks like mm.dd.yyyy
112                         if ( $1 < 99 && $2 < 99 && $1 > 0 && $2 > 0 && $3 > 0) {
113                                 if ($1 > 12 && $1 < 31 && $2 < 13) { # well, actually it looks like dd.mm.yyyy
114                                         ($y,$m,$d) = ($3,$2,$1);
115                                 } elsif ($2 > 12 && $2 < 31 && $1 < 13) {
116                                         ($y,$m,$d) = ($3,$1,$2);
117                                 }
118                         }
119                 } elsif ( length($1) > 3 ) { # format probably yyyy.mm.dd
120                         if ( $3 < 99 && $2 < 99 && $1 > 0 && $2 > 0 && $3 > 0) {
121                                 if ($2 > 12 && $2 < 32 && $3 < 13) { # well, actually it looks like yyyy.dd.mm -- why, I don't konw
122                                         ($y,$m,$d) = ($1,$3,$2);
123                                 } elsif ($3 > 12 && $3 < 31 && $2 < 13) {
124                                         ($y,$m,$d) = ($1,$2,$3);
125                                 }
126                         }
127                 } elsif ( $1 < 99 && $2 < 99 && $3 < 99 && $1 > 0 && $2 > 0 && $3 > 0) {
128                         if ($3 < 7) { # probably 2000 or greater, mm.dd.yy
129                                 $y = $3 + 2000;
130                                 if ($1 > 12 && $1 < 32 && $2 < 13) { # well, actually it looks like dd.mm.yyyy
131                                         ($m,$d) = ($2,$1);
132                                 } elsif ($2 > 12 && $2 < 32 && $1 < 13) {
133                                         ($m,$d) = ($1,$2);
134                                 }
135                         } else { # probably before 2000, mm.dd.yy
136                                 $y = $3 + 1900;
137                                 if ($1 > 12 && $1 < 32 && $2 < 13) { # well, actually it looks like dd.mm.yyyy
138                                         ($m,$d) = ($2,$1);
139                                 } elsif ($2 > 12 && $2 < 32 && $1 < 13) {
140                                         ($m,$d) = ($1,$2);
141                                 }
142                         }
143                 }
144         }
145
146         my $date = $string;
147         if ($y && $m && $d) {
148                 eval {
149                         $date = sprintf('%04d-%02d-%-2d',$y, $m, $d)
150                                 if (new DateTime ( year => $y, month => $m, day => $d ));
151                 }
152         }
153
154         return $date;
155 }
156