File Coverage

blib/lib/WebService/IFConfig/Client.pm
Criterion Covered Total %
statement 53 53 100.0
branch 5 6 83.3
condition n/a
subroutine 19 19 100.0
pod 7 8 87.5
total 84 86 97.6


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