IPinfo 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/cd_rubygems.yaml +34 -0
- data/.github/workflows/unittest.yaml +31 -0
- data/.rubocop.yml +6 -0
- data/README.md +80 -10
- data/ipinfo.gemspec +0 -10
- data/lib/ipinfo/adapter.rb +8 -1
- data/lib/ipinfo/continent.json +252 -0
- data/lib/ipinfo/currency.json +253 -0
- data/lib/ipinfo/eu.json +1 -0
- data/lib/ipinfo/flags.json +252 -0
- data/lib/ipinfo/ipAddressMatcher.rb +92 -0
- data/lib/ipinfo/version.rb +1 -1
- data/lib/ipinfo.rb +110 -4
- metadata +9 -3
- data/.travis.yml +0 -11
data/lib/ipinfo.rb
CHANGED
@@ -8,14 +8,27 @@ require 'ipinfo/errors'
|
|
8
8
|
require 'ipinfo/response'
|
9
9
|
require 'ipinfo/version'
|
10
10
|
require 'json'
|
11
|
+
require_relative 'ipinfo/ipAddressMatcher'
|
11
12
|
|
12
13
|
module IPinfo
|
13
14
|
DEFAULT_CACHE_MAXSIZE = 4096
|
14
15
|
DEFAULT_CACHE_TTL = 60 * 60 * 24
|
15
16
|
DEFAULT_COUNTRY_FILE = File.join(File.dirname(__FILE__),
|
16
17
|
'ipinfo/countries.json')
|
18
|
+
DEFAULT_EU_COUNTRIES_FILE = File.join(File.dirname(__FILE__),
|
19
|
+
'ipinfo/eu.json')
|
20
|
+
DEFAULT_COUNTRIES_FLAG_FILE = File.join(File.dirname(__FILE__),
|
21
|
+
'ipinfo/flags.json')
|
22
|
+
DEFAULT_COUNTRIES_CURRENCIES_FILE = File.join(File.dirname(__FILE__),
|
23
|
+
'ipinfo/currency.json')
|
24
|
+
DEFAULT_CONTINENT_FILE = File.join(File.dirname(__FILE__),
|
25
|
+
'ipinfo/continent.json')
|
17
26
|
RATE_LIMIT_MESSAGE = 'To increase your limits, please review our ' \
|
18
27
|
'paid plans at https://ipinfo.io/pricing'
|
28
|
+
# Base URL to get country flag image link.
|
29
|
+
# "PK" -> "https://cdn.ipinfo.io/static/images/countries-flags/PK.svg"
|
30
|
+
COUNTRY_FLAGS_URL = "https://cdn.ipinfo.io/static/images/countries-flags/"
|
31
|
+
|
19
32
|
|
20
33
|
class << self
|
21
34
|
def create(access_token = nil, settings = {})
|
@@ -35,8 +48,16 @@ class IPinfo::IPinfo
|
|
35
48
|
maxsize = settings.fetch('maxsize', DEFAULT_CACHE_MAXSIZE)
|
36
49
|
ttl = settings.fetch('ttl', DEFAULT_CACHE_TTL)
|
37
50
|
@cache = settings.fetch('cache', DefaultCache.new(ttl, maxsize))
|
38
|
-
@countries =
|
51
|
+
@countries = prepare_json(settings.fetch('countries',
|
39
52
|
DEFAULT_COUNTRY_FILE))
|
53
|
+
@eu_countries = prepare_json(settings.fetch('eu_countries',
|
54
|
+
DEFAULT_EU_COUNTRIES_FILE))
|
55
|
+
@countries_flags = prepare_json(settings.fetch('countries_flags',
|
56
|
+
DEFAULT_COUNTRIES_FLAG_FILE))
|
57
|
+
@countries_currencies = prepare_json(settings.fetch('countries_currencies',
|
58
|
+
DEFAULT_COUNTRIES_CURRENCIES_FILE))
|
59
|
+
@continents = prepare_json(settings.fetch('continents',
|
60
|
+
DEFAULT_CONTINENT_FILE))
|
40
61
|
end
|
41
62
|
|
42
63
|
def details(ip_address = nil)
|
@@ -44,6 +65,15 @@ class IPinfo::IPinfo
|
|
44
65
|
if details.key? :country
|
45
66
|
details[:country_name] =
|
46
67
|
@countries.fetch(details.fetch(:country), nil)
|
68
|
+
details[:is_eu] =
|
69
|
+
@eu_countries.include?(details.fetch(:country))
|
70
|
+
details[:country_flag] =
|
71
|
+
@countries_flags.fetch(details.fetch(:country), nil)
|
72
|
+
details[:country_currency] =
|
73
|
+
@countries_currencies.fetch(details.fetch(:country), nil)
|
74
|
+
details[:continent] =
|
75
|
+
@continents.fetch(details.fetch(:country), nil)
|
76
|
+
details[:country_flag_url] = COUNTRY_FLAGS_URL + details.fetch(:country) + ".svg"
|
47
77
|
end
|
48
78
|
|
49
79
|
if details.key? :ip
|
@@ -60,10 +90,73 @@ class IPinfo::IPinfo
|
|
60
90
|
Response.new(details)
|
61
91
|
end
|
62
92
|
|
93
|
+
def get_map_url(ips)
|
94
|
+
if !ips.kind_of?(Array)
|
95
|
+
return JSON.generate({:error => 'Invalid input. Array required!'})
|
96
|
+
end
|
97
|
+
if ips.length > 500000
|
98
|
+
return JSON.generate({:error => 'No more than 500,000 ips allowed!'})
|
99
|
+
end
|
100
|
+
|
101
|
+
json_ips = JSON.generate({:ips => ips})
|
102
|
+
res = @httpc.post('/tools/map', json_ips)
|
103
|
+
|
104
|
+
obj = JSON.parse(res.body)
|
105
|
+
obj['reportUrl']
|
106
|
+
end
|
107
|
+
|
108
|
+
def batch_requests(url_array, api_token)
|
109
|
+
result = Hash.new
|
110
|
+
lookup_ips = []
|
111
|
+
|
112
|
+
url_array.each { |url|
|
113
|
+
ip = @cache.get(cache_key(url))
|
114
|
+
|
115
|
+
unless ip.nil?
|
116
|
+
result.store(url, ip)
|
117
|
+
else
|
118
|
+
lookup_ips << url
|
119
|
+
end
|
120
|
+
}
|
121
|
+
|
122
|
+
if lookup_ips.empty?
|
123
|
+
return result
|
124
|
+
end
|
125
|
+
|
126
|
+
begin
|
127
|
+
lookup_ips.each_slice(1000){ |ips|
|
128
|
+
json_arr = JSON.generate(lookup_ips)
|
129
|
+
res = @httpc.post("/batch?token=#{api_token}", json_arr, 5)
|
130
|
+
|
131
|
+
raise StandardError, "Request Quota Exceeded" if res.status == 429
|
132
|
+
|
133
|
+
data = JSON.parse(res.body)
|
134
|
+
data.each { |key, val|
|
135
|
+
@cache.set(cache_key(key), val)
|
136
|
+
}
|
137
|
+
|
138
|
+
result.merge!(data)
|
139
|
+
}
|
140
|
+
|
141
|
+
rescue StandardError => e
|
142
|
+
return e.message
|
143
|
+
end
|
144
|
+
|
145
|
+
result
|
146
|
+
end
|
147
|
+
|
63
148
|
protected
|
64
149
|
|
65
150
|
def request_details(ip_address = nil)
|
66
|
-
|
151
|
+
if isBogon(ip_address)
|
152
|
+
details[:ip] = ip_address
|
153
|
+
details[:bogon] = true
|
154
|
+
details[:ip_address] = IPAddr.new(ip_address)
|
155
|
+
|
156
|
+
return details
|
157
|
+
end
|
158
|
+
|
159
|
+
res = @cache.get(cache_key(ip_address))
|
67
160
|
return res unless res.nil?
|
68
161
|
|
69
162
|
response = @httpc.get(escape_path(ip_address))
|
@@ -74,7 +167,7 @@ class IPinfo::IPinfo
|
|
74
167
|
end
|
75
168
|
|
76
169
|
details = JSON.parse(response.body, symbolize_names: true)
|
77
|
-
@cache.set(ip_address, details)
|
170
|
+
@cache.set(cache_key(ip_address), details)
|
78
171
|
details
|
79
172
|
end
|
80
173
|
|
@@ -86,14 +179,27 @@ class IPinfo::IPinfo
|
|
86
179
|
end
|
87
180
|
end
|
88
181
|
|
89
|
-
def
|
182
|
+
def prepare_json(filename)
|
90
183
|
file = File.read(filename)
|
91
184
|
JSON.parse(file)
|
92
185
|
end
|
93
186
|
|
94
187
|
private
|
95
188
|
|
189
|
+
def isBogon(ip)
|
190
|
+
if ip.nil?
|
191
|
+
return false
|
192
|
+
end
|
193
|
+
|
194
|
+
matcher_object = IpAddressMatcher.new(ip)
|
195
|
+
matcher_object.matches
|
196
|
+
end
|
197
|
+
|
96
198
|
def escape_path(ip)
|
97
199
|
ip ? "/#{CGI.escape(ip)}" : '/'
|
98
200
|
end
|
201
|
+
|
202
|
+
def cache_key(ip)
|
203
|
+
"1:#{ip}"
|
204
|
+
end
|
99
205
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: IPinfo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stanislav K, James Timmins
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-09-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
@@ -62,10 +62,11 @@ extensions: []
|
|
62
62
|
extra_rdoc_files: []
|
63
63
|
files:
|
64
64
|
- ".editorconfig"
|
65
|
+
- ".github/workflows/cd_rubygems.yaml"
|
66
|
+
- ".github/workflows/unittest.yaml"
|
65
67
|
- ".gitignore"
|
66
68
|
- ".rubocop.yml"
|
67
69
|
- ".ruby-version"
|
68
|
-
- ".travis.yml"
|
69
70
|
- Gemfile
|
70
71
|
- LICENSE
|
71
72
|
- README.md
|
@@ -77,8 +78,13 @@ files:
|
|
77
78
|
- lib/ipinfo/adapter.rb
|
78
79
|
- lib/ipinfo/cache/cache_interface.rb
|
79
80
|
- lib/ipinfo/cache/default_cache.rb
|
81
|
+
- lib/ipinfo/continent.json
|
80
82
|
- lib/ipinfo/countries.json
|
83
|
+
- lib/ipinfo/currency.json
|
81
84
|
- lib/ipinfo/errors.rb
|
85
|
+
- lib/ipinfo/eu.json
|
86
|
+
- lib/ipinfo/flags.json
|
87
|
+
- lib/ipinfo/ipAddressMatcher.rb
|
82
88
|
- lib/ipinfo/mod.rb
|
83
89
|
- lib/ipinfo/response.rb
|
84
90
|
- lib/ipinfo/version.rb
|