IPinfo 0.1.2 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +1 -1
- data/.gitignore +1 -0
- data/.rubocop.yml +42 -0
- data/.ruby-version +1 -0
- data/.travis.yml +3 -5
- data/Gemfile +7 -28
- data/README.md +56 -24
- data/Rakefile +8 -6
- data/bin/console +4 -10
- data/bin/setup +1 -2
- data/ipinfo.gemspec +30 -28
- data/lib/ipinfo.rb +64 -54
- data/lib/ipinfo/adapter.rb +16 -18
- data/lib/ipinfo/cache/cache_interface.rb +10 -9
- data/lib/ipinfo/cache/default_cache.rb +8 -9
- data/lib/ipinfo/errors.rb +3 -3
- data/lib/ipinfo/mod.rb +4 -0
- data/lib/ipinfo/response.rb +8 -9
- data/lib/ipinfo/version.rb +3 -1
- metadata +20 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4c7edbf9ea00bfe0f34278ce345a0be0af732787dac8894043640d1c72f3dda
|
4
|
+
data.tar.gz: a012b52f9d182417c48f96997e80464b37633b46b0e54e2251b36c8d36710174
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 706d928db455afb05db71bbf170b33616fa141c3f5765ac1045563e24b90e124fd8fbb9743bcdd7ac9b0ba1a7d0ccf30a4615cb2edf0fefe55e5c903f9be8eac
|
7
|
+
data.tar.gz: f49d989cf52c9b1524ce2d4a177cc906ab5c680745fb23f540fa6395c31f6a4bac304f904849f0b8298a89600e93321a2f6e0165988506f8ad0ede81c7873ad1
|
data/.editorconfig
CHANGED
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.5
|
3
|
+
NewCops: enable
|
4
|
+
|
5
|
+
Layout/IndentationWidth:
|
6
|
+
Width: 4
|
7
|
+
|
8
|
+
Layout/LineLength:
|
9
|
+
Enabled: true
|
10
|
+
Max: 80
|
11
|
+
|
12
|
+
Lint/MissingSuper:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
Metrics/MethodLength:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
Metrics/AbcSize:
|
19
|
+
Enabled: false
|
20
|
+
|
21
|
+
Metrics/ClassLength:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Lint/DuplicateMethods:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
Style/Documentation:
|
28
|
+
Enabled: false
|
29
|
+
|
30
|
+
Style/ClassAndModuleChildren:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Style/MethodCallWithArgsParentheses:
|
34
|
+
EnforcedStyle: require_parentheses
|
35
|
+
IgnoreMacros: false
|
36
|
+
IgnoredPatterns: []
|
37
|
+
AllowParenthesesInMultilineCall: true
|
38
|
+
AllowParenthesesInChaining: true
|
39
|
+
AllowParenthesesInCamelCaseMethod: true
|
40
|
+
|
41
|
+
Style/MethodCallWithoutArgsParentheses:
|
42
|
+
Enabled: false
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.7.2
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,34 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
source 'https://rubygems.org'
|
2
4
|
|
3
|
-
# Specify your gem's dependencies in ipinfo.gemspec
|
4
5
|
gemspec
|
5
6
|
|
6
|
-
|
7
7
|
group :development do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
gem "rack", ">= 1.5"
|
14
|
-
else
|
15
|
-
gem "rack", ">= 1.5", "< 2.0"
|
16
|
-
end
|
17
|
-
|
18
|
-
gem "bundler"
|
19
|
-
gem "rake"
|
20
|
-
gem "minitest"
|
21
|
-
gem 'minitest-vcr'
|
22
|
-
gem 'minitest-reporters'
|
23
|
-
gem 'webmock'
|
24
|
-
|
25
|
-
platforms :mri do
|
26
|
-
# to avoid problems, bring Byebug in on just versions of Ruby under which
|
27
|
-
# it's known to work well
|
28
|
-
if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new("2.0.0")
|
29
|
-
gem "byebug"
|
30
|
-
gem "pry"
|
31
|
-
gem "pry-byebug"
|
32
|
-
end
|
33
|
-
end
|
8
|
+
gem 'bundler'
|
9
|
+
gem 'minitest'
|
10
|
+
gem 'minitest-reporters'
|
11
|
+
gem 'rake'
|
12
|
+
gem 'rubocop'
|
34
13
|
end
|
data/README.md
CHANGED
@@ -1,24 +1,25 @@
|
|
1
1
|
# [<img src="https://ipinfo.io/static/ipinfo-small.svg" alt="IPinfo" width="24"/>](https://ipinfo.io/) IPinfo Ruby Client Library
|
2
2
|
|
3
3
|
This is the official Ruby client library for the [IPinfo.io](https://ipinfo.io) IP address API, allowing you to lookup your own IP address, or get any of the following details for an IP:
|
4
|
-
- IP geolocation (city, region, country, postal code, latitude and longitude)
|
5
|
-
- ASN
|
6
|
-
-
|
7
|
-
- Carrier details (the name of the mobile carrier and MNC and MCC for that carrier if the IP is used exclusively for mobile traffic)
|
4
|
+
- [IP geolocation data](https://ipinfo.io/ip-geolocation-api) (city, region, country, postal code, latitude and longitude)
|
5
|
+
- [ASN information](https://ipinfo.io/asn-api) (ISP or network operator, associated domain name, and type, such as business, hosting or company)
|
6
|
+
- [Firmographic data](https://ipinfo.io/ip-company-api) (the name and domain of the business that uses the IP address)
|
7
|
+
- [Carrier details](https://ipinfo.io/ip-carrier-api) (the name of the mobile carrier and MNC and MCC for that carrier if the IP is used exclusively for mobile traffic)
|
8
8
|
|
9
|
+
Check all the data we have for your IP address [here](https://ipinfo.io/what-is-my-ip).
|
9
10
|
|
10
11
|
### Getting Started
|
11
12
|
|
12
|
-
You'll need an IPinfo API access token, which you can get by singing up for a free account at [https://ipinfo.io/signup](https://ipinfo.io/signup
|
13
|
+
You'll need an IPinfo API access token, which you can get by singing up for a free account at [https://ipinfo.io/signup](https://ipinfo.io/signup).
|
13
14
|
|
14
|
-
The free plan is limited to
|
15
|
+
The free plan is limited to 50,000 requests per month, and doesn't include some of the data fields such as IP type and company data. To enable all the data fields and additional request volumes see [https://ipinfo.io/pricing](https://ipinfo.io/pricing)
|
15
16
|
|
16
17
|
#### Installation
|
17
18
|
|
18
19
|
Add this line to your application's Gemfile:
|
19
20
|
|
20
21
|
```ruby
|
21
|
-
gem '
|
22
|
+
gem 'IPinfo'
|
22
23
|
```
|
23
24
|
|
24
25
|
And then execute:
|
@@ -27,12 +28,12 @@ And then execute:
|
|
27
28
|
|
28
29
|
Or install it yourself as:
|
29
30
|
|
30
|
-
$ gem install
|
31
|
+
$ gem install IPinfo
|
31
32
|
|
32
33
|
#### Quick Start
|
33
34
|
|
34
35
|
```ruby
|
35
|
-
require '
|
36
|
+
require 'IPinfo'
|
36
37
|
|
37
38
|
access_token = '123456789abc'
|
38
39
|
handler = IPinfo::create(access_token)
|
@@ -45,10 +46,12 @@ loc = details.loc # 37.8342,-122.2900
|
|
45
46
|
|
46
47
|
#### Usage
|
47
48
|
|
48
|
-
The `IPinfo.details()` method accepts an IP address as an optional, positional
|
49
|
+
The `IPinfo.details()` method accepts an IP address as an optional, positional
|
50
|
+
argument. If no IP address is specified, the API will return data for the IP
|
51
|
+
address from which it receives the request.
|
49
52
|
|
50
53
|
```ruby
|
51
|
-
require '
|
54
|
+
require 'IPinfo'
|
52
55
|
|
53
56
|
access_token = '123456789abc'
|
54
57
|
handler = IPinfo::create(access_token)
|
@@ -60,7 +63,9 @@ loc = details.loc # 37.8342,-122.2900
|
|
60
63
|
|
61
64
|
#### Authentication
|
62
65
|
|
63
|
-
The IPinfo library can be authenticated with your IPinfo API token, which is
|
66
|
+
The IPinfo library can be authenticated with your IPinfo API token, which is
|
67
|
+
passed in as a positional argument. It also works without an authentication
|
68
|
+
token, but in a more limited capacity.
|
64
69
|
|
65
70
|
```ruby
|
66
71
|
access_token = '123456789abc'
|
@@ -69,7 +74,9 @@ handler = IPinfo::create(access_token)
|
|
69
74
|
|
70
75
|
#### Details Data
|
71
76
|
|
72
|
-
`handler.details()` will return a `Response` object that contains all fields
|
77
|
+
`handler.details()` will return a `Response` object that contains all fields
|
78
|
+
listed in the [IPinfo developerdocs](https://ipinfo.io/developers/responses#full-response)
|
79
|
+
with a few minor additions. Properties can be accessed directly.
|
73
80
|
|
74
81
|
```ruby
|
75
82
|
hostname = details.hostname # cpe-104-175-221-247.socal.res.rr.com
|
@@ -77,7 +84,9 @@ hostname = details.hostname # cpe-104-175-221-247.socal.res.rr.com
|
|
77
84
|
|
78
85
|
##### Country Name
|
79
86
|
|
80
|
-
`details.country_name` will return the country name, as supplied by the
|
87
|
+
`details.country_name` will return the country name, as supplied by the
|
88
|
+
`countries.json` file. See below for instructions on changing that file for use
|
89
|
+
with non-English languages. `details.country` will still return country code.
|
81
90
|
|
82
91
|
```ruby
|
83
92
|
country = details.country # US
|
@@ -86,7 +95,9 @@ country_name = details.country_name # United States
|
|
86
95
|
|
87
96
|
#### IP Address
|
88
97
|
|
89
|
-
`details.ip_address` will return the an `IPAddr` object from the
|
98
|
+
`details.ip_address` will return the an `IPAddr` object from the
|
99
|
+
[Ruby Standard Library](https://ruby-doc.org/stdlib-2.5.1/libdoc/ipaddr/rdoc/IPAddr.html).
|
100
|
+
`details.ip` will still return a string.
|
90
101
|
|
91
102
|
```ruby
|
92
103
|
ip = details.ip # 104.175.221.247
|
@@ -95,7 +106,9 @@ ip_addr = details.ip_address # <IPAddr: IPv4:104.175.221.247/255.255.255.255>
|
|
95
106
|
|
96
107
|
##### Longitude and Latitude
|
97
108
|
|
98
|
-
`details.latitude` and `details.longitude` will return latitude and longitude,
|
109
|
+
`details.latitude` and `details.longitude` will return latitude and longitude,
|
110
|
+
respectively, as strings. `details.loc` will still return a composite string of
|
111
|
+
both values.
|
99
112
|
|
100
113
|
```ruby
|
101
114
|
loc = details.loc # 34.0293,-118.3570
|
@@ -134,13 +147,22 @@ details.all = {
|
|
134
147
|
|
135
148
|
#### Caching
|
136
149
|
|
137
|
-
In-memory caching of `details` data is provided by default via the
|
150
|
+
In-memory caching of `details` data is provided by default via the
|
151
|
+
[`lru_redux`](https://github.com/SamSaffron/lru_redux) gem. This uses an LRU
|
152
|
+
(least recently used) cache with a TTL (time to live) by default. This means
|
153
|
+
that values will be cached for the specified duration; if the cache's max size
|
154
|
+
is reached, cache values will be invalidated as necessary, starting with the
|
155
|
+
oldest cached value.
|
138
156
|
|
139
157
|
##### Modifying cache options
|
140
158
|
|
141
|
-
Cache behavior can be modified by setting the `cache_options` keyword argument.
|
159
|
+
Cache behavior can be modified by setting the `cache_options` keyword argument.
|
160
|
+
`cache_options` is a dictionary in which the keys are keyword arguments
|
161
|
+
specified in the `cachetools` library. The nesting of keyword arguments is to
|
162
|
+
prevent name collisions between this library and its dependencies.
|
142
163
|
|
143
|
-
* Default maximum cache size: 4096 (multiples of 2 are recommended to increase
|
164
|
+
* Default maximum cache size: 4096 (multiples of 2 are recommended to increase
|
165
|
+
efficiency)
|
144
166
|
* Default TTL: 24 hours (in seconds)
|
145
167
|
|
146
168
|
```ruby
|
@@ -150,15 +172,22 @@ handler = IPinfo::create(token, {:ttl => 30, :maxsize => 30})
|
|
150
172
|
|
151
173
|
##### Using a different cache
|
152
174
|
|
153
|
-
It's possible to use a custom cache by creating a child class of the
|
175
|
+
It's possible to use a custom cache by creating a child class of the
|
176
|
+
[CacheInterface](https://github.com/jhtimmins/ruby/blob/master/lib/ipinfo/cache/cache_interface.rb)
|
177
|
+
class and passing this into the handler object with the `cache` keyword
|
178
|
+
argument. FYI this is known as
|
179
|
+
[the Strategy Pattern](https://sourcemaking.com/design_patterns/strategy).
|
154
180
|
|
155
181
|
```ruby
|
156
182
|
handler = IPinfo.handler(token, {:cache => my_fancy_custom_class})
|
157
183
|
```
|
158
184
|
|
159
|
-
|
160
185
|
### Using a different HTTP library
|
161
|
-
|
186
|
+
|
187
|
+
Ruby is notorious for having lots of HTTP libraries. While `Net::HTTP` is a
|
188
|
+
reasonable default, you can set any other that
|
189
|
+
[Faradaysupports](https://github.com/lostisland/faraday/tree/29feeb92e3413d38ffc1fd3a3479bb48a0915730#faraday)
|
190
|
+
if you prefer.
|
162
191
|
|
163
192
|
```ruby
|
164
193
|
access_token = '123456789abc'
|
@@ -169,7 +198,10 @@ Don't forget to bundle the custom HTTP library as well.
|
|
169
198
|
|
170
199
|
#### Internationalization
|
171
200
|
|
172
|
-
When looking up an IP address, the response object includes a
|
201
|
+
When looking up an IP address, the response object includes a
|
202
|
+
`details.country_name` attribute which includes the country name based on
|
203
|
+
American English. It is possible to return the country name in other languages
|
204
|
+
by setting the `countries` setting when creating the `IPinfo` object.
|
173
205
|
|
174
206
|
The file must be a `.json` file with the following structure:
|
175
207
|
|
@@ -189,6 +221,6 @@ There are official IPinfo client libraries available for many languages includin
|
|
189
221
|
|
190
222
|
### About IPinfo
|
191
223
|
|
192
|
-
Founded in 2013, IPinfo prides itself on being the most reliable, accurate, and in-depth source of IP address data available anywhere. We process terabytes of data to produce our custom IP geolocation, company, carrier and IP type data sets. Our API handles over
|
224
|
+
Founded in 2013, IPinfo prides itself on being the most reliable, accurate, and in-depth source of IP address data available anywhere. We process terabytes of data to produce our custom IP geolocation, company, carrier, privacy detection, reverse IP, and IP type data sets. Our API handles over 20 billion requests a month for 100,000 businesses and developers.
|
193
225
|
|
194
226
|
[![image](https://avatars3.githubusercontent.com/u/15721521?s=128&u=7bb7dde5c4991335fb234e68a30971944abc6bf3&v=4)](https://ipinfo.io/)
|
data/Rakefile
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/testtask'
|
3
5
|
|
4
6
|
Rake::TestTask.new(:test) do |t|
|
5
|
-
|
6
|
-
|
7
|
-
|
7
|
+
t.libs << 'test'
|
8
|
+
t.libs << 'lib'
|
9
|
+
t.test_files = FileList['test/**/*_test.rb']
|
8
10
|
end
|
9
11
|
|
10
|
-
task :
|
12
|
+
task default: :test
|
data/bin/console
CHANGED
@@ -1,14 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'ipinfo'
|
5
6
|
|
6
|
-
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
7
|
+
require 'irb'
|
14
8
|
IRB.start
|
data/bin/setup
CHANGED
data/ipinfo.gemspec
CHANGED
@@ -1,37 +1,39 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
4
6
|
require 'ipinfo/version'
|
5
7
|
|
6
8
|
Gem::Specification.new do |spec|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
spec.name = 'IPinfo'
|
10
|
+
spec.version = IPinfo::VERSION
|
11
|
+
spec.required_ruby_version = '>= 2.5.0'
|
12
|
+
spec.authors = ['Stanislav K, James Timmins', 'Uman Shahzad']
|
13
|
+
spec.email = ['jameshtimmins@gmail.com', 'uman@mslm.io']
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
spec.license = "Apache-2.0"
|
15
|
+
spec.summary = ' This is a ruby wrapper for http://ipinfo.io. '
|
16
|
+
spec.description = ' This is a ruby wrapper for http://ipinfo.io. '
|
17
|
+
spec.homepage = 'https://ipinfo.io'
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
19
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the
|
20
|
+
# 'allowed_push_host' to allow pushing to a single host or delete this
|
21
|
+
# section to allow pushing to any host.
|
22
|
+
if spec.respond_to?(:metadata)
|
23
|
+
# spec.metadata['allowed_push_host'] = "http://mygemserver.com'"
|
24
|
+
else
|
25
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
26
|
+
'public gem pushes.'
|
27
|
+
end
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
spec.add_runtime_dependency 'faraday', '~> 1.0'
|
30
|
+
spec.add_runtime_dependency 'json', '~> 2.1'
|
31
|
+
spec.add_runtime_dependency 'lru_redux', '~> 1.1'
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
34
|
+
f.match(%r{^(test|spec|features)/})
|
35
|
+
end
|
36
|
+
spec.bindir = 'exe'
|
37
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
38
|
+
spec.require_paths = ['lib']
|
37
39
|
end
|
data/lib/ipinfo.rb
CHANGED
@@ -10,80 +10,90 @@ require 'ipinfo/version'
|
|
10
10
|
require 'json'
|
11
11
|
|
12
12
|
module IPinfo
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
DEFAULT_CACHE_MAXSIZE = 4096
|
14
|
+
DEFAULT_CACHE_TTL = 60 * 60 * 24
|
15
|
+
DEFAULT_COUNTRY_FILE = File.join(File.dirname(__FILE__),
|
16
|
+
'ipinfo/countries.json')
|
17
|
+
RATE_LIMIT_MESSAGE = 'To increase your limits, please review our ' \
|
18
|
+
'paid plans at https://ipinfo.io/pricing'
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def create(access_token = nil, settings = {})
|
22
|
+
IPinfo.new(access_token, settings)
|
23
|
+
end
|
21
24
|
end
|
22
|
-
|
25
|
+
end
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
attr_accessor :countries
|
27
|
-
attr_accessor :http_client
|
27
|
+
class IPinfo::IPinfo
|
28
|
+
include IPinfo
|
29
|
+
attr_accessor :access_token, :countries, :httpc
|
28
30
|
|
29
|
-
def initialize(access_token=nil, settings={})
|
30
|
-
|
31
|
-
|
31
|
+
def initialize(access_token = nil, settings = {})
|
32
|
+
@access_token = access_token
|
33
|
+
@httpc = prepare_http_client(settings.fetch('http_client', nil))
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
maxsize = settings.fetch('maxsize', DEFAULT_CACHE_MAXSIZE)
|
36
|
+
ttl = settings.fetch('ttl', DEFAULT_CACHE_TTL)
|
37
|
+
@cache = settings.fetch('cache', DefaultCache.new(ttl, maxsize))
|
38
|
+
@countries = prepare_countries(settings.fetch('countries',
|
39
|
+
DEFAULT_COUNTRY_FILE))
|
37
40
|
end
|
38
41
|
|
39
|
-
def details(ip_address=nil)
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
details
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
42
|
+
def details(ip_address = nil)
|
43
|
+
details = request_details(ip_address)
|
44
|
+
if details.key? :country
|
45
|
+
details[:country_name] =
|
46
|
+
@countries.fetch(details.fetch(:country), nil)
|
47
|
+
end
|
48
|
+
|
49
|
+
if details.key? :ip
|
50
|
+
details[:ip_address] =
|
51
|
+
IPAddr.new(details.fetch(:ip))
|
52
|
+
end
|
53
|
+
|
54
|
+
if details.key? :loc
|
55
|
+
loc = details.fetch(:loc).split(',')
|
56
|
+
details[:latitude] = loc[0]
|
57
|
+
details[:longitude] = loc[1]
|
58
|
+
end
|
59
|
+
|
60
|
+
Response.new(details)
|
56
61
|
end
|
57
62
|
|
58
63
|
protected
|
59
|
-
def request_details(ip_address=nil)
|
60
|
-
if !@cache.contains?(ip_address)
|
61
|
-
response = @http_client.get(escape_path(ip_address))
|
62
64
|
|
63
|
-
|
65
|
+
def request_details(ip_address = nil)
|
66
|
+
res = @cache.get(ip_address)
|
67
|
+
return res unless res.nil?
|
68
|
+
|
69
|
+
response = @httpc.get(escape_path(ip_address))
|
70
|
+
|
71
|
+
if response.status.eql?(429)
|
72
|
+
raise RateLimitError,
|
73
|
+
RATE_LIMIT_MESSAGE
|
74
|
+
end
|
64
75
|
|
65
76
|
details = JSON.parse(response.body, symbolize_names: true)
|
66
77
|
@cache.set(ip_address, details)
|
67
|
-
|
68
|
-
@cache.get(ip_address)
|
78
|
+
details
|
69
79
|
end
|
70
80
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
81
|
+
def prepare_http_client(httpc = nil)
|
82
|
+
@httpc = if httpc
|
83
|
+
Adapter.new(access_token, httpc)
|
84
|
+
else
|
85
|
+
Adapter.new(access_token)
|
86
|
+
end
|
77
87
|
end
|
78
88
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
89
|
+
def prepare_countries(filename)
|
90
|
+
file = File.read(filename)
|
91
|
+
JSON.parse(file)
|
82
92
|
end
|
83
93
|
|
84
94
|
private
|
95
|
+
|
85
96
|
def escape_path(ip)
|
86
|
-
|
97
|
+
ip ? "/#{CGI.escape(ip)}" : '/'
|
87
98
|
end
|
88
|
-
end
|
89
99
|
end
|
data/lib/ipinfo/adapter.rb
CHANGED
@@ -1,25 +1,26 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'faraday'
|
3
4
|
require 'cgi'
|
5
|
+
require 'ipinfo/mod'
|
4
6
|
|
5
|
-
|
6
|
-
class Adapter
|
7
|
+
class IPinfo::Adapter
|
7
8
|
HOST = 'ipinfo.io'
|
8
9
|
|
9
10
|
attr_reader :conn
|
10
11
|
|
11
12
|
def initialize(token = nil, adapter = :net_http)
|
12
|
-
|
13
|
-
|
13
|
+
@token = token
|
14
|
+
@conn = connection(adapter)
|
14
15
|
end
|
15
16
|
|
16
17
|
def get(uri)
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
@conn.get(uri) do |req|
|
19
|
+
default_headers.each_pair do |key, value|
|
20
|
+
req.headers[key] = value
|
21
|
+
end
|
22
|
+
req.params['token'] = CGI.escape(token) if token
|
20
23
|
end
|
21
|
-
req.params['token'] = CGI::escape(token) if token
|
22
|
-
end
|
23
24
|
end
|
24
25
|
|
25
26
|
private
|
@@ -27,20 +28,17 @@ module IPinfo
|
|
27
28
|
attr_reader :token
|
28
29
|
|
29
30
|
def connection(adapter)
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
Faraday.new(url: "https://#{HOST}") do |conn|
|
32
|
+
conn.adapter(adapter)
|
33
|
+
end
|
33
34
|
end
|
34
35
|
|
35
36
|
def default_headers
|
36
37
|
headers = {
|
37
|
-
|
38
|
-
|
38
|
+
'User-Agent' => 'IPinfoClient/Ruby/1.0',
|
39
|
+
'Accept' => 'application/json'
|
39
40
|
}
|
40
|
-
if token
|
41
|
-
headers['Authorization'] = "Bearer #{CGI::escape(token)}"
|
42
|
-
end
|
41
|
+
headers['Authorization'] = "Bearer #{CGI.escape(token)}" if token
|
43
42
|
headers
|
44
43
|
end
|
45
|
-
end
|
46
44
|
end
|
@@ -1,16 +1,17 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class IPinfo::CacheInterface
|
3
4
|
class InterfaceNotImplemented < StandardError; end
|
4
|
-
|
5
|
-
|
5
|
+
|
6
|
+
def get(_key)
|
7
|
+
raise InterfaceNotImplemented
|
6
8
|
end
|
7
9
|
|
8
|
-
def set(
|
9
|
-
|
10
|
+
def set(_key, _value)
|
11
|
+
raise InterfaceNotImplemented
|
10
12
|
end
|
11
13
|
|
12
|
-
def contains?(
|
13
|
-
|
14
|
+
def contains?(_key)
|
15
|
+
raise InterfaceNotImplemented
|
14
16
|
end
|
15
|
-
end
|
16
17
|
end
|
@@ -1,23 +1,22 @@
|
|
1
|
-
|
2
|
-
require 'lrucache'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
require 'ipinfo/cache/cache_interface'
|
4
|
+
require 'lru_redux'
|
6
5
|
|
6
|
+
class IPinfo::DefaultCache < IPinfo::CacheInterface
|
7
7
|
def initialize(ttl, max_size)
|
8
|
-
|
8
|
+
@cache = LruRedux::TTL::Cache.new(max_size, ttl)
|
9
9
|
end
|
10
10
|
|
11
11
|
def get(key)
|
12
|
-
|
12
|
+
@cache[key]
|
13
13
|
end
|
14
14
|
|
15
15
|
def set(key, value)
|
16
|
-
|
16
|
+
@cache[key] = value
|
17
17
|
end
|
18
18
|
|
19
19
|
def contains?(key)
|
20
|
-
|
20
|
+
!@cache[key].nil?
|
21
21
|
end
|
22
|
-
end
|
23
22
|
end
|
data/lib/ipinfo/errors.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class IPinfo::RateLimitError < StandardError; end
|
data/lib/ipinfo/mod.rb
ADDED
data/lib/ipinfo/response.rb
CHANGED
@@ -3,18 +3,17 @@
|
|
3
3
|
require 'ipaddr'
|
4
4
|
require 'json'
|
5
5
|
|
6
|
-
|
7
|
-
class Response
|
8
|
-
|
6
|
+
class IPinfo::Response
|
9
7
|
attr_reader :all
|
10
8
|
|
11
9
|
def initialize(response)
|
12
|
-
|
10
|
+
@all = response
|
11
|
+
|
12
|
+
@all.each do |name, value|
|
13
|
+
instance_variable_set("@#{name}", value)
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
15
|
+
c = class << self; self end
|
16
|
+
c.send(:attr_accessor, name)
|
17
|
+
end
|
18
18
|
end
|
19
|
-
end
|
20
19
|
end
|
data/lib/ipinfo/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: IPinfo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stanislav K, James Timmins
|
8
|
+
- Uman Shahzad
|
8
9
|
autorequire:
|
9
10
|
bindir: exe
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2021-01-05 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: faraday
|
@@ -16,54 +17,54 @@ dependencies:
|
|
16
17
|
requirements:
|
17
18
|
- - "~>"
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
+
version: '1.0'
|
20
21
|
type: :runtime
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
25
|
- - "~>"
|
25
26
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
27
|
+
version: '1.0'
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
29
|
+
name: json
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
32
|
- - "~>"
|
32
33
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
34
|
+
version: '2.1'
|
34
35
|
type: :runtime
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
38
39
|
- - "~>"
|
39
40
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
41
|
+
version: '2.1'
|
41
42
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
43
|
+
name: lru_redux
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
45
46
|
- - "~>"
|
46
47
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
+
version: '1.1'
|
48
49
|
type: :runtime
|
49
50
|
prerelease: false
|
50
51
|
version_requirements: !ruby/object:Gem::Requirement
|
51
52
|
requirements:
|
52
53
|
- - "~>"
|
53
54
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
-
description: "
|
56
|
-
the most reliable, accurate, and in-depth source of IP address data available anywhere.
|
57
|
-
We process terabytes of data to produce our custom IP geolocation, company, carrier
|
58
|
-
and IP type data sets. You can visit our developer docs at https://ipinfo.io/developers. "
|
55
|
+
version: '1.1'
|
56
|
+
description: " This is a ruby wrapper for http://ipinfo.io. "
|
59
57
|
email:
|
60
58
|
- jameshtimmins@gmail.com
|
59
|
+
- uman@mslm.io
|
61
60
|
executables: []
|
62
61
|
extensions: []
|
63
62
|
extra_rdoc_files: []
|
64
63
|
files:
|
65
64
|
- ".editorconfig"
|
66
65
|
- ".gitignore"
|
66
|
+
- ".rubocop.yml"
|
67
|
+
- ".ruby-version"
|
67
68
|
- ".travis.yml"
|
68
69
|
- Gemfile
|
69
70
|
- LICENSE
|
@@ -78,11 +79,11 @@ files:
|
|
78
79
|
- lib/ipinfo/cache/default_cache.rb
|
79
80
|
- lib/ipinfo/countries.json
|
80
81
|
- lib/ipinfo/errors.rb
|
82
|
+
- lib/ipinfo/mod.rb
|
81
83
|
- lib/ipinfo/response.rb
|
82
84
|
- lib/ipinfo/version.rb
|
83
85
|
homepage: https://ipinfo.io
|
84
|
-
licenses:
|
85
|
-
- Apache-2.0
|
86
|
+
licenses: []
|
86
87
|
metadata: {}
|
87
88
|
post_install_message:
|
88
89
|
rdoc_options: []
|
@@ -92,19 +93,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
93
|
requirements:
|
93
94
|
- - ">="
|
94
95
|
- !ruby/object:Gem::Version
|
95
|
-
version: 2.
|
96
|
+
version: 2.5.0
|
96
97
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
98
|
requirements:
|
98
99
|
- - ">="
|
99
100
|
- !ruby/object:Gem::Version
|
100
101
|
version: '0'
|
101
102
|
requirements: []
|
102
|
-
|
103
|
-
rubygems_version: 2.7.6
|
103
|
+
rubygems_version: 3.1.4
|
104
104
|
signing_key:
|
105
105
|
specification_version: 4
|
106
|
-
summary:
|
107
|
-
most reliable, accurate, and in-depth source of IP address data available anywhere.
|
108
|
-
We process terabytes of data to produce our custom IP geolocation, company, carrier
|
109
|
-
and IP type data sets. You can visit our developer docs at https://ipinfo.io/developers.
|
106
|
+
summary: This is a ruby wrapper for http://ipinfo.io.
|
110
107
|
test_files: []
|