File Coverage

blib/lib/Business/UPS.pm
Criterion Covered Total %
statement 10 100 10.0
branch 0 68 0.0
condition 0 20 0.0
subroutine 4 7 57.1
pod 2 3 66.6
total 16 198 8.0


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