https://github.com/dkam/datacenter_detector
Detect Datacenter by IP
https://github.com/dkam/datacenter_detector
Last synced: about 1 year ago
JSON representation
Detect Datacenter by IP
- Host: GitHub
- URL: https://github.com/dkam/datacenter_detector
- Owner: dkam
- Created: 2022-07-31T23:17:30.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2023-05-16T01:14:36.000Z (about 3 years ago)
- Last Synced: 2025-03-30T04:31:43.534Z (about 1 year ago)
- Language: Ruby
- Size: 49.8 KB
- Stars: 4
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# DatacenterDetector
The DatacenterDetector gem is no more. Below is a simple class to perform the same actions, but using a Redis cache via Kredis.
The following Ruby class is a slim wrapper around the [IP Address API](https://github.com/NikolaiT/IP-Address-API).
The number of hits and misses is also tracked.
# A Working Cache
```ruby
require 'kredis'
require 'open-uri'
class IpAddressApi
# Outside of Rails, configure Kredis like:
# Kredis::Connections.connections[:shared] = Redis.new(url: "redis://localhost:6379/0")
attr_accessor :prefix, :agent, :cache_only, :ttl
def initialize(prefix: IpAddressApi.prefix, agent: IpAddressApi.agent, cache_only: false, ttl: 60 * 60 * 24)
@cache_only = cache_only
@prefix = prefix
@agent = agent
@ttl = ttl
end
def key_name(ip) = "#{@prefix}#{ip}"
def hit_counter = @hit_counter ||= Kredis.counter("#{prefix}hits")
def miss_counter = @miss_counter ||= Kredis.counter("#{prefix}miss")
def stats
hit = hit_counter.value
miss = miss_counter.value
{hit: hit, miss:, total: hit + miss}
end
def hitrate
hit = hit_counter.value
miss = miss_counter.value
hit / (hit + miss).to_f
end
def reset_stats
hit_counter.reset
miss_counter.reset
end
def lookup(ip=nil)
return {} if ip.nil?
ip_data = Kredis.json(key_name(ip), expires_in: ttl)
if ip_data.value.blank? && cache_only == true
miss!
elsif ip_data.value.blank? && cache_only == false
miss!
ip_data.value = JSON.parse( URI.open("https://ipapi.is/json/?q=#{ip}", "User-Agent" => agent).read)
ip_data.value ||= {}
else
hit!
end
return ip_data.value
rescue OpenURI::HTTPError => e
puts("IP Address API error looking up IP: #{ip} : #{e.inspect}")
return {}
end
def self.prefix = 'IpAddressApi_'
def self.agent = "Ruby/#{RUBY_VERSION}"
def self.stats = IpAddressApi.new.stats
def self.reset_stats = IpAddressApi.new.reset_stats
def self.hitrate = IpAddressApi.new.hit_rate
def self.lookup(ip=nil, cache_only: false, agent: nil) = IpAddressApi.new(cache_only:, agent:).lookup(ip)
private
def hit! = hit_counter.increment
def miss! = miss_counter.increment
end
```
## Usage
You can use an instance or class methods.
```ruby
> result = IpAddressApi.lookup('1.1.1.1')
> result.dig('is_datacenter')
=> false
> result.dig('company', 'name')
=> "APNIC Research and Development"
> result.dig('asn', 'org')
=> "Cloudflare, Inc."
> client = IpAddressApi.new
> client.lookup('52.93.127.126')
> result.is_datacenter
=> true
> result.name
=> "Amazon Technologies Inc."
The cache records its hitrate:
```ruby
> client.hitrate
=> 0.6829268292682927
```
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).