Files
revsuit/internal/ipinfo/geoip/geo.go
T
2021-06-12 22:04:45 +08:00

68 lines
1.4 KiB
Go

package geoip
import (
"fmt"
"net"
"os"
"sync"
"time"
"github.com/oschwald/geoip2-golang"
log "unknwon.dev/clog/v2"
)
type Database struct {
geo *geoip2.Reader
}
var geo *geoip2.Reader
var once sync.Once
// Area returns IpArea according to ip
func (db *Database) Area(ip string) string {
defer func() {
_ = recover()
}()
record, err := db.geo.City(net.ParseIP(ip))
if err != nil {
return ""
}
country := record.Country.Names["en"]
city := record.City.Names["en"]
if city == "" {
city = record.Location.TimeZone
}
return fmt.Sprintf("%s %s", country, city)
}
func checkUpdate(licenseKey string) {
info, err := os.Stat("GeoLite2-City.mmdb")
if err != nil {
if os.IsNotExist(err) {
err := download(licenseKey)
if err != nil {
log.Warn("Download GeoLite2-City.mmdb failed, caused by:%v, recommend to download it by yourself otherwise the `IpArea` will be null", err)
}
}
} else if -time.Until(info.ModTime()) > 7*24*time.Hour {
log.Info("Updating GeoLite2-City.mmdb...")
err := download(licenseKey)
if err != nil {
log.Warn("Update GeoLite2-City.mmdb failed, please download GeoLite2-City.mmdb by yourself")
}
}
}
func New(licenseKey string) *Database {
once.Do(func() {
var err error
checkUpdate(licenseKey)
geo, err = geoip2.Open("GeoLite2-City.mmdb")
if err != nil {
log.Error("Load GeoLite2-City.mmdb failed, `IpArea` will be null")
}
})
return &Database{geo: geo}
}