File Coverage

blib/lib/Acme/Free/API/Geodata/GeoIP.pm
Criterion Covered Total %
statement 56 73 76.7
branch 5 12 41.6
condition 3 9 33.3
subroutine 10 11 90.9
pod 0 2 0.0
total 74 107 69.1


line stmt bran cond sub pod time code
1             package Acme::Free::API::Geodata::GeoIP;
2              
3 1     1   117304 use v5.38;
  1         8  
4 1     1   7 use strict;
  1         2  
  1         28  
5 1     1   5 use warnings;
  1         3  
  1         64  
6 1     1   673 use utf8;
  1         339  
  1         8  
7              
8             our $VERSION = '1.0';
9              
10 1     1   759 use Data::Dumper;
  1         10987  
  1         117  
11 1     1   2161 use WWW::Mechanize;
  1         286144  
  1         41  
12 1     1   657 use JSON::XS qw(decode_json);
  1         4393  
  1         387  
13              
14 1     1 0 178293 sub new($proto, %config) {
  1         6  
  1         6  
  1         3  
15 1   33     9 my $class = ref($proto) || $proto;
16              
17 1         4 my $self = bless \%config, $class;
18              
19 1         15 my $agent = WWW::Mechanize->new(cookie_jar => {});
20 1         23667 $agent->agent('PerlMonks contest/1 (https://perlmonks.org/?node_id=11161472)');
21 1         114 $agent->stack_depth(1);
22 1         15 $self->{agent} = $agent;
23              
24 1 50       7 if(!defined($self->{debug})) {
25 0         0 $self->{debug} = 0;
26             }
27              
28 1         24 return $self;
29             }
30              
31 2     2 0 2159 sub lookup($self, $ip) {
  2         8  
  2         5  
  2         5  
32 2         6 my $url = "http://ip-api.com/json/" . $ip;
33              
34 2         8 my $content = $self->_fetchURL($url);
35              
36 2         6 my $ok = 0;
37 2         4 my $decoded;
38 2         4 eval {
39 2         80 $decoded = decode_json($content);
40 2         8 $ok = 1;
41             };
42              
43 2 50 33     16 if(!$ok || !defined($decoded)) {
44 0         0 $self->_debuglog("Failed to decode response. Not a JSON document?");
45 0         0 $self->_debuglog(Dumper($decoded));
46 0         0 return;
47             }
48              
49             #$self->_debuglog(Dumper($decoded));
50              
51 2         13 return $decoded;
52             }
53              
54              
55              
56             # internal helpers
57             # these are copied from CAVACs vast framework. But we don't want hundreds of dependencies in this example code, only a couple of functions
58 2     2   4 sub _fetchURL($self, $url) {
  2         5  
  2         4  
  2         13  
59 2         15 $self->{agent}->get($url);
60              
61 2 50       136011 if(!$self->{agent}->success()) {
62 0         0 $self->_debuglog("Network error while fetching URL $url");
63 0         0 return;
64             }
65              
66 2         56 my $response = $self->{agent}->response();
67 2 50       16 if(!defined($response)) {
68 0         0 $self->_debuglog("Could not get agent response");
69 0         0 return;
70             }
71              
72 2         11 my $content = $response->decoded_content;
73 2 50 33     341 if(!defined($content) || !length($content)) {
74 0         0 $self->_debuglog("Could not get response content");
75 0         0 return;
76             }
77              
78             #$self->_debuglog(Dumper($content));
79              
80 2         10 return $content;
81              
82             }
83              
84 0     0     sub _debuglog($self, $message) {
  0            
  0            
  0            
85 0 0         if(!$self->{debug}) {
86 0           return;
87             }
88 0           print STDERR $message, "\n";
89             }
90              
91              
92             1;
93             __END__