class Ipapi include HTTParty BASE_URL = "https://api.ipapi.is/" def api_key = Setting.ipapi_key def lookup(ip) return unless api_key.present? response = self.class.get("#{BASE_URL}", query: { q: ip, key: api_key }) response.parsed_response end def self.lookup(ip) = new.lookup(ip) def multi_lookup(ips) ips = Array(ips) ips.each_slice(100).flat_map { |slice| post_data({ips: slice}) } end def data(ip) if ip.is_a?(Array) post_data(ip) else response = self.class.get("#{BASE_URL}", query: { q: ip, key: api_key }) response.parsed_response end rescue JSON::ParserError {} end def post_data(ips) response = self.class.post("#{BASE_URL}", query: { key: api_key }, body: { ips: ips }.to_json, headers: { 'Content-Type' => 'application/json' } ) results = response.parsed_response results["response"].map do |ip, data| IPAddr.new(ip) cidr = data.dig("asn", "route") network_range = NetworkRange.add_network(cidr) if network_range network_range.set_network_data(:ipapi, data) network_range.last_api_fetch = Time.current network_range.save end network_range rescue IPAddr::InvalidAddressError puts "Skipping #{ip}" next end end end