File Coverage

blib/lib/WebService/IFConfig/Client.pm
Criterion Covered Total %
statement 50 50 100.0
branch 5 6 83.3
condition n/a
subroutine 18 18 100.0
pod 7 8 87.5
total 80 82 97.5


line stmt bran cond sub pod time code
1 1     1   89595 use strict;
  1         4  
  1         37  
2 1     1   6 use warnings;
  1         3  
  1         42  
3 1     1   18 use 5.12.0;
  1         9  
4              
5 1     1   403 use REST::Client;
  1         55129  
  1         33  
6 1     1   758 use JSON;
  1         8212  
  1         7  
7              
8 1     1   139 use vars qw($VERSION);
  1         3  
  1         74  
9             $VERSION = '0.008';
10              
11             =head1 NAME
12              
13             WebService::IFConfig::Client - Client for Martin Polden's https://ifconfig.co
14              
15             =head1 SYNOPSIS
16              
17             use feature qw/say/;
18             use WebService::IFConfig::Client;
19             my $ifconfig = WebService::IFConfig::Client->new();
20              
21             say $ifconfig->city;
22             say $ifconfig->country;
23             say $ifconfig->hostname;
24             say $ifconfig->ip;
25             say $ifconfig->ip_decimal;
26              
27             # Time passes ...
28            
29             # Request again
30             $ifconfig->request;
31              
32             Calling C<new()> with no arguments, defaults to requesting immediately from https://ifconfig.co.
33              
34             To defer requesting, the data you can pass the argument C<'run' =E<gt> 0>.
35              
36             To use a different server, pass C<'server' =E<gt> $my_server>.
37              
38             =cut
39              
40             package WebService::IFConfig::Client;
41 1     1   467 use Moose;
  1         540223  
  1         7  
42 1     1   10633 use experimental qw/switch/;
  1         4098  
  1         10  
43              
44             =head1 METHODS
45              
46             =head2 WebService::IFConfig::Client->new( 'run' =E<gt> $boolean , 'server' =E<gt> $my_server );
47              
48             Constructor to create an new client. Default values are
49              
50             Argument Default Meaning
51             -------- ------- -------
52             run 1 1 means run immediately.
53             0 means do not run until a request is made.
54             server https://ifconfig.co/json IPD Server, but you can run your own and provide it here.
55              
56             =cut
57              
58             # Whether to run immediately at construction. Default true.
59             has 'run' => (
60             is => 'ro',
61             isa => 'Bool',
62             default => 1,
63             reader => '_run_at_construction'
64             );
65              
66             =head2 get_server
67              
68             Get the URL this client is configured to talk to
69              
70             =cut
71              
72             =head2 set_server
73              
74             Set the URL this client is configured to talk to
75              
76             =cut
77              
78             has 'server' => (
79             is => 'ro',
80             isa => 'Str',
81             default => 'https://ifconfig.co/json',
82             reader => 'get_server',
83             writer => 'set_server'
84             );
85              
86             has '_json' => (
87             is => 'ro',
88             isa => 'HashRef',
89             default => sub { {} },
90             reader => '_get_json',
91             writer => '_set_json'
92             );
93              
94             =head2 get_raw_status
95              
96             Get the HTTP Response Code of the latest request. Returns 0 if no request has been made.
97              
98             =cut
99              
100             has '_raw_status' => (
101             is => 'ro',
102             isa => 'Int',
103             default => 0,
104             reader => 'get_raw_status',
105             writer => '_set_raw_status'
106             );
107              
108             sub BUILD {
109 3     3 0 10983 my $self = shift;
110              
111 3 100       352 $self->request if $self->_run_at_construction;
112             }
113              
114             =head2 get_status
115              
116             Returns 1 if the HTTP Response Code of the latest request was 200, or 0 if not.
117             Returns undef if no request has been made.
118              
119             =cut
120              
121             sub get_status {
122 11     11 1 66 my $self = shift;
123 11         22 my $answer;
124              
125 11         641 given ( $self->get_raw_status ) {
126 11         43 $answer = undef when 0;
127 11         34 $answer = 1 when 200;
128 4         8 default { $answer = 0 }
  4         11  
129             }
130              
131 11         109 return $answer;
132             }
133              
134             =head2 request
135              
136             Makes a(nother) request from the server.
137              
138             =cut
139              
140             sub request {
141 3     3 1 34 my $self = shift;
142 3         96 my $client = REST::Client->new();
143 3         21856 my $json = JSON->new();
144              
145             # Reset
146 3         238 $self->_set_json({});
147              
148 3         195 $client->GET( $self->get_server );
149              
150 3         175137 $self->_set_raw_status( $client->responseCode() );
151 3 100       16 $self->get_status()
152             and $self->_set_json( $json->decode( $client->responseContent() ) );
153             }
154              
155             sub _request_if_not_ok {
156 5     5   14 my $self = shift;
157 5 50       14 $self->get_status() or $self->request();
158             }
159              
160             sub _elements {
161 5     5   19 my ( $self, $element ) = @_;
162 5         18 $self->_request_if_not_ok();
163 5         259 return $self->_get_json->{$element};
164             }
165              
166             =head2 get_city
167              
168             Get the City name. Forces a request if no valid data.
169              
170             =cut
171              
172 1     1 1 6 sub get_city { return $_[0]->_elements('city'); }
173              
174             =head2 get_country
175              
176             Get the Country name. Forces a request if no valid data.
177              
178             =cut
179              
180 1     1 1 5 sub get_country { return $_[0]->_elements('country'); }
181              
182             =head2 get_hostname
183              
184             Get the Hostname. Forces a request if no valid data.
185              
186             =cut
187              
188 1     1 1 5 sub get_hostname { return $_[0]->_elements('hostname'); }
189              
190             =head2 get_ip
191              
192             Get the IP address. Forces a request if no valid data.
193              
194             =cut
195              
196 1     1 1 3829 sub get_ip { return $_[0]->_elements('ip'); }
197              
198             =head2 get_ip_decimal
199              
200             Get a decimal representation of the IP. Forces a request if no valid data.
201              
202             =cut
203              
204 1     1 1 6 sub get_ip_decimal { return $_[0]->_elements('ip_decimal'); }
205              
206             =head1 AUTHOR
207              
208             Nic Doye E<lt>nic@worldofnic.orgE<gt>
209              
210             =head1 BUGS
211              
212             None. None whatsoever. (This is a lie).
213              
214             =head1 LICENSE
215              
216             Copyright 2017 Nicolas Doye
217              
218             Licensed under the Apache License, Version 2.0 (the "License");
219             you may not use this file except in compliance with the License.
220             You may obtain a copy of the License at
221              
222             http://www.apache.org/licenses/LICENSE-2.0
223              
224             Unless required by applicable law or agreed to in writing, software
225             distributed under the License is distributed on an "AS IS" BASIS,
226             WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
227             See the License for the specific language governing permissions and
228             limitations under the License.
229              
230             =cut
231              
232             1;