File Coverage

blib/lib/Business/UPS.pm
Criterion Covered Total %
statement 9 99 9.0
branch 0 68 0.0
condition 0 20 0.0
subroutine 4 7 57.1
pod 2 3 66.6
total 15 197 7.6


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 =~ /
(.+)<\/form>/ims and $1 =~ /WebTracking\/processRequest/ ) {
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__