File Coverage

blib/lib/Business/Shipping/Config.pm
Criterion Covered Total %
statement 91 134 67.9
branch 13 24 54.1
condition 0 10 0.0
subroutine 28 33 84.8
pod 8 10 80.0
total 140 211 66.3


line stmt bran cond sub pod time code
1             package Business::Shipping::Config;
2              
3             =head1 NAME
4              
5             Business::Shipping::Config - Configuration functions
6              
7             =head1 DESCRIPTION
8              
9             Among other things, this module implements a simple API on top of the
10             Config::IniFiles module.
11              
12             =head1 METHODS
13              
14             =cut
15              
16 13     13   80 use strict;
  13         148  
  13         495  
17 13     13   71 use warnings;
  13         25  
  13         427  
18              
19 13     13   66 use constant DEFAULT_CONFIG_DIR => '/usr/local/B_Shipping/config';
  13         21  
  13         905  
20              
21             #use constant DEFAULT_CONFIG_DIR => '~_~DEFAULT_CONFIG_DIR~_~';
22              
23 13     13   67 use constant DEFAULT_DATA_DIR => '/usr/local/B_Shipping/data';
  13         21  
  13         631  
24              
25             #use constant DEFAULT_DATA_DIR => '~_~DEFAULT_DATA_DIR~_~';
26              
27 13     13   70 use base ('Exporter');
  13         24  
  13         1316  
28 13     13   45788 use Config::IniFiles;
  13         751293  
  13         543  
29 13     13   223 use Business::Shipping::Logging;
  13         32  
  13         738  
30 13     13   166 use Carp;
  13         33  
  13         725  
31 13     13   97 use Cwd;
  13         30  
  13         811  
32 13     13   12331 use version; our $VERSION = qv('400');
  13         27831  
  13         1063  
33 13     13   1299 use vars qw(@EXPORT);
  13         30  
  13         18246  
