maxmind-geoip2 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2/record/abstract'
4
+
5
+ module MaxMind::GeoIP2::Record
6
+ # Contains data for the location record associated with an IP address.
7
+ #
8
+ # This record is returned by all location services and databases besides
9
+ # Country.
10
+ class Location < Abstract
11
+ # The approximate accuracy radius in kilometers around the latitude and
12
+ # longitude for the IP address. This is the radius where we have a 67%
13
+ # confidence that the device using the IP address resides within the circle
14
+ # centered at the latitude and longitude with the provided radius. Integer
15
+ # but may be nil.
16
+ def accuracy_radius
17
+ get('accuracy_radius')
18
+ end
19
+
20
+ # The average income in US dollars associated with the requested IP
21
+ # address. This attribute is only available from the Insights service.
22
+ # Integer but may be nil.
23
+ def average_income
24
+ get('average_income')
25
+ end
26
+
27
+ # The approximate latitude of the location associated with the IP address.
28
+ # This value is not precise and should not be used to identify a particular
29
+ # address or household. Float but may be nil.
30
+ def latitude
31
+ get('latitude')
32
+ end
33
+
34
+ # The approximate longitude of the location associated with the IP address.
35
+ # This value is not precise and should not be used to identify a particular
36
+ # address or household. Float but may be nil.
37
+ def longitude
38
+ get('longitude')
39
+ end
40
+
41
+ # The metro code of the location if the location is in the US. MaxMind
42
+ # returns the same metro codes as the Google AdWords API. See
43
+ # https://developers.google.com/adwords/api/docs/appendix/cities-DMAregions.
44
+ # Integer but may be nil.
45
+ def metro_code
46
+ get('metro_code')
47
+ end
48
+
49
+ # The estimated population per square kilometer associated with the IP
50
+ # address. This attribute is only available from the Insights service.
51
+ # Integer but may be nil.
52
+ def population_density
53
+ get('population_density')
54
+ end
55
+
56
+ # The time zone associated with location, as specified by the IANA Time
57
+ # Zone Database, e.g., "America/New_York". See
58
+ # https://www.iana.org/time-zones. String but may be nil.
59
+ def time_zone
60
+ get('time_zone')
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2/record/abstract'
4
+
5
+ module MaxMind::GeoIP2::Record
6
+ # Location data common to different location types.
7
+ class Place < Abstract
8
+ def initialize(record, locales) # :nodoc:
9
+ super(record)
10
+ @locales = locales
11
+ end
12
+
13
+ # A string containing the first available localized name in order of
14
+ # preference.
15
+ def name
16
+ n = names
17
+ return nil if n.nil?
18
+
19
+ @locales.each do |locale|
20
+ return n[locale] if n.key?(locale)
21
+ end
22
+
23
+ nil
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2/record/abstract'
4
+
5
+ module MaxMind::GeoIP2::Record
6
+ # Contains data for the postal record associated with an IP address.
7
+ #
8
+ # This record is returned by all location services and databases besides
9
+ # Country.
10
+ class Postal < Abstract
11
+ # The postal code of the location. Postal codes are not available for all
12
+ # countries. In some countries, this will only contain part of the postal
13
+ # code. This attribute is returned by all location databases and services
14
+ # besides Country. String but may be nil.
15
+ def code
16
+ get('code')
17
+ end
18
+
19
+ # A value from 0-100 indicating MaxMind's confidence that the postal code
20
+ # is correct. This attribute is only available from the Insights service
21
+ # and the GeoIP2 Enterprise database. Integer but may be nil.
22
+ def confidence
23
+ get('confidence')
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2/record/country'
4
+
5
+ module MaxMind::GeoIP2::Record
6
+ # Contains data for the represented country associated with an IP address.
7
+ #
8
+ # This class contains the country-level data associated with an IP address
9
+ # for the IP's represented country. The represented country is the country
10
+ # represented by something like a military base.
11
+ #
12
+ # See Country for inherited methods.
13
+ class RepresentedCountry < Country
14
+ # A string indicating the type of entity that is representing the country.
15
+ # Currently we only return +military+ but this could expand to include
16
+ # other types in the future. String but may be nil.
17
+ def type
18
+ get('type')
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2/record/place'
4
+
5
+ module MaxMind::GeoIP2::Record
6
+ # Contains data for the subdivisions associated with an IP address.
7
+ #
8
+ # This record is returned by all location databases and services besides
9
+ # Country.
10
+ #
11
+ # See Place for inherited methods.
12
+ class Subdivision < Place
13
+ # This is a value from 0-100 indicating MaxMind's confidence that the
14
+ # subdivision is correct. This attribute is only available from the
15
+ # Insights service and the GeoIP2 Enterprise database. Integer but may be
16
+ # nil.
17
+ def confidence
18
+ get('confidence')
19
+ end
20
+
21
+ # This is a GeoName ID for the subdivision. This attribute is returned by
22
+ # all location databases and services besides Country. Integer but may be
23
+ # nil.
24
+ def geoname_id
25
+ get('geoname_id')
26
+ end
27
+
28
+ # This is a string up to three characters long contain the subdivision
29
+ # portion of the ISO 3166-2 code. See
30
+ # https://en.wikipedia.org/wiki/ISO_3166-2. This attribute is returned by
31
+ # all location databases and services except Country. String but may be
32
+ # nil.
33
+ def iso_code
34
+ get('iso_code')
35
+ end
36
+
37
+ # A Hash where the keys are locale codes (Strings) and the values are names
38
+ # (Strings). This attribute is returned by all location services and
39
+ # databases besides country. Hash but may be nil.
40
+ def names
41
+ get('names')
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,169 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ipaddr'
4
+ require 'maxmind/geoip2/record/abstract'
5
+
6
+ module MaxMind::GeoIP2::Record
7
+ # Contains data for the traits record associated with an IP address.
8
+ #
9
+ # This record is returned by all location services and databases.
10
+ class Traits < Abstract
11
+ def initialize(record) # :nodoc:
12
+ super(record)
13
+ if !record.key?('network') && record.key?('ip_address') &&
14
+ record.key?('prefix_length')
15
+ ip = IPAddr.new(
16
+ format('%s/%d', record['ip_address'], record['prefix_length']),
17
+ )
18
+ # We could use ip.prefix instead of record['prefix_length'], but that
19
+ # method only becomes available in Ruby 2.5+.
20
+ record['network'] = format('%s/%d', ip.to_s, record['prefix_length'])
21
+ end
22
+ end
23
+
24
+ # The autonomous system number associated with the IP address. See
25
+ # Wikipedia[https://en.wikipedia.org/wiki/Autonomous_system_(Internet)].
26
+ # This attribute is only available from the City and Insights web service
27
+ # and the GeoIP2 Enterprise database. Integer but may be nil.
28
+ def autonomous_system_number
29
+ get('autonomous_system_number')
30
+ end
31
+
32
+ # The organization associated with the registered autonomous system number
33
+ # for the IP address. See
34
+ # Wikipedia[https://en.wikipedia.org/wiki/Autonomous_system_(Internet)].
35
+ # This attribute is only available from the City and Insights web service
36
+ # and the GeoIP2 Enterprise database. String but may be nil.
37
+ def autonomous_system_organization
38
+ get('autonomous_system_organization')
39
+ end
40
+
41
+ # The connection type may take the following values: "Dialup",
42
+ # "Cable/DSL", "Corporate", "Cellular". Additional values may be added in
43
+ # the future. This attribute is only available in the GeoIP2 Enterprise
44
+ # database. String but may be nil.
45
+ def connection_type
46
+ get('connection_type')
47
+ end
48
+
49
+ # The second level domain associated with the IP address. This will be
50
+ # something like "example.com" or "example.co.uk", not "foo.example.com".
51
+ # This attribute is only available from the City and Insights web service
52
+ # and the GeoIP2 Enterprise database. String but may be nil.
53
+ def domain
54
+ get('domain')
55
+ end
56
+
57
+ # The IP address that the data in the model is for. If you performed a "me"
58
+ # lookup against the web service, this will be the externally routable IP
59
+ # address for the system the code is running on. If the system is behind a
60
+ # NAT, this may differ from the IP address locally assigned to it. This
61
+ # attribute is returned by all end points. String.
62
+ def ip_address
63
+ get('ip_address')
64
+ end
65
+
66
+ # This is true if the IP address belongs to any sort of anonymous network.
67
+ # This property is only available from GeoIP2 Precision Insights. Boolean.
68
+ def anonymous?
69
+ get('is_anonymous')
70
+ end
71
+
72
+ # This is true if the IP address is registered to an anonymous VPN
73
+ # provider. If a VPN provider does not register subnets under names
74
+ # associated with them, we will likely only flag their IP ranges using the
75
+ # hosting_provider? property. This property is only available from GeoIP2
76
+ # Precision Insights. Boolean.
77
+ def anonymous_vpn?
78
+ get('is_anonymous_vpn')
79
+ end
80
+
81
+ # This is true if the IP address belongs to a hosting or VPN provider (see
82
+ # description of the anonymous_vpn? property). This property is only
83
+ # available from GeoIP2 Precision Insights. Boolean.
84
+ def hosting_provider?
85
+ get('is_hosting_provider')
86
+ end
87
+
88
+ # This attribute is true if MaxMind believes this IP address to be a
89
+ # legitimate proxy, such as an internal VPN used by a corporation. This
90
+ # attribute is only available in the GeoIP2 Enterprise database. Boolean.
91
+ def legitimate_proxy?
92
+ get('is_legitimate_proxy')
93
+ end
94
+
95
+ # This is true if the IP address belongs to a public proxy. This property
96
+ # is only available from GeoIP2 Precision Insights. Boolean.
97
+ def public_proxy?
98
+ get('is_public_proxy')
99
+ end
100
+
101
+ # This is true if the IP address is a Tor exit node. This property is only
102
+ # available from GeoIP2 Precision Insights. Boolean.
103
+ def tor_exit_node?
104
+ get('is_tor_exit_node')
105
+ end
106
+
107
+ # The name of the ISP associated with the IP address. This attribute is
108
+ # only available from the City and Insights web services and the GeoIP2
109
+ # Enterprise database. String but may be nil.
110
+ def isp
111
+ get('isp')
112
+ end
113
+
114
+ # The network in CIDR notation associated with the record. In particular,
115
+ # this is the largest network where all of the fields besides ip_address
116
+ # have the same value. String.
117
+ def network
118
+ get('network')
119
+ end
120
+
121
+ # The name of the organization associated with the IP address. This
122
+ # attribute is only available from the City and Insights web services and
123
+ # the GeoIP2 Enterprise database. String but may be nil.
124
+ def organization
125
+ get('organization')
126
+ end
127
+
128
+ # An indicator of how static or dynamic an IP address is. This property is
129
+ # only available from GeoIP2 Precision Insights. Float but may be nil.
130
+ def static_ip_score
131
+ get('static_ip_score')
132
+ end
133
+
134
+ # The estimated number of users sharing the IP/network during the past 24
135
+ # hours. For IPv4, the count is for the individual IP. For IPv6, the count
136
+ # is for the /64 network. This property is only available from GeoIP2
137
+ # Precision Insights. Integer but may be nil.
138
+ def user_count
139
+ get('user_count')
140
+ end
141
+
142
+ # The user type associated with the IP address. This can be one of the
143
+ # following values:
144
+ #
145
+ # * business
146
+ # * cafe
147
+ # * cellular
148
+ # * college
149
+ # * content_delivery_network
150
+ # * dialup
151
+ # * government
152
+ # * hosting
153
+ # * library
154
+ # * military
155
+ # * residential
156
+ # * router
157
+ # * school
158
+ # * search_engine_spider
159
+ # * traveler
160
+ #
161
+ # This attribute is only available from the Insights web service and the
162
+ # GeoIP2 Enterprise database.
163
+ #
164
+ # May be nil.
165
+ def user_type
166
+ get('user_type')
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem::Specification.new do |s|
4
+ s.authors = ['William Storey']
5
+ s.files = Dir['**/*']
6
+ s.name = 'maxmind-geoip2'
7
+ s.summary = 'A gem for interacting with the GeoIP2 webservices and databases.'
8
+ s.version = '0.0.1'
9
+
10
+ s.description = 'A gem for interacting with the GeoIP2 webservices and databases. MaxMind provides geolocation data as downloadable databases as well as through a webservice.'
11
+ s.email = 'support@maxmind.com'
12
+ s.homepage = 'https://github.com/maxmind/GeoIP2-ruby'
13
+ s.licenses = ['Apache-2.0', 'MIT']
14
+ s.metadata = {
15
+ 'bug_tracker_uri' => 'https://github.com/maxmind/GeoIP2-ruby/issues',
16
+ 'changelog_uri' => 'https://github.com/maxmind/GeoIP2-ruby/blob/master/CHANGELOG.md',
17
+ 'documentation_uri' => 'https://github.com/maxmind/GeoIP2-ruby',
18
+ 'homepage_uri' => 'https://github.com/maxmind/GeoIP2-ruby',
19
+ 'source_code_uri' => 'https://github.com/maxmind/GeoIP2-ruby',
20
+ }
21
+ s.required_ruby_version = '>= 2.4.0'
22
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'maxmind/geoip2'
4
+ require 'minitest/autorun'
5
+
6
+ class CountryModelTest < Minitest::Test # :nodoc:
7
+ RAW = {
8
+ 'continent' => {
9
+ 'code' => 'NA',
10
+ 'geoname_id' => 42,
11
+ 'names' => { 'en' => 'North America' },
12
+ },
13
+ 'country' => {
14
+ 'geoname_id' => 1,
15
+ 'iso_code' => 'US',
16
+ 'names' => { 'en' => 'United States of America' },
17
+ },
18
+ 'registered_country' => {
19
+ 'geoname_id' => 2,
20
+ 'is_in_european_union' => true,
21
+ 'iso_code' => 'DE',
22
+ 'names' => { 'en' => 'Germany' },
23
+ },
24
+ 'traits' => {
25
+ 'ip_address' => '1.2.3.4',
26
+ 'prefix_length' => 24,
27
+ },
28
+ }.freeze
29
+
30
+ def test_objects
31
+ model = MaxMind::GeoIP2::Model::Country.new(RAW, ['en'])
32
+ assert_equal(MaxMind::GeoIP2::Model::Country, model.class)
33
+ assert_equal(MaxMind::GeoIP2::Record::Continent, model.continent.class)
34
+ assert_equal(MaxMind::GeoIP2::Record::Country, model.country.class)
35
+ assert_equal(
36
+ MaxMind::GeoIP2::Record::Country,
37
+ model.registered_country.class,
38
+ )
39
+ assert_equal(
40
+ MaxMind::GeoIP2::Record::RepresentedCountry,
41
+ model.represented_country.class,
42
+ )
43
+ assert_equal(
44
+ MaxMind::GeoIP2::Record::Traits,
45
+ model.traits.class,
46
+ )
47
+ end
48
+
49
+ def test_values
50
+ model = MaxMind::GeoIP2::Model::Country.new(RAW, ['en'])
51
+
52
+ assert_equal(42, model.continent.geoname_id)
53
+ assert_equal('NA', model.continent.code)
54
+ assert_equal({ 'en' => 'North America' }, model.continent.names)
55
+ assert_equal('North America', model.continent.name)
56
+
57
+ assert_equal(1, model.country.geoname_id)
58
+ assert_equal(false, model.country.in_european_union?)
59
+ assert_equal('US', model.country.iso_code)
60
+ assert_equal({ 'en' => 'United States of America' }, model.country.names)
61
+ assert_equal('United States of America', model.country.name)
62
+ assert_nil(model.country.confidence)
63
+
64
+ assert_equal(2, model.registered_country.geoname_id)
65
+ assert_equal(true, model.registered_country.in_european_union?)
66
+ assert_equal('DE', model.registered_country.iso_code)
67
+ assert_equal({ 'en' => 'Germany' }, model.registered_country.names)
68
+ assert_equal('Germany', model.registered_country.name)
69
+ end
70
+
71
+ def test_unknown_record
72
+ model = MaxMind::GeoIP2::Model::Country.new(RAW, ['en'])
73
+ assert_raises(NoMethodError) { model.unknown_record }
74
+ end
75
+
76
+ def test_unknown_trait
77
+ model = MaxMind::GeoIP2::Model::Country.new(RAW, ['en'])
78
+ assert_raises(NoMethodError) { model.traits.unknown }
79
+ end
80
+ end