mirror of
https://github.com/Li4n0/revsuit.git
synced 2026-09-24 23:51:54 +08:00
68 lines
1.4 KiB
Go
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}
|
|
}
|