Skip to content

Commit

Permalink
Restructured code.
Browse files Browse the repository at this point in the history
Added _v6 functions.
Updated README file.
  • Loading branch information
SaadHassan-dev committed Jan 2, 2024
1 parent 51a1487 commit 158a4d7
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 115 deletions.
21 changes: 4 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,11 @@ handler = IPinfo::create(access_token)
ip_address = '216.239.36.21'

details = handler.details(ip_address)
details_v6 = handler.details_v6() # to get details from ipinfo's IPv6 host
city = details.city # Emeryville
loc = details.loc # 37.8342,-122.2900
```

#### To make an IPv6 request

```ruby
require 'ipinfo'

access_token = '123456789abc'
handler = IPinfo::create(access_token)
handler.initialize_v6
ip_address = '216.239.36.21'

details = handler.details(ip_address)
city = details.city # Emeryville
loc = details.loc # 37.8342,-122.2900
``````

##### Note about Rails 6+

If using this package in Rails 6+, the Zeitwerk auto-loader may not properly
Expand All @@ -73,7 +59,7 @@ require 'ipinfo' unless defined?(IPinfo)

#### Usage

The `IPinfo.details()` method accepts an IP address as an optional, positional
The `IPinfo.details()` and `IPinfo.details_v6()` methods accept an IP address as an optional, positional
argument. If no IP address is specified, the API will return data for the IP
address from which it receives the request.

Expand All @@ -84,6 +70,7 @@ access_token = '123456789abc'
handler = IPinfo::create(access_token)

