File Coverage

blib/lib/Webservice/Shipment/Carrier/USPS.pm
Criterion Covered Total %
statement 66 67 98.5
branch 15 24 62.5
condition 1 2 50.0
subroutine 15 16 93.7
pod 6 6 100.0
total 103 115 89.5


line stmt bran cond sub pod time code
1             package Webservice::Shipment::Carrier::USPS;
2              
3 2     2   146090 use Mojo::Base 'Webservice::Shipment::Carrier';
  2         13  
  2         15  
4              
5 2     2   316 use constant DEBUG => $ENV{MOJO_SHIPMENT_DEBUG};
  2         4  
  2         113  
6              
7 2     2   437 use Mojo::Template;
  2         3075  
  2         12  
8 2     2   58 use Mojo::URL;
  2         4  
  2         10  
9 2     2   44 use Mojo::IOLoop;
  2         4  
  2         9  
10 2     2   350 use Time::Piece;
  2         5068  
  2         9  
11              
12             has api_url => sub { Mojo::URL->new('http://production.shippingapis.com/ShippingAPI.dll?API=TrackV2') };
13              
14             has template => <<'XML';
15             % my ($self, $id) = @_;
16            
17            
18             1
19             127.0.0.1
20             Restore Health
21            
22            
23             XML
24              
25             has carrier_description => sub { 'USPS' };
26             has validation_regex => sub { qr/\b(9\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d\d|91\d\d ?\d\d\d\d ?\d\d\d\d ?\d\d\d\d ?\d\d\d\d)\b/i };
27              
28             sub human_url {
29 4     4 1 13 my ($self, $id, $dom) = @_;
30 4         46 return Mojo::URL->new('https://tools.usps.com/go/TrackConfirmAction')->query(tLabels => $id);
31             }
32              
33             sub extract_destination {
34 18     18 1 39 my ($self, $id, $dom, $target) = @_;
35              
36 18         63 my %targets = (
37             postal_code => 'DestinationZip',
38             state => 'DestinationState',
39             city => 'DestinationCity',
40             country => 'DestinationCountryCode',
41             );
42              
43 18 100       56 my $t = $targets{$target} or return;
44 12 100       25 my $addr = $dom->at($t) or return;
45 9         1952 return $addr->text;
46             }
47              
48             sub extract_service {
49 3     3 1 9 my ($self, $id, $dom) = @_;
50 3         9 my $class = $dom->at('Class');
51 3         468 my $service = 'USPS';
52 3 50       9 $service .= ' ' . $class->text if $class;
53 3         93 return $service;
54             }
55              
56             sub extract_status{
57 3     3 1 7 my ($self, $id, $dom) = @_;
58 3         9 my $summary = $dom->at('TrackSummary');
59 3 50       2008 return unless $summary;
60 3         22 my $event = $summary->at('Event')->text;
61 3 50       621 my $delivered = ($event =~ /delivered/i) ? 1 : 0;
62              
63 3         10 my $desc = $dom->at('StatusSummary');
64 3 50       2090 $desc = $desc ? $desc->text : $event;
65              
66 3         89 my $date = $summary->at('EventDate');
67 3 50       477 $date = $date ? $date->text : '';
68 3         82 my $fmt = '%B %d, %Y';
69              
70 3 50       10 if ($date) {
71 3 50       10 if (my $time = $summary->at('EventTime')) {
72 3         415 $time = $time->text;
73 3         73 $date .= " T $time";
74 3         10 $fmt .= ' T %H:%M %p';
75             }
76 3   50     7 $date = eval { Time::Piece->strptime($date, $fmt) } || '';
77 3 50       401 warn $@ if $@;
78             }
79 3         17 return ($desc, $date, $delivered);
80             }
81              
82 3     3 1 13 sub extract_weight { '' }
83              
84             sub request {
85 3     3 1 18 my ($self, $id, $cb) = @_;
86              
87 3         18 my $xml = Mojo::Template->new->render($self->template, $self, $id);
88 3         4141 warn "Request:\n$xml" if DEBUG;
89 3         15 my $url = $self->api_url->clone->query({XML => $xml});
90              
91 3 100       947 unless ($cb) {
92 2         11 my $tx = $self->ua->get($url);
93 2         5022 return _handle_response($tx);
94             }
95              
96             Mojo::IOLoop->delay(
97 1     1   175 sub { $self->ua->get($url, shift->begin) },
98             sub {
99 1     1   2660 my ($ua, $tx) = @_;
100 1 50       12 die $tx->error->{message} unless $tx->success;
101 1         24 my $dom = _handle_response($tx);
102 1         368 $self->$cb(undef, $dom);
103             },
104 1     0   11 )->catch(sub{ $self->$cb(pop, undef) })->wait;
  0         0  
105             }
106              
107             sub _handle_response {
108 3     3   10 my $tx = shift;
109 3         11 my $dom = $tx->res->dom;
110 3         28186 warn "Response:\n$dom\n" if DEBUG;
111 3         20 return $dom->at('TrackResponse TrackInfo');
112             }
113              
114             1;
115              
116             =head1 NAME
117              
118             Webservice::Shipment::Carrier::USPS - USPS handling for Webservice::Shipment
119              
120             =head1 DESCRIPTION
121              
122             Implements USPS handling for L.
123             It is a subclass of L which implements all the necessary methods.
124              
125             =head1 ATTRIBUTES
126              
127             L implements all of the attributes from L and implements the following new ones
128              
129             =head2 template
130              
131             The string template used with L to format the request.
132              
133             =head1 NOTES
134              
135             The service does not provide weight information, so C will always return an empty string.
136