File Coverage

blib/lib/Business/US/USPS/WebTools.pm
Criterion Covered Total %
statement 38 68 55.8
branch 5 10 50.0
condition 2 8 25.0
subroutine 13 21 61.9
pod 6 6 100.0
total 64 113 56.6


line stmt bran cond sub pod time code
1 3     3   2387 use v5.10;
  3         9  
2 3     3   1855 use utf8;
  3         23  
  3         13  
3              
4             package Business::US::USPS::WebTools;
5 3     3   117 use strict;
  3         7  
  3         74  
6 3     3   16 no warnings 'uninitialized';
  3         4  
  3         135  
7              
8 3     3   14 use Carp qw(croak);
  3         5  
  3         159  
9              
10 3     3   2340 use subs qw();
  3         58  
  3         73  
11 3     3   14 use vars qw($VERSION);
  3         5  
  3         1964  
12              
13             $VERSION = '1.12_01';
14              
15             =encoding utf8
16              
17             =head1 NAME
18              
19             Business::US::USPS::WebTools - Use the US Postal Service Web Tools
20              
21             =head1 SYNOPSIS
22              
23             use Business::US::USPS::WebTools;
24              
25             # see subclasses for API details
26              
27             =head1 DESCRIPTION
28              
29             *** THIS IS ALPHA SOFTWARE ***
30              
31             This is the base class for the WebTools web service from the US Postal
32             Service. The USPS offers several services, and this module handles the
33             parts common to all of them: making the request, getting the response,
34             parsing error reponses, and so on. The interesting stuff happens in
35             one of the subclasses which implement a particular service. So far,
36             the only subclass in this distribution is
37             C.
38              
39             =over
40              
41             =cut
42              
43             my $LiveServer = "production.shippingapis.com";
44             my $TestServer = "testing.shippingapis.com";
45              
46             =item new( ANONYMOUS_HASH )
47              
48             Make the web service object. Pass is an anonymous hash with these keys:
49              
50             UserID the user id provided by the USPS
51             Password the password provided by the USPS
52             Testing true or false, to select the right server
53              
54             If you don't pass the UserID or Password entries, C looks in the
55             environment variables USPS_WEBTOOLS_USERID and USPS_WEBTOOLS_PASSWORD.
56              
57             If C cannot find both the User ID and the Password, it croaks.
58              
59             If you pass a true value with the Testing key, the object will use the
60             testing server host name and the testing URL path. If the Testing key
61             is false or not present, the object uses the live server details.
62              
63             =cut
64              
65             sub new {
66 3     3 1 3573 my( $class, $args ) = @_;
67              
68             my $user_id = $args->{UserID} || $ENV{USPS_WEBTOOLS_USERID} ||
69 3   0     15 croak "No user ID for USPS WebTools!";
70              
71             my $password = $args->{Password} || $ENV{USPS_WEBTOOLS_PASSWORD} ||
72 3   0     10 croak "No password for USPS WebTools!";
73              
74 3         5 $args->{UserID} = $user_id;
75 3         5 $args->{Password} = $password;
76 3   100     16 $args->{testing} = $args->{Testing} || 0;
77 3         8 $args->{live} = ! $args->{Testing};
78              
79 3         10 bless $args, $class;
80             }
81              
82 6     6   33 sub _testing { $_[0]->{testing} }
83 8     8   42 sub _live { $_[0]->{live} }
84              
85             =item userid
86              
87             Returns the User ID for the web service. You need to get this from the
88             US Postal Service.
89              
90             =item password
91              
92             Returns the Password for the web service. You need to get this from the
93             US Postal Service.
94              
95             =item url
96              
97             Returns the URL for the request to the web service. So far, all requests
98             are GET request with all of the data in the query string.
99              
100             =item response
101              
102             Returns the response from the web service. This is the slightly modified
103             response. So far it only fixes up line endings and normalizes some error
104             output for inconsistent responses from different physical servers.
105              
106             =cut
107              
108 0     0 1 0 sub userid { $_[0]->{UserID} }
109 0     0 1 0 sub password { $_[0]->{Password} }
110              
111 0 0   0 1 0 sub url { $_[0]->{url} || $_[0]->_make_url }
112 0     0 1 0 sub response { $_[0]->{response} }
113              
114             sub _api_host {
115 3     3   7 my $self = shift;
116              
117 3 100       9 if( $self->_testing ) { $TestServer }
  1 50       5  
118 2         9 elsif( $self->_live ) { $LiveServer }
119 0         0 else { die "Am I testing or live?" }
120             }
121              
122             sub _api_path {
123 3 100   3   9 $_[0]->_live ?
124             "/ShippingAPI.dll"
125             :
126             "/ShippingAPITest.dll"
127             }
128              
129             sub _make_query_string {
130 0     0     require URI;
131              
132 0           my( $self, $hash ) = @_;
133              
134 0           my $xml = $self->_make_query_xml( $hash );
135              
136 0           my $uri = URI->new;
137 0           $uri->query_form(
138             API => $self->_api_name,
139             XML => $xml,
140             );
141              
142 0           $uri->query; # this should work, but doesn't
143             }
144              
145             sub _make_url {
146 0     0     my( $self, $hash ) = @_;
147              
148 0           $self->{url} = qq|http://| . $self->_api_host . $self->_api_path .
149             "?" . $self->_make_query_string( $hash );
150             }
151              
152             sub _make_request {
153 0     0     my( $self, $url ) = @_;
154 0           require LWP::Simple;
155              
156 0           $self->{error} = undef;
157              
158 0           $self->{response} = LWP::Simple::get( $self->url );
159 0           $self->{response} =~ s/\015\012/\n/g;
160              
161 0           $self->is_error;
162              
163 3     3   5137588 use Data::Dumper;
  3         24362  
  3         1128  
164             # print STDERR "In _make_request:\n" . Dumper( $self ) . "\n";
165              
166 0           $self->{response};
167             }
168              
169             =item is_error
170              
171             Returns true if the response to the last request was an error, and false
172             otherwise.
173              
174             If the response was an error, this method sets various fields in the
175             object:
176              
177             $self->{error}{number}
178             $self->{error}{source}
179             $self->{error}{description}
180             $self->{error}{help_file}
181             $self->{error}{help_context}
182              
183             =cut
184              
185             sub is_error {
186 0     0 1   my $self = shift;
187              
188 0 0         return 0 unless $self->response =~ "";
189              
190 0           $self->{error} = {};
191              
192             # Apparently not all servers return this string in the
193             # same way. Some have SOL and some have SoL
194 0           $self->{response} =~ s/SOLServer/SOLServer/ig;
195              
196 0           ( $self->{error}{number} ) = $self->response =~ m|(-?\d+)|g;
197 0           ( $self->{error}{source} ) = $self->response =~ m|(.*?)|g;
198 0           ( $self->{error}{description} ) = $self->response =~ m|(.*?)|g;
199 0           ( $self->{error}{help_file} ) = $self->response =~ m|(.*?)|ig;
200 0           ( $self->{error}{help_context} ) = $self->response =~ m|(.*?)|ig;
201              
202 0           1;
203             }
204              
205             =back
206              
207             =head1 SEE ALSO
208              
209             The WebTools API is documented on the US Postal Service's website:
210              
211             http://www.usps.com/webtools/htm/Address-Information.htm
212              
213             =head1 SOURCE AVAILABILITY
214              
215             This source is in GitHub:
216              
217             https://github.com/briandfoy/business-us-usps-webtools
218              
219             =head1 AUTHOR
220              
221             brian d foy, C<< >>
222              
223             =head1 COPYRIGHT AND LICENSE
224              
225             Copyright © 2006-2016, brian d foy . All rights reserved.
226              
227             This program is free software; you can redistribute it and/or modify
228             it under the same terms as Perl itself.
229              
230             =cut
231              
232             1;