details = handler.details()
details_v6 = handler.details_v6() # to get details from ipinfo's IPv6 host
city = details.city # "Emeryville"
loc = details.loc # 37.8342,-122.2900
```
Expand All @@ -101,7 +88,7 @@ handler = IPinfo::create(access_token)

#### Details Data

`handler.details()` will return a `Response` object that contains all fields
`handler.details()` and `handler.details_v6` will return a `Response` object that contains all fields
listed in the [IPinfo developerdocs](https://ipinfo.io/developers/responses#full-response)
with a few minor additions. Properties can be accessed directly.

Expand Down
133 changes: 83 additions & 50 deletions lib/ipinfo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,85 @@ def initialize_v6(access_token = nil, settings = {})
end

def details(ip_address = nil)
details_base(ip_address, host_type: :v4)
end

def details_v6(ip_address = nil)
details_base(ip_address, host_type: :v6)
end

def get_map_url(ips)
get_map_url_base(ips, host_type: :v4)
end

def get_map_url_v6(ips)
get_map_url_base(ips, host_type: :v6)
end

def batch_requests(url_array, api_token)
batch_requests_base(url_array, api_token, host_type: :v4)
end

def batch_requests_v6(url_array, api_token)
batch_requests_base(url_array, api_token, host_type: :v6)
end

private

def request_details(ip_address = nil)
if isBogon(ip_address)
details[:ip] = ip_address
details[:bogon] = true
details[:ip_address] = IPAddr.new(ip_address)

return details
end

res = @cache.get(cache_key(ip_address))
return res unless res.nil?

response = @httpc.get(escape_path(ip_address))

if response.status.eql?(429)
raise RateLimitError,
RATE_LIMIT_MESSAGE
end

details = JSON.parse(response.body, symbolize_names: true)
@cache.set(cache_key(ip_address), details)
details
end

def prepare_http_client(httpc = nil)
@httpc = httpc ? Adapter.new(access_token, httpc, host_type) :
Adapter.new(access_token, :net_http, host_type)
end

def init_adapter(settings = {}, host_type: :v4)
puts "old val: #{@host_type}, new val: #{host_type}"
if @host_type.nil? || @host_type != host_type
puts "value changing"
@host_type = host_type
@httpc = prepare_http_client(settings.fetch('http_client', nil))
end
end

def initialize_base(access_token = nil, settings = {}, host_type: :v4)
@access_token = access_token
init_adapter(settings, host_type: host_type)

maxsize = settings.fetch('maxsize', DEFAULT_CACHE_MAXSIZE)
ttl = settings.fetch('ttl', DEFAULT_CACHE_TTL)
@cache = settings.fetch('cache', DefaultCache.new(ttl, maxsize))
@countries = settings.fetch('countries', DEFAULT_COUNTRY_LIST)
@eu_countries = settings.fetch('eu_countries', DEFAULT_EU_COUNTRIES_LIST)
@countries_flags = settings.fetch('countries_flags', DEFAULT_COUNTRIES_FLAG_LIST)
@countries_currencies = settings.fetch('countries_currencies', DEFAULT_COUNTRIES_CURRENCIES_LIST)
@continents = settings.fetch('continents', DEFAULT_CONTINENT_LIST)
end

def details_base(ip_address, settings = {}, host_type: :v4)
init_adapter(settings, host_type: host_type)
details = request_details(ip_address)
if details.key? :country
details[:country_name] =
Expand Down Expand Up @@ -70,7 +149,8 @@ def details(ip_address = nil)
Response.new(details)
end

def get_map_url(ips)
def get_map_url_base(ips, settings = {}, host_type: :v4)
init_adapter(settings, host_type: host_type)
if !ips.kind_of?(Array)
return JSON.generate({:error => 'Invalid input. Array required!'})
end
Expand All @@ -85,7 +165,8 @@ def get_map_url(ips)
obj['reportUrl']
end

def batch_requests(url_array, api_token)
def batch_requests_base(url_array, api_token, settings = {}, host_type: :v4)
init_adapter(settings, host_type: host_type)
result = Hash.new
lookup_ips = []

Expand Down Expand Up @@ -125,54 +206,6 @@ def batch_requests(url_array, api_token)
result
end

protected

def request_details(ip_address = nil)
if isBogon(ip_address)
details[:ip] = ip_address
details[:bogon] = true
details[:ip_address] = IPAddr.new(ip_address)

return details
end

res = @cache.get(cache_key(ip_address))
return res unless res.nil?

response = @httpc.get(escape_path(ip_address))

if response.status.eql?(429)
raise RateLimitError,
RATE_LIMIT_MESSAGE
end

details = JSON.parse(response.body, symbolize_names: true)
@cache.set(cache_key(ip_address), details)
details
end

def prepare_http_client(httpc = nil)
@httpc = httpc ? Adapter.new(access_token, httpc, host_type) :
Adapter.new(access_token, :net_http, host_type)
end

private

def initialize_base(access_token = nil, settings = {}, host_type: :v4)
@access_token = access_token
@host_type = host_type
@httpc = prepare_http_client(settings.fetch('http_client', nil))

maxsize = settings.fetch('maxsize', DEFAULT_CACHE_MAXSIZE)
ttl = settings.fetch('ttl', DEFAULT_CACHE_TTL)
@cache = settings.fetch('cache', DefaultCache.new(ttl, maxsize))
@countries = settings.fetch('countries', DEFAULT_COUNTRY_LIST)
@eu_countries = settings.fetch('eu_countries', DEFAULT_EU_COUNTRIES_LIST)
@countries_flags = settings.fetch('countries_flags', DEFAULT_COUNTRIES_FLAG_LIST)
@countries_currencies = settings.fetch('countries_currencies', DEFAULT_COUNTRIES_CURRENCIES_LIST)
@continents = settings.fetch('continents', DEFAULT_CONTINENT_LIST)
end

def isBogon(ip)
if ip.nil?
return false
Expand Down
2 changes: 1 addition & 1 deletion lib/ipinfo/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def connection(adapter)

def default_headers
headers = {
'User-Agent' => 'IPinfoClient/Ruby/#{IPinfo::VERSION}',
'User-Agent' => "IPinfoClient/Ruby/#{IPinfo::VERSION}",
'Accept' => 'application/json'
}
headers['Authorization'] = "Bearer #{CGI.escape(token)}" if token
Expand Down
92 changes: 45 additions & 47 deletions test/ipinfo_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,6 @@ class IPinfoTest < Minitest::Test
TEST_IPV4 = '8.8.8.8'
TEST_IPV6 = '2601:9:7680:363:75df:f491:6f85:352f'

def test_that_it_has_a_version_number
refute_nil ::IPinfo::VERSION
end

def test_set_adapter_v4
ipinfo = IPinfo.create(
ENV['IPINFO_TOKEN'],
{ http_client: :excon }
)

assert(ipinfo.httpc = :excon)
end

def test_set_adapter_v6
ipinfo = IPinfo.create(
ENV['IPINFO_TOKEN'],
{ http_client: :excon }
)
ipinfo.initialize_v6

assert(ipinfo.httpc = :excon)
end

def assert_ip6(resp)
assert_equal(resp.ip, TEST_IPV6)
assert_equal(resp.ip_address, IPAddr.new(TEST_IPV6))
Expand Down Expand Up @@ -94,28 +71,6 @@ def assert_ip6(resp)
)
end

def test_lookup_ip6
ipinfo = IPinfo.create(ENV['IPINFO_TOKEN'])

# multiple checks for cache
(0...5).each do |_|
resp = ipinfo.details(TEST_IPV6)
assert_ip6(resp)
end
end

# # Requires IPv6 support
# def test_lookup_ip6_on_host_v6
# ipinfo = IPinfo.create(ENV['IPINFO_TOKEN'])
# ipinfo.initialize_v6

# # multiple checks for cache
# (0...5).each do |_|
# resp = ipinfo.details(TEST_IPV6)
# assert_ip6(resp)
# end
# end

def assert_ip4(resp)
assert_equal(resp.ip, TEST_IPV4)
assert_equal(resp.ip_address, IPAddr.new(TEST_IPV4))
Expand Down Expand Up @@ -184,6 +139,50 @@ def assert_ip4(resp)
refute_nil(resp.domains[:domains])
end

def test_that_it_has_a_version_number
refute_nil ::IPinfo::VERSION
end

def test_set_adapter_v4
ipinfo = IPinfo.create(
ENV['IPINFO_TOKEN'],
{ http_client: :excon }
)

assert(ipinfo.httpc = :excon)
end

def test_set_adapter_v6
ipinfo = IPinfo.create(
ENV['IPINFO_TOKEN'],
{ http_client: :excon }
)
ipinfo.initialize_v6

assert(ipinfo.httpc = :excon)
end

def test_lookup_ip6
ipinfo = IPinfo.create(ENV['IPINFO_TOKEN'])

# multiple checks for cache
(0...5).each do |_|
resp = ipinfo.details(TEST_IPV6)
assert_ip6(resp)
end
end

# # Requires IPv6 support
# def test_lookup_ip6_on_host_v6
# ipinfo = IPinfo.create(ENV['IPINFO_TOKEN'])

# # multiple checks for cache
# (0...5).each do |_|
# resp = ipinfo.details_v6(TEST_IPV6)
# assert_ip6(resp)
# end
# end

def test_lookup_ip4
ipinfo = IPinfo.create(ENV['IPINFO_TOKEN'])

Expand All @@ -197,11 +196,10 @@ def test_lookup_ip4
# # Requires IPv6 support
# def test_lookup_ip4_on_host_v6
# ipinfo = IPinfo.create(ENV['IPINFO_TOKEN'])
# ipinfo.initialize_v6

# # multiple checks for cache
# (0...5).each do |_|
# resp = ipinfo.details(TEST_IPV4)
# resp = ipinfo.details_v6(TEST_IPV4)
# assert_ip4(resp)
# end
# end
Expand Down

0 comments on commit 158a4d7

Please sign in to comment.