ip2geo 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +6 -0
- data/README.md +99 -0
- data/ip2geo.gemspec +24 -0
- data/lib/ip2geo/data/constants.rb +118 -0
- data/lib/ip2geo/data/messages.rb +29 -0
- data/lib/ip2geo/data/states.rb +19 -0
- data/lib/ip2geo/helpers/check_version.rb +78 -0
- data/lib/ip2geo/helpers/http.rb +47 -0
- data/lib/ip2geo/helpers/ip_validation.rb +28 -0
- data/lib/ip2geo/methods/convert_ip.rb +56 -0
- data/lib/ip2geo/methods/convert_ips.rb +73 -0
- data/lib/ip2geo/methods/get_conversion.rb +52 -0
- data/lib/ip2geo/methods/get_conversions.rb +52 -0
- data/lib/ip2geo/methods/init.rb +28 -0
- data/lib/ip2geo/methods/list_conversions.rb +38 -0
- data/lib/ip2geo.rb +148 -0
- metadata +75 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 3cdf86cb50c5d08c734ea15c78ec62d0f218dae67ccdb074b9b889fb0c77681f
|
|
4
|
+
data.tar.gz: ed6420fd62687669cf430d6525b6415326a595cd60e4fae6a65ce0aae268e182
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 2a7f9f99b598e068ccff78fb2ba2199835a2db6ee086f7871228fcd8e785d321b72b7187bc195a77589acbb6a7f7f170e1d3410044355b913d9e41f2766ac0e0
|
|
7
|
+
data.tar.gz: 190301f6be0572c93262611ec8cc2ee6f4ec631c9c810755777076daa379bc87ab22eaa5f543ef959584acd46c4ab54f3529d8c6218c1acb0c70917c55bc40c7
|
data/LICENSE
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Copyright (c) 2024 Ip2Geo. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software is proprietary and confidential. Unauthorized copying, distribution,
|
|
4
|
+
modification, or use of this software, via any medium, is strictly prohibited.
|
|
5
|
+
|
|
6
|
+
No license, express or implied, is granted to any person or entity for any purpose.
|
data/README.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<div align='center'>
|
|
2
|
+
<a href='https://axios-http.com'>
|
|
3
|
+
<img
|
|
4
|
+
src='https://cdn-prod.ip2geo.dev/assets/npm/generals/ip2geo.svg'
|
|
5
|
+
alt='Ip2Geo Logo'
|
|
6
|
+
/>
|
|
7
|
+
</a>
|
|
8
|
+
|
|
9
|
+
<br />
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<p align='center'>
|
|
13
|
+
Your go-to IP-to-Geo cloud service — fast, accurate, and built for developers. Start free with 2,000 monthly stored conversions.
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align='center'>
|
|
17
|
+
<a href='https://ip2geo.dev'>
|
|
18
|
+
<b>
|
|
19
|
+
Website
|
|
20
|
+
</b>
|
|
21
|
+
</a>
|
|
22
|
+
•
|
|
23
|
+
<a href='https://app.ip2geo.dev'>
|
|
24
|
+
<b>
|
|
25
|
+
Dashboard
|
|
26
|
+
</b>
|
|
27
|
+
</a>
|
|
28
|
+
•
|
|
29
|
+
<a href='https://docs.ip2geo.dev'>
|
|
30
|
+
<b>
|
|
31
|
+
Documentation
|
|
32
|
+
</b>
|
|
33
|
+
</a>
|
|
34
|
+
•
|
|
35
|
+
<a href='https://status.ip2geo.dev'>
|
|
36
|
+
<b>
|
|
37
|
+
Services Status
|
|
38
|
+
</b>
|
|
39
|
+
</a>
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
<br />
|
|
43
|
+
|
|
44
|
+
## Intro to the Ruby Gem
|
|
45
|
+
|
|
46
|
+
This gem provides a lightweight way to integrate Ip2Geo into your Ruby applications.
|
|
47
|
+
|
|
48
|
+
### Installing
|
|
49
|
+
```bash
|
|
50
|
+
gem install ip2geo
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Initializing
|
|
54
|
+
```ruby
|
|
55
|
+
require 'ip2geo'
|
|
56
|
+
|
|
57
|
+
Ip2Geo.init(ENV['IP2GEO_API_KEY'])
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Using
|
|
61
|
+
```ruby
|
|
62
|
+
converted_ip = Ip2Geo.convert_ip(ip: '8.8.8.8')
|
|
63
|
+
|
|
64
|
+
converted_ips = Ip2Geo.convert_ips(
|
|
65
|
+
ips: [
|
|
66
|
+
'8.8.8.8',
|
|
67
|
+
'1.1.1.1',
|
|
68
|
+
'9.9.9.9',
|
|
69
|
+
'64.6.64.6'
|
|
70
|
+
]
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
# {
|
|
74
|
+
# 'success' => true,
|
|
75
|
+
# 'code' => 200,
|
|
76
|
+
# 'message' => 'Success',
|
|
77
|
+
# 'data' => { ... },
|
|
78
|
+
# '_req' => {
|
|
79
|
+
# 'reqId' => 'string',
|
|
80
|
+
# 'resTime' => 123
|
|
81
|
+
# }
|
|
82
|
+
# }
|
|
83
|
+
|
|
84
|
+
# {
|
|
85
|
+
# 'success' => true,
|
|
86
|
+
# 'code' => 200,
|
|
87
|
+
# 'message' => 'Success',
|
|
88
|
+
# 'data' => [
|
|
89
|
+
# {
|
|
90
|
+
# 'ip' => '8.8.8.8',
|
|
91
|
+
# 'conversion' => { ... }
|
|
92
|
+
# }
|
|
93
|
+
# ],
|
|
94
|
+
# '_req' => {
|
|
95
|
+
# 'reqId' => 'string',
|
|
96
|
+
# 'resTime' => 123
|
|
97
|
+
# }
|
|
98
|
+
# }
|
|
99
|
+
```
|
data/ip2geo.gemspec
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |spec|
|
|
4
|
+
spec.name = 'ip2geo'
|
|
5
|
+
spec.version = '0.0.1'
|
|
6
|
+
spec.authors = ['Ip2Geo']
|
|
7
|
+
spec.email = ['support@ip2geo.dev']
|
|
8
|
+
|
|
9
|
+
spec.summary = 'Official Ruby SDK for Ip2Geo - IP to Geolocation API.'
|
|
10
|
+
spec.description = 'A lightweight Ruby client for the Ip2Geo cloud service. Get accurate geolocation data for IP addresses including continent, country, city, timezone, ASN, and more.'
|
|
11
|
+
spec.homepage = 'https://ip2geo.dev'
|
|
12
|
+
spec.required_ruby_version = '>= 2.7.0'
|
|
13
|
+
|
|
14
|
+
spec.license = 'Nonstandard'
|
|
15
|
+
|
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
17
|
+
spec.metadata['changelog_uri'] = 'https://docs.ip2geo.dev/changelog'
|
|
18
|
+
spec.metadata['documentation_uri'] = 'https://docs.ip2geo.dev'
|
|
19
|
+
|
|
20
|
+
spec.files = Dir.glob('lib/**/*') + ['ip2geo.gemspec', 'README.md', 'LICENSE']
|
|
21
|
+
spec.require_paths = ['lib']
|
|
22
|
+
|
|
23
|
+
spec.add_dependency 'json', '~> 2.0'
|
|
24
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ip2Geo
|
|
4
|
+
module Data
|
|
5
|
+
API_ENDPOINT = 'https://api.ip2geo.dev'
|
|
6
|
+
DOCS_URL = 'https://docs.ip2geo.dev'
|
|
7
|
+
RUBYGEMS_URL = 'https://rubygems.org/api/v1/gems/ip2geo.json'
|
|
8
|
+
|
|
9
|
+
IP_TYPES = {
|
|
10
|
+
IPV4: 'ipv4',
|
|
11
|
+
IPV6: 'ipv6'
|
|
12
|
+
}.freeze
|
|
13
|
+
|
|
14
|
+
HTTP_METHODS = {
|
|
15
|
+
ALL: 'all',
|
|
16
|
+
GET: 'GET',
|
|
17
|
+
POST: 'POST',
|
|
18
|
+
DELETE: 'DELETE',
|
|
19
|
+
OPTIONS: 'OPTIONS'
|
|
20
|
+
}.freeze
|
|
21
|
+
|
|
22
|
+
HEADER_KEYS = {
|
|
23
|
+
X_API_KEY: 'X-Api-Key'
|
|
24
|
+
}.freeze
|
|
25
|
+
|
|
26
|
+
FILE_TYPES = {
|
|
27
|
+
JSON: 'json'
|
|
28
|
+
}.freeze
|
|
29
|
+
|
|
30
|
+
FILE_FORMATS = {
|
|
31
|
+
APPLICATION_JSON: 'application/json'
|
|
32
|
+
}.freeze
|
|
33
|
+
|
|
34
|
+
HEADER_TYPES = {
|
|
35
|
+
CONTENT_TYPE: 'Content-Type'
|
|
36
|
+
}.freeze
|
|
37
|
+
|
|
38
|
+
ENDPOINTS = {
|
|
39
|
+
CONVERT: '/convert',
|
|
40
|
+
CONVERSIONS: {
|
|
41
|
+
GET: '/conversions/get',
|
|
42
|
+
LIST: '/conversions/list'
|
|
43
|
+
}.freeze
|
|
44
|
+
}.freeze
|
|
45
|
+
|
|
46
|
+
SELECT = {
|
|
47
|
+
CONVERSION: {
|
|
48
|
+
ID: 'id',
|
|
49
|
+
UNIQUE_ID: 'uniqueId',
|
|
50
|
+
DATA: 'data',
|
|
51
|
+
STATUS: 'status',
|
|
52
|
+
STARTED_AT: 'startedAt',
|
|
53
|
+
COMPLETED_AT: 'completedAt',
|
|
54
|
+
CREATED_AT: 'createdAt',
|
|
55
|
+
CREDITED: 'credited',
|
|
56
|
+
CONVERT_ONLY: 'convertOnly'
|
|
57
|
+
}.freeze,
|
|
58
|
+
DATA: {
|
|
59
|
+
IP: 'data.ip',
|
|
60
|
+
TYPE: 'data.type',
|
|
61
|
+
IS_EU: 'data.is_eu',
|
|
62
|
+
CONTINENT: {
|
|
63
|
+
NAME: 'data.continent.name',
|
|
64
|
+
CODE: 'data.continent.code',
|
|
65
|
+
GEONAME_ID: 'data.continent.geoname_id',
|
|
66
|
+
COUNTRY: {
|
|
67
|
+
NAME: 'data.continent.country.name',
|
|
68
|
+
CODE: 'data.continent.country.code',
|
|
69
|
+
GEONAME_ID: 'data.continent.country.geoname_id',
|
|
70
|
+
PHONE_CODE: 'data.continent.country.phone_code',
|
|
71
|
+
CAPITAL: 'data.continent.country.capital',
|
|
72
|
+
TLD: 'data.continent.country.tld',
|
|
73
|
+
SUBDIVISION: {
|
|
74
|
+
NAME: 'data.continent.country.subdivision.name',
|
|
75
|
+
CODE: 'data.continent.country.subdivision.code'
|
|
76
|
+
}.freeze,
|
|
77
|
+
CITY: {
|
|
78
|
+
NAME: 'data.continent.country.city.name',
|
|
79
|
+
GEONAME_ID: 'data.continent.country.city.geoname_id',
|
|
80
|
+
LATITUDE: 'data.continent.country.city.latitude',
|
|
81
|
+
LONGITUDE: 'data.continent.country.city.longitude',
|
|
82
|
+
ACCURACY_RADIUS: 'data.continent.country.city.accuracy_radius',
|
|
83
|
+
METRO_CODE: 'data.continent.country.city.metro_code',
|
|
84
|
+
POSTAL_CODE: 'data.continent.country.city.postal_code',
|
|
85
|
+
TIMEZONE: {
|
|
86
|
+
NAME: 'data.continent.country.city.timezone.name',
|
|
87
|
+
TIME_NOW: 'data.continent.country.city.timezone.time_now'
|
|
88
|
+
}.freeze
|
|
89
|
+
}.freeze,
|
|
90
|
+
FLAG: {
|
|
91
|
+
IMG: 'data.continent.country.flag.img',
|
|
92
|
+
EMOJI: 'data.continent.country.flag.emoji',
|
|
93
|
+
EMOJI_UNICODE: 'data.continent.country.flag.emoji_unicode'
|
|
94
|
+
}.freeze,
|
|
95
|
+
CURRENCY: {
|
|
96
|
+
NAME: 'data.continent.country.currency.name',
|
|
97
|
+
CODE: 'data.continent.country.currency.code',
|
|
98
|
+
SYMBOL: 'data.continent.country.currency.symbol'
|
|
99
|
+
}.freeze
|
|
100
|
+
}.freeze
|
|
101
|
+
}.freeze,
|
|
102
|
+
REGISTERED_COUNTRY: {
|
|
103
|
+
NAME: 'data.registered_country.name',
|
|
104
|
+
CODE: 'data.registered_country.code',
|
|
105
|
+
GEONAME_ID: 'data.registered_country.geoname_id'
|
|
106
|
+
}.freeze,
|
|
107
|
+
ASN: {
|
|
108
|
+
NUMBER: 'data.asn.number',
|
|
109
|
+
NAME: 'data.asn.name'
|
|
110
|
+
}.freeze,
|
|
111
|
+
COMPLETION_TIME: {
|
|
112
|
+
MILISECONDS: 'data.completion_time.miliseconds',
|
|
113
|
+
SECONDS: 'data.completion_time.seconds'
|
|
114
|
+
}.freeze
|
|
115
|
+
}.freeze
|
|
116
|
+
}.freeze
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ip2Geo
|
|
4
|
+
module Data
|
|
5
|
+
MESSAGES = {
|
|
6
|
+
conversions: {
|
|
7
|
+
'ip-address-is-required-to-convert-it' => 'IP address is required to convert it.',
|
|
8
|
+
'invalid-ip-address-so-we-could-not-convert-it' => 'Invalid IP address, so we could not convert it.',
|
|
9
|
+
'ip-addresses-are-required-to-convert-them' => 'IP addresses are required to convert them.',
|
|
10
|
+
'all-ip-addresses-are-invalid' => 'All IP addresses are invalid.',
|
|
11
|
+
'some-ip-addresses-are-invalid' => 'Some IP addresses are invalid.',
|
|
12
|
+
'conversion-id-is-required' => 'Conversion ID is required.',
|
|
13
|
+
'conversion-ids-are-required' => 'Conversion IDs are required.'
|
|
14
|
+
}
|
|
15
|
+
}.freeze
|
|
16
|
+
|
|
17
|
+
def self.translate(key)
|
|
18
|
+
keys = key.split('.')
|
|
19
|
+
result = MESSAGES
|
|
20
|
+
|
|
21
|
+
keys.each do |k|
|
|
22
|
+
result = result[k.to_sym] || result[k]
|
|
23
|
+
return key if result.nil?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
result
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ip2Geo
|
|
4
|
+
module Data
|
|
5
|
+
class State
|
|
6
|
+
class << self
|
|
7
|
+
attr_accessor :auth_key, :version_update_message, :is_version_checked
|
|
8
|
+
|
|
9
|
+
def reset!
|
|
10
|
+
@auth_key = nil
|
|
11
|
+
@version_update_message = true
|
|
12
|
+
@is_version_checked = false
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
reset!
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
module Ip2Geo
|
|
7
|
+
module Helpers
|
|
8
|
+
class CheckVersion
|
|
9
|
+
RUBYGEMS_API_URL = 'https://rubygems.org/api/v1/gems/ip2geo.json'
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
def call
|
|
13
|
+
return if Data::State.is_version_checked || !Data::State.version_update_message
|
|
14
|
+
|
|
15
|
+
Data::State.is_version_checked = true
|
|
16
|
+
|
|
17
|
+
current_version = Ip2Geo::VERSION
|
|
18
|
+
latest_version = fetch_latest_version
|
|
19
|
+
|
|
20
|
+
return unless current_version && latest_version
|
|
21
|
+
return if current_version == latest_version
|
|
22
|
+
|
|
23
|
+
display_update_message(current_version, latest_version)
|
|
24
|
+
rescue StandardError
|
|
25
|
+
# Silently fail - version check is non-critical
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def fetch_latest_version
|
|
31
|
+
uri = URI.parse(RUBYGEMS_API_URL)
|
|
32
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
33
|
+
http.use_ssl = true
|
|
34
|
+
http.open_timeout = 5
|
|
35
|
+
http.read_timeout = 5
|
|
36
|
+
|
|
37
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
|
38
|
+
response = http.request(request)
|
|
39
|
+
|
|
40
|
+
return nil unless response.is_a?(Net::HTTPSuccess)
|
|
41
|
+
|
|
42
|
+
data = JSON.parse(response.body)
|
|
43
|
+
data['version']
|
|
44
|
+
rescue StandardError
|
|
45
|
+
nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def display_update_message(current_version, latest_version)
|
|
49
|
+
box_width = 70
|
|
50
|
+
top_border = "\u250C#{"\u2500" * (box_width - 2)}\u2510"
|
|
51
|
+
bottom_border = "\u2514#{"\u2500" * (box_width - 2)}\u2518"
|
|
52
|
+
|
|
53
|
+
lines = [
|
|
54
|
+
'',
|
|
55
|
+
top_border,
|
|
56
|
+
center_text("\e[1m\e[33mUpdate available\e[0m \e[2m#{current_version} \u2192 #{latest_version}\e[0m", box_width),
|
|
57
|
+
center_text("Changelog: \e[36mhttps://docs.ip2geo.dev/sdk/changelogs\e[0m", box_width),
|
|
58
|
+
center_text("Run \e[32m`gem update ip2geo`\e[0m to update.", box_width),
|
|
59
|
+
center_text('', box_width),
|
|
60
|
+
center_text("Disable this warning using: \e[36mversion_update_message: false\e[0m on init.", box_width),
|
|
61
|
+
bottom_border,
|
|
62
|
+
''
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
lines.each { |line| warn line }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def center_text(text, box_width)
|
|
69
|
+
visible_length = text.gsub(/\e\[[0-9;]*m/, '').length
|
|
70
|
+
padding = [(box_width - 2 - visible_length) / 2, 0].max
|
|
71
|
+
right_padding = [box_width - 2 - padding - visible_length, 0].max
|
|
72
|
+
|
|
73
|
+
"\u2502#{' ' * padding}#{text}#{' ' * right_padding}\u2502"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'uri'
|
|
5
|
+
require 'json'
|
|
6
|
+
require 'openssl'
|
|
7
|
+
|
|
8
|
+
module Ip2Geo
|
|
9
|
+
module Helpers
|
|
10
|
+
class Http
|
|
11
|
+
class << self
|
|
12
|
+
def request(endpoint, body = nil)
|
|
13
|
+
uri = URI.parse(endpoint)
|
|
14
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
15
|
+
http.use_ssl = uri.scheme == 'https'
|
|
16
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
17
|
+
http.ssl_version = :TLSv1_2
|
|
18
|
+
http.open_timeout = 30
|
|
19
|
+
http.read_timeout = 30
|
|
20
|
+
|
|
21
|
+
# Fix for macOS certificate CRL verification issues
|
|
22
|
+
cert_store = OpenSSL::X509::Store.new
|
|
23
|
+
cert_store.set_default_paths
|
|
24
|
+
http.cert_store = cert_store
|
|
25
|
+
|
|
26
|
+
headers = {
|
|
27
|
+
Data::HEADER_TYPES[:CONTENT_TYPE] => Data::FILE_FORMATS[:APPLICATION_JSON],
|
|
28
|
+
Data::HEADER_KEYS[:X_API_KEY] => Data::State.auth_key
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if body && !body.empty?
|
|
32
|
+
request = Net::HTTP::Post.new(uri.request_uri, headers)
|
|
33
|
+
request.body = body.to_json
|
|
34
|
+
else
|
|
35
|
+
request = Net::HTTP::Get.new(uri.request_uri, headers)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
response = http.request(request)
|
|
39
|
+
JSON.parse(response.body, symbolize_names: false)
|
|
40
|
+
rescue StandardError => e
|
|
41
|
+
warn "[Ip2Geo::Http] Error: #{e.message}"
|
|
42
|
+
nil
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ip2Geo
|
|
4
|
+
module Helpers
|
|
5
|
+
class IpValidation
|
|
6
|
+
IPV4_REGEX = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.freeze
|
|
7
|
+
IPV6_REGEX = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^([0-9a-fA-F]{1,4}:){1,7}:$|^([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}$|^([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}$|^([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}$|^([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}$|^([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}$|^[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6}|:)$|^:((:[0-9a-fA-F]{1,4}){1,7}|:)$/.freeze
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
# Validate an IP address and return if it is IPv4 or IPv6.
|
|
11
|
+
#
|
|
12
|
+
# @param ip_address [String] The IP address to validate
|
|
13
|
+
# @return [Hash] A hash with :ip4 and :ip6 boolean values
|
|
14
|
+
def validate(ip_address)
|
|
15
|
+
return { ip4: false, ip6: false } unless ip_address.is_a?(String)
|
|
16
|
+
|
|
17
|
+
{
|
|
18
|
+
ip4: IPV4_REGEX.match?(ip_address),
|
|
19
|
+
ip6: IPV6_REGEX.match?(ip_address)
|
|
20
|
+
}
|
|
21
|
+
rescue StandardError => e
|
|
22
|
+
warn "[Ip2Geo::IpValidation] Error: #{e.message}"
|
|
23
|
+
{ ip4: false, ip6: false }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ip2Geo
|
|
4
|
+
module Methods
|
|
5
|
+
class ConvertIP
|
|
6
|
+
class << self
|
|
7
|
+
# Get geo information from an IP address.
|
|
8
|
+
#
|
|
9
|
+
# @param options [Hash] The options for the conversion
|
|
10
|
+
# @option options [String] :ip The IP address to retrieve geo information for (required)
|
|
11
|
+
# @option options [Boolean] :convert_only If true, stores minimal data and charges $0.001 per conversion
|
|
12
|
+
# instead of $0.0005 (default: false)
|
|
13
|
+
# @return [Hash, nil] The API response containing geo data, or nil if the request fails
|
|
14
|
+
def call(options = {})
|
|
15
|
+
ip = options[:ip]
|
|
16
|
+
convert_only = options.fetch(:convert_only, false)
|
|
17
|
+
|
|
18
|
+
unless ip
|
|
19
|
+
return error_response(
|
|
20
|
+
Data.translate('conversions.ip-address-is-required-to-convert-it')
|
|
21
|
+
)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
validation = Helpers::IpValidation.validate(ip)
|
|
25
|
+
|
|
26
|
+
unless validation[:ip4] || validation[:ip6]
|
|
27
|
+
return error_response(
|
|
28
|
+
Data.translate('conversions.invalid-ip-address-so-we-could-not-convert-it')
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
url = "#{Data::API_ENDPOINT}#{Data::ENDPOINTS[:CONVERT]}?ip=#{ip}&convertOnly=#{convert_only}"
|
|
33
|
+
Helpers::Http.request(url)
|
|
34
|
+
rescue StandardError => e
|
|
35
|
+
warn "[Ip2Geo::ConvertIP] Error: #{e.message}"
|
|
36
|
+
nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def error_response(message)
|
|
42
|
+
{
|
|
43
|
+
'success' => false,
|
|
44
|
+
'message' => message,
|
|
45
|
+
'code' => 400,
|
|
46
|
+
'data' => nil,
|
|
47
|
+
'_req' => {
|
|
48
|
+
'reqId' => nil,
|
|
49
|
+
'resTime' => 0
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ip2Geo
|
|
4
|
+
module Methods
|
|
5
|
+
class ConvertIPs
|
|
6
|
+
class << self
|
|
7
|
+
# Get geo information from multiple IP addresses.
|
|
8
|
+
#
|
|
9
|
+
# @param options [Hash] The options for the conversion
|
|
10
|
+
# @option options [Array<String>] :ips An array of IP addresses to retrieve geo information for (required)
|
|
11
|
+
# @option options [Boolean] :convert_only If true, stores minimal data and charges $0.001 per conversion
|
|
12
|
+
# instead of $0.0005 (default: false)
|
|
13
|
+
# @return [Hash, nil] The API response containing geo data for all IPs, or nil if the request fails
|
|
14
|
+
def call(options = {})
|
|
15
|
+
ips = options[:ips]
|
|
16
|
+
convert_only = options.fetch(:convert_only, false)
|
|
17
|
+
|
|
18
|
+
unless ips.is_a?(Array) && !ips.empty?
|
|
19
|
+
return error_response(
|
|
20
|
+
Data.translate('conversions.ip-addresses-are-required-to-convert-them'),
|
|
21
|
+
nil
|
|
22
|
+
)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
valid_ips = []
|
|
26
|
+
invalid_ips = []
|
|
27
|
+
|
|
28
|
+
ips.each do |ip|
|
|
29
|
+
validation = Helpers::IpValidation.validate(ip)
|
|
30
|
+
if validation[:ip4] || validation[:ip6]
|
|
31
|
+
valid_ips << ip
|
|
32
|
+
else
|
|
33
|
+
invalid_ips << ip
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if invalid_ips.any?
|
|
38
|
+
all_invalid = invalid_ips.length == ips.length
|
|
39
|
+
message = all_invalid ? 'conversions.all-ip-addresses-are-invalid' : 'conversions.some-ip-addresses-are-invalid'
|
|
40
|
+
|
|
41
|
+
return error_response(
|
|
42
|
+
Data.translate(message),
|
|
43
|
+
invalid_ips.map { |ip| { 'ip' => ip, 'conversion' => nil } }
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
url = "#{Data::API_ENDPOINT}#{Data::ENDPOINTS[:CONVERT]}"
|
|
48
|
+
body = { ips: ips, convertOnly: convert_only }
|
|
49
|
+
|
|
50
|
+
Helpers::Http.request(url, body)
|
|
51
|
+
rescue StandardError => e
|
|
52
|
+
warn "[Ip2Geo::ConvertIPs] Error: #{e.message}"
|
|
53
|
+
nil
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def error_response(message, data)
|
|
59
|
+
{
|
|
60
|
+
'success' => false,
|
|
61
|
+
'message' => message,
|
|
62
|
+
'code' => 400,
|
|
63
|
+
'data' => data,
|
|
64
|
+
'_req' => {
|
|
65
|
+
'reqId' => nil,
|
|
66
|
+
'resTime' => 0
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ip2Geo
|
|
4
|
+
module Methods
|
|
5
|
+
class GetConversion
|
|
6
|
+
class << self
|
|
7
|
+
# Retrieve a single conversion by its ID.
|
|
8
|
+
#
|
|
9
|
+
# @param options [Hash] The options for retrieving the conversion
|
|
10
|
+
# @option options [String] :conversion_id The unique identifier of the conversion to retrieve (required)
|
|
11
|
+
# @option options [Array<String>] :select Optional array of property names to return
|
|
12
|
+
# @return [Hash, nil] The API response containing conversion data, or nil if the request fails
|
|
13
|
+
def call(options = {})
|
|
14
|
+
conversion_id = options[:conversion_id]
|
|
15
|
+
select = options[:select]
|
|
16
|
+
|
|
17
|
+
unless conversion_id
|
|
18
|
+
return error_response(
|
|
19
|
+
Data.translate('conversions.conversion-id-is-required')
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
params = []
|
|
24
|
+
params << "select=#{select.join(',')}" if select.is_a?(Array) && !select.empty?
|
|
25
|
+
|
|
26
|
+
query_string = params.empty? ? '' : "?#{params.join('&')}"
|
|
27
|
+
url = "#{Data::API_ENDPOINT}#{Data::ENDPOINTS[:CONVERSIONS][:GET]}#{query_string}"
|
|
28
|
+
|
|
29
|
+
Helpers::Http.request(url, { conversionId: conversion_id })
|
|
30
|
+
rescue StandardError => e
|
|
31
|
+
warn "[Ip2Geo::GetConversion] Error: #{e.message}"
|
|
32
|
+
nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def error_response(message)
|
|
38
|
+
{
|
|
39
|
+
'success' => false,
|
|
40
|
+
'message' => message,
|
|
41
|
+
'code' => 400,
|
|
42
|
+
'data' => nil,
|
|
43
|
+
'_req' => {
|
|
44
|
+
'reqId' => nil,
|
|
45
|
+
'resTime' => 0
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ip2Geo
|
|
4
|
+
module Methods
|
|
5
|
+
class GetConversions
|
|
6
|
+
class << self
|
|
7
|
+
# Retrieve multiple conversions by their IDs.
|
|
8
|
+
#
|
|
9
|
+
# @param options [Hash] The options for retrieving conversions
|
|
10
|
+
# @option options [Array<String>] :conversion_ids An array of unique identifiers to retrieve (required)
|
|
11
|
+
# @option options [Array<String>] :select Optional array of property names to return
|
|
12
|
+
# @return [Hash, nil] The API response containing conversions data, or nil if the request fails
|
|
13
|
+
def call(options = {})
|
|
14
|
+
conversion_ids = options[:conversion_ids]
|
|
15
|
+
select = options[:select]
|
|
16
|
+
|
|
17
|
+
unless conversion_ids.is_a?(Array) && !conversion_ids.empty?
|
|
18
|
+
return error_response(
|
|
19
|
+
Data.translate('conversions.conversion-ids-are-required')
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
params = []
|
|
24
|
+
params << "select=#{select.join(',')}" if select.is_a?(Array) && !select.empty?
|
|
25
|
+
|
|
26
|
+
query_string = params.empty? ? '' : "?#{params.join('&')}"
|
|
27
|
+
url = "#{Data::API_ENDPOINT}#{Data::ENDPOINTS[:CONVERSIONS][:GET]}#{query_string}"
|
|
28
|
+
|
|
29
|
+
Helpers::Http.request(url, { conversionIds: conversion_ids })
|
|
30
|
+
rescue StandardError => e
|
|
31
|
+
warn "[Ip2Geo::GetConversions] Error: #{e.message}"
|
|
32
|
+
nil
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def error_response(message)
|
|
38
|
+
{
|
|
39
|
+
'success' => false,
|
|
40
|
+
'message' => message,
|
|
41
|
+
'code' => 400,
|
|
42
|
+
'data' => nil,
|
|
43
|
+
'_req' => {
|
|
44
|
+
'reqId' => nil,
|
|
45
|
+
'resTime' => 0
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ip2Geo
|
|
4
|
+
module Methods
|
|
5
|
+
class Init
|
|
6
|
+
class << self
|
|
7
|
+
# Initializes the SDK with the given API key.
|
|
8
|
+
#
|
|
9
|
+
# @param key [String] The API key used to authenticate with Ip2Geo
|
|
10
|
+
# @param options [Hash] Optional configuration
|
|
11
|
+
# @option options [Boolean] :version_update_message Whether to display version update messages (default: true)
|
|
12
|
+
# @return [Boolean] Whether the initialization was successful
|
|
13
|
+
def call(key, options = {})
|
|
14
|
+
Data::State.auth_key = key
|
|
15
|
+
Data::State.version_update_message = options.fetch(:version_update_message, true)
|
|
16
|
+
|
|
17
|
+
Helpers::CheckVersion.call
|
|
18
|
+
|
|
19
|
+
true
|
|
20
|
+
rescue StandardError => e
|
|
21
|
+
Data::State.reset!
|
|
22
|
+
warn "[Ip2Geo::Init] Error: #{e.message}"
|
|
23
|
+
false
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ip2Geo
|
|
4
|
+
module Methods
|
|
5
|
+
class ListConversions
|
|
6
|
+
class << self
|
|
7
|
+
# List conversions with pagination and optional filtering.
|
|
8
|
+
#
|
|
9
|
+
# @param options [Hash] The options for listing conversions
|
|
10
|
+
# @option options [Integer] :offset The number of conversions to skip (default: 0)
|
|
11
|
+
# @option options [Integer] :limit The maximum number of conversions to return (default: 50, max: 50)
|
|
12
|
+
# @option options [Array<String>] :select Optional array of property names to return
|
|
13
|
+
# @option options [String] :ip_search Filter conversions by IP address
|
|
14
|
+
# @return [Hash, nil] The API response containing conversions list with pagination info, or nil if fails
|
|
15
|
+
def call(options = {})
|
|
16
|
+
offset = options.fetch(:offset, 0)
|
|
17
|
+
limit = options.fetch(:limit, 50)
|
|
18
|
+
select = options[:select]
|
|
19
|
+
ip_search = options[:ip_search]
|
|
20
|
+
|
|
21
|
+
params = []
|
|
22
|
+
params << "offset=#{offset}" if offset.positive?
|
|
23
|
+
params << "limit=#{limit}" if limit != 50
|
|
24
|
+
params << "select=#{select.join(',')}" if select.is_a?(Array) && !select.empty?
|
|
25
|
+
params << "ipSearch=#{ip_search}" if ip_search
|
|
26
|
+
|
|
27
|
+
query_string = params.empty? ? '' : "?#{params.join('&')}"
|
|
28
|
+
url = "#{Data::API_ENDPOINT}#{Data::ENDPOINTS[:CONVERSIONS][:LIST]}#{query_string}"
|
|
29
|
+
|
|
30
|
+
Helpers::Http.request(url)
|
|
31
|
+
rescue StandardError => e
|
|
32
|
+
warn "[Ip2Geo::ListConversions] Error: #{e.message}"
|
|
33
|
+
nil
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/ip2geo.rb
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Ip2Geo Ruby SDK
|
|
4
|
+
# Official Ruby SDK for Ip2Geo - IP to Geolocation API
|
|
5
|
+
#
|
|
6
|
+
# @example Basic usage
|
|
7
|
+
# require 'ip2geo'
|
|
8
|
+
#
|
|
9
|
+
# # Initialize with your API key
|
|
10
|
+
# Ip2Geo.init('your-api-key')
|
|
11
|
+
#
|
|
12
|
+
# # Convert a single IP address
|
|
13
|
+
# result = Ip2Geo.convert_ip(ip: '8.8.8.8')
|
|
14
|
+
#
|
|
15
|
+
# # Convert multiple IP addresses
|
|
16
|
+
# result = Ip2Geo.convert_ips(ips: ['8.8.8.8', '1.1.1.1'])
|
|
17
|
+
#
|
|
18
|
+
# # List your conversions
|
|
19
|
+
# result = Ip2Geo.list_conversions(limit: 10)
|
|
20
|
+
|
|
21
|
+
require_relative 'ip2geo/data/constants'
|
|
22
|
+
require_relative 'ip2geo/data/states'
|
|
23
|
+
require_relative 'ip2geo/data/messages'
|
|
24
|
+
require_relative 'ip2geo/helpers/http'
|
|
25
|
+
require_relative 'ip2geo/helpers/ip_validation'
|
|
26
|
+
require_relative 'ip2geo/helpers/check_version'
|
|
27
|
+
require_relative 'ip2geo/methods/init'
|
|
28
|
+
require_relative 'ip2geo/methods/convert_ip'
|
|
29
|
+
require_relative 'ip2geo/methods/convert_ips'
|
|
30
|
+
require_relative 'ip2geo/methods/get_conversion'
|
|
31
|
+
require_relative 'ip2geo/methods/get_conversions'
|
|
32
|
+
require_relative 'ip2geo/methods/list_conversions'
|
|
33
|
+
|
|
34
|
+
module Ip2Geo
|
|
35
|
+
VERSION = '0.0.1'
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
# Initializes the SDK with the given API key.
|
|
39
|
+
#
|
|
40
|
+
# @param key [String] The API key used to authenticate with Ip2Geo
|
|
41
|
+
# @param options [Hash] Optional configuration
|
|
42
|
+
# @option options [Boolean] :version_update_message Whether to display version update messages (default: true)
|
|
43
|
+
# @return [Boolean] Whether the initialization was successful
|
|
44
|
+
#
|
|
45
|
+
# @example
|
|
46
|
+
# Ip2Geo.init('your-api-key')
|
|
47
|
+
# Ip2Geo.init('your-api-key', version_update_message: false)
|
|
48
|
+
def init(key, options = {})
|
|
49
|
+
Methods::Init.call(key, options)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Get geo information from an IP address.
|
|
53
|
+
#
|
|
54
|
+
# @param options [Hash] The options for the conversion
|
|
55
|
+
# @option options [String] :ip The IP address to retrieve geo information for (required)
|
|
56
|
+
# @option options [Boolean] :convert_only If true, stores minimal data (default: false)
|
|
57
|
+
# @return [Hash, nil] The API response containing geo data
|
|
58
|
+
#
|
|
59
|
+
# @example
|
|
60
|
+
# result = Ip2Geo.convert_ip(ip: '8.8.8.8')
|
|
61
|
+
# result = Ip2Geo.convert_ip(ip: '8.8.8.8', convert_only: true)
|
|
62
|
+
def convert_ip(options = {})
|
|
63
|
+
Methods::ConvertIP.call(options)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Get geo information from multiple IP addresses.
|
|
67
|
+
#
|
|
68
|
+
# @param options [Hash] The options for the conversion
|
|
69
|
+
# @option options [Array<String>] :ips An array of IP addresses (required)
|
|
70
|
+
# @option options [Boolean] :convert_only If true, stores minimal data (default: false)
|
|
71
|
+
# @return [Hash, nil] The API response containing geo data for all IPs
|
|
72
|
+
#
|
|
73
|
+
# @example
|
|
74
|
+
# result = Ip2Geo.convert_ips(ips: ['8.8.8.8', '1.1.1.1'])
|
|
75
|
+
def convert_ips(options = {})
|
|
76
|
+
Methods::ConvertIPs.call(options)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Retrieve a single conversion by its ID.
|
|
80
|
+
#
|
|
81
|
+
# @param options [Hash] The options for retrieving the conversion
|
|
82
|
+
# @option options [String] :conversion_id The unique identifier (required)
|
|
83
|
+
# @option options [Array<String>] :select Optional array of property names to return
|
|
84
|
+
# @return [Hash, nil] The API response containing conversion data
|
|
85
|
+
#
|
|
86
|
+
# @example
|
|
87
|
+
# result = Ip2Geo.get_conversion(conversion_id: 'abc123')
|
|
88
|
+
# result = Ip2Geo.get_conversion(conversion_id: 'abc123', select: ['id', 'data.ip'])
|
|
89
|
+
def get_conversion(options = {})
|
|
90
|
+
Methods::GetConversion.call(options)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Retrieve multiple conversions by their IDs.
|
|
94
|
+
#
|
|
95
|
+
# @param options [Hash] The options for retrieving conversions
|
|
96
|
+
# @option options [Array<String>] :conversion_ids An array of unique identifiers (required)
|
|
97
|
+
# @option options [Array<String>] :select Optional array of property names to return
|
|
98
|
+
# @return [Hash, nil] The API response containing conversions data
|
|
99
|
+
#
|
|
100
|
+
# @example
|
|
101
|
+
# result = Ip2Geo.get_conversions(conversion_ids: ['abc123', 'def456'])
|
|
102
|
+
def get_conversions(options = {})
|
|
103
|
+
Methods::GetConversions.call(options)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# List conversions with pagination and optional filtering.
|
|
107
|
+
#
|
|
108
|
+
# @param options [Hash] The options for listing conversions
|
|
109
|
+
# @option options [Integer] :offset The number of conversions to skip (default: 0)
|
|
110
|
+
# @option options [Integer] :limit The maximum number to return (default: 50, max: 50)
|
|
111
|
+
# @option options [Array<String>] :select Optional array of property names to return
|
|
112
|
+
# @option options [String] :ip_search Filter conversions by IP address
|
|
113
|
+
# @return [Hash, nil] The API response containing conversions list with pagination info
|
|
114
|
+
#
|
|
115
|
+
# @example
|
|
116
|
+
# result = Ip2Geo.list_conversions
|
|
117
|
+
# result = Ip2Geo.list_conversions(limit: 10, offset: 20)
|
|
118
|
+
# result = Ip2Geo.list_conversions(ip_search: '8.8.8.8')
|
|
119
|
+
def list_conversions(options = {})
|
|
120
|
+
Methods::ListConversions.call(options)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Validate an IP address and return if it is IPv4 or IPv6.
|
|
124
|
+
#
|
|
125
|
+
# @param ip_address [String] The IP address to validate
|
|
126
|
+
# @return [Hash] A hash with :ip4 and :ip6 boolean values
|
|
127
|
+
#
|
|
128
|
+
# @example
|
|
129
|
+
# result = Ip2Geo.ip_validation('8.8.8.8')
|
|
130
|
+
# # => { ip4: true, ip6: false }
|
|
131
|
+
def ip_validation(ip_address)
|
|
132
|
+
Helpers::IpValidation.validate(ip_address)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# SELECT constants for field selection
|
|
136
|
+
#
|
|
137
|
+
# @return [Hash] The SELECT constants
|
|
138
|
+
#
|
|
139
|
+
# @example
|
|
140
|
+
# Ip2Geo.select[:CONVERSION][:ID]
|
|
141
|
+
# # => 'id'
|
|
142
|
+
# Ip2Geo.select[:DATA][:CONTINENT][:COUNTRY][:NAME]
|
|
143
|
+
# # => 'data.continent.country.name'
|
|
144
|
+
def select
|
|
145
|
+
Data::SELECT
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ip2geo
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Ip2Geo
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-01-30 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: json
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '2.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '2.0'
|
|
26
|
+
description: A lightweight Ruby client for the Ip2Geo cloud service. Get accurate
|
|
27
|
+
geolocation data for IP addresses including continent, country, city, timezone,
|
|
28
|
+
ASN, and more.
|
|
29
|
+
email:
|
|
30
|
+
- support@ip2geo.dev
|
|
31
|
+
executables: []
|
|
32
|
+
extensions: []
|
|
33
|
+
extra_rdoc_files: []
|
|
34
|
+
files:
|
|
35
|
+
- LICENSE
|
|
36
|
+
- README.md
|
|
37
|
+
- ip2geo.gemspec
|
|
38
|
+
- lib/ip2geo.rb
|
|
39
|
+
- lib/ip2geo/data/constants.rb
|
|
40
|
+
- lib/ip2geo/data/messages.rb
|
|
41
|
+
- lib/ip2geo/data/states.rb
|
|
42
|
+
- lib/ip2geo/helpers/check_version.rb
|
|
43
|
+
- lib/ip2geo/helpers/http.rb
|
|
44
|
+
- lib/ip2geo/helpers/ip_validation.rb
|
|
45
|
+
- lib/ip2geo/methods/convert_ip.rb
|
|
46
|
+
- lib/ip2geo/methods/convert_ips.rb
|
|
47
|
+
- lib/ip2geo/methods/get_conversion.rb
|
|
48
|
+
- lib/ip2geo/methods/get_conversions.rb
|
|
49
|
+
- lib/ip2geo/methods/init.rb
|
|
50
|
+
- lib/ip2geo/methods/list_conversions.rb
|
|
51
|
+
homepage: https://ip2geo.dev
|
|
52
|
+
licenses:
|
|
53
|
+
- Nonstandard
|
|
54
|
+
metadata:
|
|
55
|
+
homepage_uri: https://ip2geo.dev
|
|
56
|
+
changelog_uri: https://docs.ip2geo.dev/changelog
|
|
57
|
+
documentation_uri: https://docs.ip2geo.dev
|
|
58
|
+
rdoc_options: []
|
|
59
|
+
require_paths:
|
|
60
|
+
- lib
|
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: 2.7.0
|
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - ">="
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '0'
|
|
71
|
+
requirements: []
|
|
72
|
+
rubygems_version: 3.6.3
|
|
73
|
+
specification_version: 4
|
|
74
|
+
summary: Official Ruby SDK for Ip2Geo - IP to Geolocation API.
|
|
75
|
+
test_files: []
|