Skip to content

Commit 4ff6535

Browse files
authored
Merge pull request #42 from ipinfo/silvano/eng-503-add-plus-bundle-support-in-ipinfoperl-library
Add support for Plus bundle
2 parents 46b5151 + 1141d43 commit 4ff6535

File tree

4 files changed

+643
-0
lines changed

4 files changed

+643
-0
lines changed

Geo-IPinfo/MANIFEST

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@ Changes
22
lib/Geo/IPinfo.pm
33
lib/Geo/IPinfoLite.pm
44
lib/Geo/IPinfoCore.pm
5+
lib/Geo/IPinfoPlus.pm
56
lib/Geo/Details.pm
67
lib/Geo/DetailsLite.pm
78
lib/Geo/DetailsCore.pm
9+
lib/Geo/DetailsPlus.pm
810
Makefile.PL
911
MANIFEST This list of files
1012
ignore.txt
1113
t/00-load.t
1214
t/01-usage.t
1315
t/02-usage-lite.t
1416
t/03-usage-core.t
17+
t/04-usage-plus.t
1518
t/cache-hit.t
1619
t/manifest.t
1720
t/pod-coverage.t

Geo-IPinfo/lib/Geo/DetailsPlus.pm

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
package Geo::DetailsPlus;
2+
3+
use 5.006;
4+
use strict;
5+
use warnings;
6+
7+
# Helper package for GeoPlus data
8+
package Geo::DetailsPlus::Geo {
9+
use strict;
10+
use warnings;
11+
12+
sub new {
13+
my $class = shift;
14+
my $data = shift || {};
15+
bless $data, $class;
16+
return $data;
17+
}
18+
19+
sub city { return $_[0]->{city}; }
20+
sub region { return $_[0]->{region}; }
21+
sub region_code { return $_[0]->{region_code}; }
22+
sub country { return $_[0]->{country}; }
23+
sub country_code { return $_[0]->{country_code}; }
24+
sub continent { return $_[0]->{continent}; }
25+
sub continent_code { return $_[0]->{continent_code}; }
26+
sub latitude { return $_[0]->{latitude}; }
27+
sub longitude { return $_[0]->{longitude}; }
28+
sub timezone { return $_[0]->{timezone}; }
29+
sub postal_code { return $_[0]->{postal_code}; }
30+
sub dma_code { return $_[0]->{dma_code}; }
31+
sub geoname_id { return $_[0]->{geoname_id}; }
32+
sub radius { return $_[0]->{radius}; }
33+
sub last_changed { return $_[0]->{last_changed}; }
34+
35+
# Enriched fields
36+
sub country_name { return $_[0]->{country_name}; }
37+
sub is_eu { return $_[0]->{is_eu}; }
38+
sub country_flag { return $_[0]->{country_flag}; }
39+
sub country_flag_url { return $_[0]->{country_flag_url}; }
40+
sub country_currency { return $_[0]->{country_currency}; }
41+
sub continent_info { return $_[0]->{continent_info}; }
42+
}
43+
44+
# Helper package for ASPlus data
45+
package Geo::DetailsPlus::AS {
46+
use strict;
47+
use warnings;
48+
49+
sub new {
50+
my $class = shift;
51+
my $data = shift || {};
52+
bless $data, $class;
53+
return $data;
54+
}
55+
56+
sub asn { return $_[0]->{asn}; }
57+
sub name { return $_[0]->{name}; }
58+
sub domain { return $_[0]->{domain}; }
59+
sub type { return $_[0]->{type}; }
60+
sub last_changed { return $_[0]->{last_changed}; }
61+
}
62+
63+
# Helper package for Mobile data
64+
package Geo::DetailsPlus::Mobile {
65+
use strict;
66+
use warnings;
67+
68+
sub new {
69+
my $class = shift;
70+
my $data = shift || {};
71+
bless $data, $class;
72+
return $data;
73+
}
74+
}
75+
76+
# Helper package for Anonymous data
77+
package Geo::DetailsPlus::Anonymous {
78+
use strict;
79+
use warnings;
80+
81+
sub new {
82+
my $class = shift;
83+
my $data = shift || {};
84+
bless $data, $class;
85+
return $data;
86+
}
87+
88+
sub is_proxy { return $_[0]->{is_proxy}; }
89+
sub is_relay { return $_[0]->{is_relay}; }
90+
sub is_tor { return $_[0]->{is_tor}; }
91+
sub is_vpn { return $_[0]->{is_vpn}; }
92+
}
93+
94+
# Helper package for Abuse data
95+
package Geo::DetailsPlus::Abuse {
96+
use strict;
97+
use warnings;
98+
99+
sub new {
100+
my $class = shift;
101+
my $data = shift || {};
102+
bless $data, $class;
103+
return $data;
104+
}
105+
106+
sub address { return $_[0]->{address}; }
107+
sub country { return $_[0]->{country}; }
108+
sub email { return $_[0]->{email}; }
109+
sub name { return $_[0]->{name}; }
110+
sub network { return $_[0]->{network}; }
111+
sub phone { return $_[0]->{phone}; }
112+
113+
# Enriched
114+
sub country_name { return $_[0]->{country_name}; }
115+
}
116+
117+
# Helper package for Company data
118+
package Geo::DetailsPlus::Company {
119+
use strict;
120+
use warnings;
121+
122+
sub new {
123+
my $class = shift;
124+
my $data = shift || {};
125+
bless $data, $class;
126+
return $data;
127+
}
128+
129+
sub name { return $_[0]->{name}; }
130+
sub domain { return $_[0]->{domain}; }
131+
sub type { return $_[0]->{type}; }
132+
}
133+
134+
# Helper package for Privacy data
135+
package Geo::DetailsPlus::Privacy {
136+
use strict;
137+
use warnings;
138+
139+
sub new {
140+
my $class = shift;
141+
my $data = shift || {};
142+
bless $data, $class;
143+
return $data;
144+
}
145+
146+
sub vpn { return $_[0]->{vpn}; }
147+
sub proxy { return $_[0]->{proxy}; }
148+
sub tor { return $_[0]->{tor}; }
149+
sub relay { return $_[0]->{relay}; }
150+
sub hosting { return $_[0]->{hosting}; }
151+
sub service { return $_[0]->{service}; }
152+
}
153+
154+
# Helper package for Domains data
155+
package Geo::DetailsPlus::Domains {
156+
use strict;
157+
use warnings;
158+
159+
sub new {
160+
my $class = shift;
161+
my $data = shift || {};
162+
bless $data, $class;
163+
return $data;
164+
}
165+
166+
sub domains { return $_[0]->{domains}; }
167+
sub total { return $_[0]->{total}; }
168+
}
169+
170+
# Main package
171+
package Geo::DetailsPlus;
172+
173+
sub new {
174+
my $class = shift;
175+
my $data = shift;
176+
my $key = shift // '';
177+
178+
# If $data is a hash reference, process and bless it
179+
if ( ref($data) eq 'HASH' ) {
180+
# Convert nested objects to blessed objects
181+
if ( exists $data->{geo} && ref($data->{geo}) eq 'HASH' ) {
182+
$data->{geo} = Geo::DetailsPlus::Geo->new($data->{geo});
183+
}
184+
if ( exists $data->{as} && ref($data->{as}) eq 'HASH' ) {
185+
$data->{as} = Geo::DetailsPlus::AS->new($data->{as});
186+
}
187+
if ( exists $data->{mobile} && ref($data->{mobile}) eq 'HASH' ) {
188+
$data->{mobile} = Geo::DetailsPlus::Mobile->new($data->{mobile});
189+
}
190+
if ( exists $data->{anonymous} && ref($data->{anonymous}) eq 'HASH' ) {
191+
$data->{anonymous} = Geo::DetailsPlus::Anonymous->new($data->{anonymous});
192+
}
193+
if ( exists $data->{abuse} && ref($data->{abuse}) eq 'HASH' ) {
194+
$data->{abuse} = Geo::DetailsPlus::Abuse->new($data->{abuse});
195+
}
196+
if ( exists $data->{company} && ref($data->{company}) eq 'HASH' ) {
197+
$data->{company} = Geo::DetailsPlus::Company->new($data->{company});
198+
}
199+
if ( exists $data->{privacy} && ref($data->{privacy}) eq 'HASH' ) {
200+
$data->{privacy} = Geo::DetailsPlus::Privacy->new($data->{privacy});
201+
}
202+
if ( exists $data->{domains} && ref($data->{domains}) eq 'HASH' ) {
203+
$data->{domains} = Geo::DetailsPlus::Domains->new($data->{domains});
204+
}
205+
206+
bless $data, $class;
207+
return $data;
208+
}
209+
210+
# If $data is a plain string, create a new hash reference
211+
my $self = { $key => $data };
212+
bless $self, $class;
213+
return $self;
214+
}
215+
216+
sub TO_JSON {
217+
my ($self) = @_;
218+
return {%$self};
219+
}
220+
221+
sub ip { return $_[0]->{ip}; }
222+
sub hostname { return $_[0]->{hostname}; }
223+
sub geo { return $_[0]->{geo}; }
224+
sub as { return $_[0]->{as}; }
225+
sub mobile { return $_[0]->{mobile}; }
226+
sub anonymous { return $_[0]->{anonymous}; }
227+
sub abuse { return $_[0]->{abuse}; }
228+
sub company { return $_[0]->{company}; }
229+
sub privacy { return $_[0]->{privacy}; }
230+
sub domains { return $_[0]->{domains}; }
231+
sub is_anonymous { return $_[0]->{is_anonymous}; }
232+
sub is_anycast { return $_[0]->{is_anycast}; }
233+
sub is_hosting { return $_[0]->{is_hosting}; }
234+
sub is_mobile { return $_[0]->{is_mobile}; }
235+
sub is_satellite { return $_[0]->{is_satellite}; }
236+
sub bogon { return $_[0]->{bogon}; }
237+
238+
sub all {
239+
return $_[0];
240+
}
241+
242+
1;
243+
__END__
244+
245+
=head1 NAME
246+
247+
Geo::DetailsPlus - Module to represent details of an IP returned by the Plus API
248+
249+
=head1 SYNOPSIS
250+
251+
use Geo::DetailsPlus;
252+
253+
my $data = {
254+
ip => '8.8.8.8',
255+
hostname => 'dns.google',
256+
geo => {
257+
city => 'Mountain View',
258+
country => 'United States',
259+
country_code => 'US',
260+
},
261+
as => {
262+
asn => 'AS15169',
263+
name => 'Google LLC',
264+
},
265+
privacy => {
266+
vpn => 0,
267+
proxy => 0,
268+
},
269+
};
270+
271+
my $details = Geo::DetailsPlus->new($data);
272+
print $details->ip; # Output: 8.8.8.8
273+
print $details->hostname; # Output: dns.google
274+
print $details->geo->city; # Output: Mountain View
275+
print $details->privacy->vpn; # Output: 0
276+
277+
=head1 DESCRIPTION
278+
279+
Geo::DetailsPlus represents details of an IP returned by the IPinfo Plus API.
280+
281+
=head1 AUTHOR
282+
283+
IPinfo <support@ipinfo.io>
284+
285+
=head1 COPYRIGHT AND LICENSE
286+
287+
Copyright (c) 2025 IPinfo
288+
289+
Licensed under the Apache License, Version 2.0.
290+
291+
=cut

0 commit comments

Comments
 (0)