Added coordinates from City database

This commit is contained in:
Mike Raunsbæk 2018-06-15 09:29:13 +02:00 committed by Martin Polden
parent b821b1efcc
commit ac4a9de770
3 changed files with 64 additions and 22 deletions

View File

@ -31,12 +31,15 @@ type Server struct {
}
type Response struct {
IP net.IP `json:"ip"`
IPDecimal *big.Int `json:"ip_decimal"`
Country string `json:"country,omitempty"`
CountryISO string `json:"country_iso,omitempty"`
City string `json:"city,omitempty"`
Hostname string `json:"hostname,omitempty"`
IP net.IP `json:"ip"`
IPDecimal *big.Int `json:"ip_decimal"`
Country string `json:"country,omitempty"`
CountryISO string `json:"country_iso,omitempty"`
City string `json:"city,omitempty"`
Hostname string `json:"hostname,omitempty"`
IsInEuropeanUnion bool `json:"is_in_european_union,omitempty"`
Latitude float64 `json:"location_latitude,omitempty"`
Longitude float64 `json:"location_longitude,omitempty"`
}
type PortResponse struct {
@ -95,12 +98,15 @@ func (s *Server) newResponse(r *http.Request) (Response, error) {
hostname, _ = s.LookupAddr(ip)
}
return Response{
IP: ip,
IPDecimal: ipDecimal,
Country: country.Name,
CountryISO: country.ISO,
City: city,
Hostname: hostname,
IP: ip,
IPDecimal: ipDecimal,
Country: country.Name,
CountryISO: country.ISO,
IsInEuropeanUnion: country.IsInEuropeanUnion,
City: city.Name,
Hostname: hostname,
Latitude: city.Latitude,
Longitude: city.Longitude,
}, nil
}
@ -158,6 +164,15 @@ func (s *Server) CLICityHandler(w http.ResponseWriter, r *http.Request) *appErro
return nil
}
func (s *Server) CLICoordinatesHandler(w http.ResponseWriter, r *http.Request) *appError {
response, err := s.newResponse(r)
if err != nil {
return internalServerError(err)
}
fmt.Fprintf(w, "%s, %s\n", formatCoordinate(response.Latitude), formatCoordinate(response.Longitude))
return nil
}
func (s *Server) JSONHandler(w http.ResponseWriter, r *http.Request) *appError {
response, err := s.newResponse(r)
if err != nil {
@ -281,6 +296,7 @@ func (s *Server) Handler() http.Handler {
r.Route("GET", "/country", s.CLICountryHandler)
r.Route("GET", "/country-iso", s.CLICountryISOHandler)
r.Route("GET", "/city", s.CLICityHandler)
r.Route("GET", "/coordinates", s.CLICoordinatesHandler)
}
// Browser
@ -297,3 +313,7 @@ func (s *Server) Handler() http.Handler {
func (s *Server) ListenAndServe(addr string) error {
return http.ListenAndServe(addr, s.Handler())
}
func formatCoordinate(c float64) string {
return strconv.FormatFloat(c, 'f', 6, 64)
}

View File

@ -20,7 +20,10 @@ func (t *testDb) Country(net.IP) (geo.Country, error) {
return geo.Country{Name: "Elbonia", ISO: "EB"}, nil
}
func (t *testDb) City(net.IP) (string, error) { return "Bornyasherk", nil }
func (t *testDb) City(net.IP) (database.City, error) {
return database.City{Name: "Bornyasherk"}, nil
}
func (t *testDb) IsEmpty() bool { return false }
func testServer() *Server {

View File

@ -2,19 +2,27 @@ package geo
import (
"net"
"math"
geoip2 "github.com/oschwald/geoip2-golang"
)
type Reader interface {
Country(net.IP) (Country, error)
City(net.IP) (string, error)
City(net.IP) (City, error)
IsEmpty() bool
}
type Country struct {
Name string
ISO string
Name string
ISO string
IsInEuropeanUnion bool
}
type City struct {
Name string
Latitude float64
Longitude float64
}
type geoip struct {
@ -62,21 +70,32 @@ func (g *geoip) Country(ip net.IP) (Country, error) {
if record.RegisteredCountry.IsoCode != "" && country.ISO == "" {
country.ISO = record.RegisteredCountry.IsoCode
}
country.IsInEuropeanUnion = record.Country.IsInEuropeanUnion
if record.RegisteredCountry.IsoCode != "" && country.ISO == "" {
country.IsInEuropeanUnion = record.RegisteredCountry.IsInEuropeanUnion
}
return country, nil
}
func (g *geoip) City(ip net.IP) (string, error) {
func (g *geoip) City(ip net.IP) (City, error) {
city := City{}
if g.city == nil {
return "", nil
return city, nil
}
record, err := g.city.City(ip)
if err != nil {
return "", err
return city, err
}
if city, exists := record.City.Names["en"]; exists {
return city, nil
if c, exists := record.City.Names["en"]; exists {
city.Name = c
}
return "", nil
if !math.IsNaN(record.Location.Latitude) {
city.Latitude = record.Location.Latitude
}
if !math.IsNaN(record.Location.Longitude) {
city.Longitude = record.Location.Longitude
}
return city, nil
}
func (g *geoip) IsEmpty() bool {