34              
35             @EXPORT = qw/ cfg cfg_obj config_to_hash config_to_ary_of_hashes /;
36             $Business::Shipping::Config::config_dir = '';
37             $Business::Shipping::Config::data_dir = '';
38             $Business::Shipping::Config::main_config_file = '';
39             $Business::Shipping::Config::data_dir_test_filename = 'this_is_the_data_dir';
40              
41             sub data_dir_test_filename {
42 26     26 0 342 return $Business::Shipping::Config::data_dir_test_filename;
43             }
44              
45             # Try the current directory first.
46             if (-f './config/config.ini') {
47             $Business::Shipping::Config::config_dir = './config';
48             }
49             if (-f './data/' . data_dir_test_filename()) {
50             $Business::Shipping::Config::data_dir = './data';
51             }
52             elsif (-f '../Business-Shipping-DataFiles/data/' . data_dir_test_filename()) {
53             $Business::Shipping::Config::data_dir
54             = '../Business-Shipping-DataFiles/data/';
55             }
56              
57             # Then try environment variables
58             $Business::Shipping::Config::data_dir ||= $ENV{B_SHIPPING_DATA_DIR};
59             $Business::Shipping::Config::config_dir ||= $ENV{B_SHIPPING_CONFIG_DIR};
60              
61             # Then fall back on the default.
62             $Business::Shipping::Config::data_dir ||= DEFAULT_DATA_DIR;
63             $Business::Shipping::Config::config_dir ||= DEFAULT_CONFIG_DIR;
64              
65             my $cwd = Cwd::getcwd;
66             die "Config dir could not be found. Current working dir: $cwd."
67             if (!-d $Business::Shipping::Config::config_dir);
68             die "Data dir could not be found. Current working dir: $cwd."
69             if (!-d $Business::Shipping::Config::config_dir);
70              
71             $Business::Shipping::Config::main_config_file
72             = "$Business::Shipping::Config::config_dir/config.ini";
73              
74             if (!-f $Business::Shipping::Config::main_config_file) {
75             die "Could not open main configuration file: "
76             . "$Business::Shipping::Config::main_config_file: $!";
77             }
78              
79             # Number of times to try for online requrests. See Online.pm.
80             $Business::Shipping::Config::Try_Limit = 2;
81              
82             tie my %cfg, 'Config::IniFiles',
83             (-file => $Business::Shipping::Config::main_config_file);
84             my $cfg_obj = Config::IniFiles->new(
85             -file => $Business::Shipping::Config::main_config_file);
86              
87             =head2 cfg()
88              
89             Returns config hashref.
90              
91             =head2 cfg_obj()
92              
93             Returns config hashref.
94              
95             =head2 support_files()
96              
97             Returns the path of the support_files directory.
98              
99             =cut
100              
101 1     1 1 13 sub cfg { return \%cfg; }
102 0     0 1 0 sub cfg_obj { return $cfg_obj; }
103 0     0 1 0 sub data_dir { return $Business::Shipping::Config::data_dir }
104 13     13 0 46 sub config_dir { return $Business::Shipping::Config::config_dir }
105              
106             =head2 config_to_hash( $ary, $del )
107              
108             $ary Key/value pairs
109             $del Delimiter for the above array (tab is default)
110              
111             Builds a hash from an array of lines containing key / value pairs, like so:
112              
113             key1 value1
114             key2 value2
115             key3 value3
116              
117             =cut
118              
119             sub config_to_hash {
120 0     0 1 0 my ($ary, $delimiter) = @_;
121 0 0 0     0 return unless $ary and ref($ary) eq 'ARRAY';
122              
123 0   0     0 $delimiter ||= "\t";
124 0         0 my $hash = {};
125              
126 0         0 foreach my $line (@$ary) {
127 0         0 my ($key, $val) = split($delimiter, $line);
128 0         0 $hash->{$key} = $val;
129             }
130              
131 0         0 return $hash;
132             }
133              
134             =head2 config_to_ary_of_hashes( 'configuration_parameter' )
135              
136             Reads in the configuration hashref ( e.g. cfg()->{ primary }->{ secondary } ),
137             then returns an array of hashes. For example:
138              
139             This:
140              
141             [invalid_rate_requests]
142             invalid_rate_requests_ups=<
143             service=XDM to_country=Canada reason=Not available.
144             service=XDM to_country=Brazil
145             EOF
146              
147             When called with this:
148              
149             my @invalid_rate_requests_ups = config_to_ary_of_hashes(
150             cfg()->{ invalid_rate_requests }->{ invalid_rate_requests_ups }
151             );
152              
153             Returns this:
154              
155             [
156             {
157             service => 'XDM',
158             to_country => 'Canada',
159             reason => 'Not available.',
160             },
161             {
162             service => 'XDM',
163             to_country => 'Brazil',
164             },
165             ]
166              
167             =cut
168              
169             sub config_to_ary_of_hashes {
170 0     0 1 0 my ($cfg) = @_;
171              
172 0         0 my @ary;
173 0         0 foreach my $line (@$cfg) {
174              
175             # Convert multiple tabs into one tab, remove the leading tab.
176             # Split on the tabs to get key=val pairs, then split on the '='.
177 0         0 $line =~ s/\t+/\t/g;
178 0         0 $line =~ s/^\t//;
179 0         0 my @key_val_pairs = split("\t", $line);
180 0 0       0 next unless @key_val_pairs;
181              
182             # Each line becomes a hash.
183 0         0 my $hash = {};
184 0         0 foreach my $key_val_pair (@key_val_pairs) {
185 0         0 my ($key, $val) = split('=', $key_val_pair);
186 0 0 0     0 next unless (defined $key and defined $val);
187 0         0 $hash->{$key} = $val;
188             }
189              
190 0 0       0 push @ary, $hash if (%$hash);
191             }
192              
193 0         0 return @ary;
194             }
195              
196             =head2 data_dir_name()
197              
198             The name of the data_dir (e.g. "data").
199              
200             =cut
201              
202             sub data_dir_name {
203              
204             # name only.
205 0   0 0 1 0 return cfg()->{general}->{data_dir_name} || 'data';
206             }
207              
208             =head2 data_dir()
209              
210             The path of the data_dir (e.g. "/var/perl/Business-Shipping/data").
211              
212             =cut
213              
214             =head2 get_req_mod()
215              
216             Return a list of the required modules for a given shipper. Return all if no
217             shipper is given.
218              
219             =cut
220              
221             sub get_req_mod {
222 12     12 1 831 my (%opt) = @_;
223 12         31 my $shipper = $opt{shipper};
224              
225 12         144 my $req_mod = {
226             'Minimum' => [
227             qw/
228             Any::Moose
229             Log::Log4perl
230             Business::Shipping
231             /
232             ],
233             'UPS_Offline' => [
234             qw/
235             Business::Shipping::DataFiles
236             Config::IniFiles
237             /
238             ],
239             'UPS_Online' => [
240             qw/
241             CHI
242             Crypt::SSLeay
243             Date::Parse
244             LWP::UserAgent
245             XML::DOM
246             XML::Simple
247             /
248             ],
249             'USPS_Online' => [
250             qw/
251             CHI
252             Crypt::SSLeay
253             Date::Parse
254             LWP::UserAgent
255             XML::DOM
256             XML::Simple
257             /
258             ],
259              
260             };
261 12 100       64 if ($opt{get_hash}) {
262 11         40 return $req_mod;
263             }
264 1 50       4 if ($shipper) {
265 1         3 my $module_list = $req_mod->{$shipper};
266 1         7 return @$module_list;
267             }
268             else {
269 0         0 my @all_modules;
270 0         0 foreach my $key (keys %$req_mod) {
271 0         0 my $module_list = $req_mod->{$shipper};
272 0         0 push @all_modules, @$module_list;
273             }
274 0         0 return @all_modules;
275             }
276             }
277              
278             =head2 calc_req_mod()
279              
280             Determine if the required modules for each shipper are available, in turn.
281              
282             =cut
283              
284             sub calc_req_mod {
285 11     11 1 1774 my ($one_shipper) = @_;
286              
287 11         30 my @avail;
288 11         56 my $req_mod = get_req_mod(get_hash => 1);
289              
290 11 100       47 if ($one_shipper) {
291 9         48 foreach my $shipper (keys %$req_mod) {
292 36 100       99 if ($shipper ne $one_shipper) {
293 27         82 delete $req_mod->{$shipper};
294             }
295             }
296             }
297 11         34 my @to_load;
298 11         69 SHIPPER: while (my ($shipper, $list) = each %$req_mod) {
299 17         42 @to_load = ();
300 17         47 MODULE: foreach my $module (@$list) {
301 10     10   10738 eval "use $module";
  0     1   0  
  0     1   0  
  1     1   615  
  0     1   0  
  0     1   0  
  1     1   379  
  0     1   0  
  0     1   0  
  1     1   5  
  1     1   3  
  1     1   12  
  1         6  
  1         2  
  1         11  
  1         5  
  1         4  
  1         8  
  1         57  
  1         2  
  1         6  
  1         6  
  1         2  
  1         6  
  1         7  
  1         2  
  1         6  
  1         472  
  0         0  
  0         0  
  1         450  
  0         0  
  0         0  
  1         482  
  0         0  
  0         0  
  21         2542  
302 21 100       1743 if ($@) {
303 15         36 $@ = '';
304              
305             # "Could not load $module";
306 15         124 next SHIPPER;
307             }
308             else {
309 6         13 push @to_load, $module;
310 6         14 next MODULE;
311             }
312             }
313 2 50       7 if (!$@) {
314 2         10 push @avail, $shipper;
315             }
316             }
317 11 100       51 if ($one_shipper) {
318 9 50       42 if (grep $one_shipper, @avail) {
319 0         0 return 1;
320             }
321             else {
322 9         57 return 0;
323             }
324             }
325             else {
326 2         17 return @avail;
327             }
328             }
329             1;
330              
331             __END__