openreplay/backend/internal/http/geoip/geoip.go
Alexander f89d84232a
[DB] Added support for city/state autocomplete (#1317)
* feat(backend): added support for city/state autocomplete

* fix(backend): removed unused http handlers
2023-06-08 15:59:53 +02:00

84 lines
1.5 KiB
Go

package geoip
import (
"github.com/oschwald/maxminddb-golang"
"log"
"net"
"strings"
)
type geoIPRecord struct {
Country struct {
ISOCode string `maxminddb:"iso_code"`
} `maxminddb:"country"`
States []struct {
Names map[string]string `maxminddb:"names"`
} `maxminddb:"subdivisions"`
City struct {
Names map[string]string `maxminddb:"names"`
} `maxminddb:"city"`
}
type GeoRecord struct {
Country string
State string
City string
}
func (r *GeoRecord) Pack() string {
return r.Country + "|" + r.State + "|" + r.City
}
func UnpackGeoRecord(pkg string) *GeoRecord {
parts := strings.Split(pkg, "|")
if len(parts) != 3 {
return &GeoRecord{
Country: pkg,
}
}
return &GeoRecord{
Country: parts[0],
State: parts[1],
City: parts[2],
}
}
type GeoParser interface {
Parse(ip net.IP) *GeoRecord
}
type geoParser struct {
r *maxminddb.Reader
}
func New(file string) GeoParser {
r, err := maxminddb.Open(file)
if err != nil {
log.Fatalln(err)
}
return &geoParser{r}
}
func (geoIP *geoParser) Parse(ip net.IP) *GeoRecord {
res := &GeoRecord{
Country: "UN",
State: "",
City: "",
}
if ip == nil {
return res
}
var record geoIPRecord
if err := geoIP.r.Lookup(ip, &record); err != nil {
log.Println(err)
return res
}
if record.Country.ISOCode != "" {
res.Country = record.Country.ISOCode
}
if len(record.States) > 0 {
res.State = record.States[0].Names["en"]
}
res.City = record.City.Names["en"]
return res
}