line
stmt
bran
cond
sub
pod
time
code
1
package Business::UPS;
2
3
1
1
69990
use strict;
1
3
1
30
4
1
1
5
use warnings;
1
2
1
23
5
6
1
1
794
use LWP::UserAgent;
1
48162
1
1436
7
require 5.008;
8
9
require Exporter;
10
11
our @ISA = qw(Exporter AutoLoader);
12
13
our @EXPORT = qw/ getUPS UPStrack /;
14
15
# Copyright 2003 Justin Wheeler
16
# Copyright 1998 Mark Solomon (See GNU GPL)
17
# Started 01/07/1998 Mark Solomon
18
19
our $VERSION = '2.02';
20
21
sub getUPS {
22
23
my (
24
0
0
1
$product, $origin, $dest, $weight, $country, $rate_chart, $length,
25
$width, $height, $oversized, $cod
26
) = @_;
27
28
0
0
$country ||= 'US';
29
30
0
my $ups_cgi = 'https://www.ups.com/using/services/rave/qcostcgi.cgi';
31
0
my $workString = "?";
32
0
$workString .= "accept_UPS_license_agreement=yes&";
33
0
$workString .= "10_action=3&";
34
0
$workString .= "13_product=" . $product . "&";
35
0
$workString .= "15_origPostal=" . $origin . "&";
36
0
$workString .= "19_destPostal=" . $dest . "&";
37
0
$workString .= "23_weight=" . $weight;
38
0
0
$workString .= "&22_destCountry=" . $country if $country;
39
0
0
$workString .= "&25_length=" . $length if $length;
40
0
0
$workString .= "&26_width=" . $width if $width;
41
0
0
$workString .= "&27_height=" . $height if $height;
42
0
0
$workString .= "&29_oversized=1" if $oversized;
43
0
0
$workString .= "&47_rate_chart=" . $rate_chart if $rate_chart;
44
0
0
$workString .= "&30_cod=1" if $cod;
45
0
$workString = "${ups_cgi}${workString}";
46
47
0
my $lwp = LWP::UserAgent->new();
48
0
my $result = $lwp->get($workString);
49
50
0
0
Error("Failed fetching data.") unless $result->is_success;
51
52
0
my @ret = split( '%', $result->content );
53
54
0
0
if ( !$ret[5] ) {
55
56
# Error
57
0
return ( undef, undef, $ret[1] );
58
}
59
else {
60
# Good results
61
0
my $total_shipping = $ret[10];
62
0
my $ups_zone = $ret[6];
63
0
return ( $total_shipping, $ups_zone, undef );
64
}
65
}
66
67
sub UPStrack {
68
0
0
1
my $tracking_number = shift;
69
0
my %retValue;
70
71
0
0
$tracking_number || Error("No number to track in UPStrack()");
72
73
0
my $lwp = LWP::UserAgent->new();
74
0
my $result = $lwp->get("https://wwwapps.ups.com/tracking/tracking.cgi?tracknum=$tracking_number");
75
0
0
Error("Cannot get data from UPS") unless $result->is_success();
76
77
0
my $tracking_data = $result->content();
78
0
my %post_data;
79
0
my ( $url, $data );
80
81
0
0
0
if ( ( $url, $data ) = $tracking_data =~ /
82
0
while ( $data =~ s/ //ims ) {
83
0
$post_data{$1} = $2;
84
}
85
}
86
else {
87
0
Error("Cannot parse output from UPS!");
88
}
89
90
0
my ($imagename) = $tracking_data =~ / /;
91
92
0
$post_data{"${imagename}.x"} = 0;
93
0
$post_data{"${imagename}.y"} = 0;
94
95
0
my $result2 = $lwp->post( $url, \%post_data, Referer => "https://wwwaaps.ups.com/tracking/tracking.cgi?tracknum=$tracking_number" );
96
97
0
0
Error("Failed fetching tracking data from UPS!") unless $result2->is_success;
98
99
0
my $raw_data = $result2->content();
100
101
0
$raw_data =~ tr/\r//d;
102
0
$raw_data =~ s/<.*?>//gims;
103
0
$raw_data =~ s/ / /gi;
104
0
$raw_data =~ s/^\s+//gms;
105
0
$raw_data =~ s/\s+$//gms;
106
0
$raw_data =~ s/\s{2,}/ /gms;
107
108
0
my @raw_data = split( /\n/, $raw_data );
109
0
my %scanning;
110
my $progress;
111
0
my $count = 0;
112
0
my $reference;
113
114
0
for ( my $q = 0; $q < @raw_data; $q++ ) {
115
116
# flip thru the text in the page line-by-line
117
0
0
if ( $progress == 1 ) {
118
119
# progress will == 1 when we've found the line that says 'package progress'
120
# which means from here on in, we're tracking the package.
121
122
0
0
if ( $raw_data[$q] =~ /Tracking results provided by UPS: (.+)/ ) {
0
0
0
123
0
$progress = 0;
124
0
$retValue{'Last Updated'} = $1 . ' ' . $raw_data[ $q + 1 ];
125
}
126
elsif ( $raw_data[$q] =~ /\w+\s+\d+,\s+\d+/ ) {
127
128
# would match jun 10, 2003
129
0
$reference = $raw_data[$q];
130
}
131
elsif ( $raw_data[$q] =~ /\d+:\d+\s+\w\.\w\./ ) {
132
133
# matches 2:10 a.m.
134
0
$scanning{ ++$count }{'time'} = $raw_data[$q];
135
136
0
0
$scanning{$count}{'date'} ||= $reference;
137
}
138
elsif ( $raw_data[$q] =~ /,$/ ) {
139
140
# if it ends in a comma, then it's an unfinished location e.g.:
141
# austin,
142
# tx,
143
# us
144
145
0
$scanning{$count}{'location'} .= ' ' . $raw_data[$q];
146
}
147
else {
148
# if all else fails, it's either the last line of the
149
# location, or it's the description. we check that by
150
# seeing if the current location ends in a comma.
151
152
0
0
next unless $scanning{$count}{'date'};
153
154
0
0
if ( $scanning{$count}{'location'} =~ /,$/ ) {
155
0
$scanning{$count}{'location'} .= ' ' . $raw_data[$q];
156
}
157
else {
158
0
$scanning{$count}{'activity'} = $raw_data[$q];
159
}
160
}
161
}
162
else {
163
# html tables make life easy. :)
164
165
0
0
$retValue{'Current Status'} = $raw_data[ $q + 1 ] if uc( $raw_data[$q] ) eq 'STATUS:';
166
167
0
0
$retValue{'Shipped To'} = $raw_data[ $q + 1 ] if uc( $raw_data[$q] ) eq 'SHIPPED TO:';
168
0
0
0
$retValue{'Shipped To'} .= ' ' . $raw_data[ $q + 2 ] if $raw_data[ $q + 1 ] =~ /,$/ and uc( $raw_data[$q] ) eq 'SHIPPED TO:';
169
0
0
0
$retValue{'Shipped To'} .= ' ' . $raw_data[ $q + 3 ] if $raw_data[ $q + 2 ] =~ /,$/ and uc( $raw_data[$q] ) eq 'SHIPPED TO:';
170
171
0
0
$retValue{'Delivered To'} = $raw_data[ $q + 1 ] if uc( $raw_data[$q] ) eq 'DELIVERED TO:';
172
0
0
0
$retValue{'Delivered To'} .= ' ' . $raw_data[ $q + 2 ] if $raw_data[ $q + 1 ] =~ /,$/ and uc( $raw_data[$q] ) eq 'DELIVERED TO:';
173
0
0
0
$retValue{'Delivered To'} .= ' ' . $raw_data[ $q + 3 ] if $raw_data[ $q + 2 ] =~ /,$/ and uc( $raw_data[$q] ) eq 'DELIVERED TO:';
174
175
0
0
$retValue{'Shipped On'} = $raw_data[ $q + 1 ] if uc( $raw_data[$q] ) eq 'SHIPPED OR BILLED ON:';
176
0
0
$retValue{'Service Type'} = $raw_data[ $q + 1 ] if uc( $raw_data[$q] ) eq 'SERVICE TYPE:';
177
0
0
$retValue{'Weight'} = $raw_data[ $q + 1 ] if uc( $raw_data[$q] ) eq 'WEIGHT:';
178
0
0
$retValue{'Delivery Date'} = $raw_data[ $q + 1 ] if uc( $raw_data[$q] ) eq 'DELIVERED ON:';
179
0
0
$retValue{'Signed By'} = $raw_data[ $q + 1 ] if uc( $raw_data[$q] ) eq 'SIGNED BY:';
180
0
0
$retValue{'Location'} = $raw_data[ $q + 1 ] if uc( $raw_data[$q] ) eq 'LOCATION:';
181
182
0
0
$progress = 1 if uc( $raw_data[$q] ) eq 'PACKAGE PROGRESS:';
183
}
184
}
185
186
0
$retValue{'Scanning'} = \%scanning;
187
0
$retValue{'Activity Count'} = $count;
188
0
$retValue{'Notice'} = "UPS authorizes you to use UPS tracking systems solely to track shipments tendered by or for you to UPS for delivery and for no other purpose. Any other use of UPS tracking systems and information is strictly prohibited.";
189
190
0
return %retValue;
191
}
192
193
sub Error {
194
0
0
0
my $error = shift;
195
0
print STDERR "$error\n";
196
0
exit(1);
197
}
198
199
1
END { }
200
201
# Autoload methods go after =cut, and are processed by the autosplit program.
202
203
1;
204
205
__END__