Getting information about an IP address from PB

Share your advanced PureBasic knowledge/code with the community.
Quin
Addict
Addict
Posts: 1133
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Getting information about an IP address from PB

Post by Quin »

Hi,
I wrote a PB library to quickly query information about an IP address. It gives you things such as the country, city, region, zip code, ISP, and time zone of the specified IP.
For usage, see the bottom of the file.

Code: Select all

; IPLocale Library.
; Written by Quin on Monday, October 2, 2023.

EnableExplicit

;{ Structures
Structure IPLocaleInfo
  Query.s
  Country.s
  Region.s
  City.s
  ZipCode.s
  Latitude.f
  Longitude.f
  Timezone.s
  ISP.s
EndStructure
;}

;{ Declares
Declare GetIPLocale(IPAddress.s, *Info.IPLocaleInfo)
;}

;{ Macros
Macro JString(Value)
  GetJSONString(GetJSONMember(JSONValue(0), Value))
EndMacro

Macro JFloat(Value)
  GetJSONFloat(GetJSONMember(JSONValue(0), Value))
EndMacro
;}

;{ Main
Procedure GetIPLocale(IPAddress.s, *Info.IPLocaleInfo)
  Protected Request = HTTPRequest(#PB_HTTP_Get, "http://ip-api.com/json/" + IPAddress)
  If Request = 0
    ProcedureReturn 1
  EndIf
  Protected Response.s = HTTPInfo(Request, #PB_HTTP_Response)
  FinishHTTP(Request)
  If ParseJSON(0, Response) = 0
    ProcedureReturn 1
  EndIf
  Protected Status.s = JString("status")
  If Status = "fail"
    FreeJSON(0)
    ProcedureReturn 1
  EndIf
  With *Info
    \Query = JString("query")
    \Country = JString("country")
    \Region = JString("regionName")
    \City = JString("city")
    \ZipCode = JString("zip")
    \Latitude = JFloat("lat")
    \Longitude = JFloat("lon")
    \Timezone = JString("timezone")
    \ISP = RTrim(JString("isp"), ".")
  EndWith
  FreeJSON(0)
  ProcedureReturn 0
EndProcedure
;}

;{ Demo
CompilerIf #PB_Compiler_IsMainFile
  Define Info.IPLocaleInfo
  GetIPLocale("76.25.0.4", @Info)
  With Info
    Debug \City
    Debug \Country
    Debug \ISP
    Debug \Latitude
    Debug \Longitude
    Debug \Query
    Debug \Region
    Debug \Timezone
    Debug \ZipCode
  EndWith
CompilerEndIf
;}
Enjoy, and feel free to leave any feedback (I'm still not entirely sure if I should try to return a populated structure). I think not but haven't been using PB for a super long time, so am still second guessing myself.
User avatar
VB6_to_PBx
Enthusiast
Enthusiast
Posts: 627
Joined: Mon May 09, 2011 9:36 am

Re: Getting information about an IP address from PB

Post by VB6_to_PBx »

by Quin » Mon Oct 02, 2023 12:11 pm

thanks Quin ,
your Code works perfectly for my IP !
 
PureBasic .... making tiny electrons do what you want !

"With every mistake we must surely be learning" - George Harrison
infratec
Always Here
Always Here
Posts: 7618
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Getting information about an IP address from PB

Post by infratec »

A bit simpler and with all possible values:

Code: Select all

; IPLocale Library.
; Written by Quin on Monday, October 2, 2023.

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf


Structure IPLocaleInfo
  query.s
  status.s
  continent.s
  continentCode.s
  country.s
  countryCode.s
  region.s
  regionName.s
  city.s
  district.s
  zip.s
  lat.f
  lon.f
  timezone.s
  offset.i
  currency.s
  isp.s
  org.s
  As.s
  asname.s
  reverse.s
  ;mobile.i
  ;proxy.i
  ;hosting.i
EndStructure



Procedure.i GetIPLocale(IPAddress.s, *Info.IPLocaleInfo)
  
  Protected.i Result, Request, JSON
  Protected Response.s
  
  
  Request = HTTPRequest(#PB_HTTP_Get, "http://ip-api.com/json/" + IPAddress + "?fields=status,message,continent,continentCode,country,countryCode,region,regionName,city,district,zip,lat,lon,timezone,offset,currency,isp,org,as,asname,reverse,query")
  If Request
    Response = HTTPInfo(Request, #PB_HTTP_Response)
    Debug Response
    FinishHTTP(Request)
    
    JSON = ParseJSON(#PB_Any, Response, #PB_JSON_NoCase)
    If JSON
      ExtractJSONStructure(JSONValue(JSON), *Info, IPLocaleInfo)
      FreeJSON(JSON)
      
      If *Info\status = "success"
        Result = #True
      EndIf
    EndIf
    
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
  Define Info.IPLocaleInfo
  If GetIPLocale("", @Info)
    With Info
      Debug \query
      Debug \status
      Debug \continent
      Debug \continentCode
      Debug \zip
      Debug \city
      Debug \country
      Debug \countryCode
      Debug \district
      Debug \region
      Debug \regionName
      Debug \timezone
      Debug \offset
      Debug \lat
      Debug \lon
      Debug \isp
      Debug \org
      Debug \As
      Debug \asname
      Debug \reverse
    EndWith
  EndIf
CompilerEndIf
Last edited by infratec on Mon Oct 02, 2023 9:01 pm, edited 2 times in total.
User avatar
idle
Always Here
Always Here
Posts: 5899
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Getting information about an IP address from PB

Post by idle »

That's very useful. I will see if I can use that in dnscope when I get around to trying to do p2p dns to get around geo blocks.
infratec
Always Here
Always Here
Posts: 7618
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Getting information about an IP address from PB

Post by infratec »

If you want to get all entries, you have to specify them.

I added this in the code above.
Quin
Addict
Addict
Posts: 1133
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: Getting information about an IP address from PB

Post by Quin »

That's epic! Thanks a ton!
infratec wrote: Mon Oct 02, 2023 8:36 pm A bit simpler and with all possible values:

Code: Select all

; IPLocale Library.
; Written by Quin on Monday, October 2, 2023.

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf


Structure IPLocaleInfo
  query.s
  status.s
  continent.s
  continentCode.s
  country.s
  countryCode.s
  region.s
  regionName.s
  city.s
  district.s
  zip.s
  lat.f
  lon.f
  timezone.s
  offset.i
  currency.s
  isp.s
  org.s
  As.s
  asname.s
  reverse.s
  ;mobile.i
  ;proxy.i
  ;hosting.i
EndStructure



Procedure.i GetIPLocale(IPAddress.s, *Info.IPLocaleInfo)
  
  Protected.i Result, Request, JSON
  Protected Response.s
  
  
  Request = HTTPRequest(#PB_HTTP_Get, "http://ip-api.com/json/" + IPAddress + "?fields=status,message,continent,continentCode,country,countryCode,region,regionName,city,district,zip,lat,lon,timezone,offset,currency,isp,org,as,asname,reverse,query")
  If Request
    Response = HTTPInfo(Request, #PB_HTTP_Response)
    Debug Response
    FinishHTTP(Request)
    
    JSON = ParseJSON(#PB_Any, Response, #PB_JSON_NoCase)
    If JSON
      ExtractJSONStructure(JSONValue(JSON), *Info, IPLocaleInfo)
      FreeJSON(JSON)
      
      If *Info\status = "success"
        Result = #True
      EndIf
    EndIf
    
  EndIf
  
  ProcedureReturn Result
  
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
  Define Info.IPLocaleInfo
  If GetIPLocale("", @Info)
    With Info
      Debug \query
      Debug \status
      Debug \continent
      Debug \continentCode
      Debug \zip
      Debug \city
      Debug \country
      Debug \countryCode
      Debug \district
      Debug \region
      Debug \regionName
      Debug \timezone
      Debug \offset
      Debug \lat
      Debug \lon
      Debug \isp
      Debug \org
      Debug \As
      Debug \asname
      Debug \reverse
    EndWith
  EndIf
CompilerEndIf
benubi
Enthusiast
Enthusiast
Posts: 220
Joined: Tue Mar 29, 2005 4:01 pm

Re: Getting information about an IP address from PB

Post by benubi »

Better keep an eye on the limitations (for free access users). Max. 45 request per minute, and only HTTP - which may not be good because it send the IP information in plain text (JSON). You can get SSL for paying a monthly fee. In any case you probably want to cache the IP results to speed up and minimize multiple queries, save bandwidth.
Post Reply