IPinfo 1.0.1 → 1.1.0
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 +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
|