feat: geo ip.
This commit is contained in:
12
geoip/geolite/README.md
Normal file
12
geoip/geolite/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# GEOIP2(GeoLite2)
|
||||
|
||||
GeoLite2数据库是免费的IP地理位置数据库,它可以通过IP地址识别其所在的城市和国家。与MaxMind的GeoIP2数据库相比,准确性较差。
|
||||
|
||||
GeoLite2-*.mmdb文件是一个二进制数据库文件,包含了MaxMind GeoLite2所需的全部数据。
|
||||
|
||||
GeoLite2的数据库分为:国家(Country),城市(City)和ASN三个数据库。每周两次更新。
|
||||
|
||||
## 数据库下载地址
|
||||
|
||||
1. <https://github.com/P3TERX/GeoLite.mmdb/releases>
|
||||
2. <https://dev.maxmind.com/geoip/geolite2-free-geolocation-data>
|
||||
BIN
geoip/geolite/assets/GeoLite2-City.mmdb
Normal file
BIN
geoip/geolite/assets/GeoLite2-City.mmdb
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 MiB |
6
geoip/geolite/assets/assets.go
Normal file
6
geoip/geolite/assets/assets.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package assets
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed GeoLite2-City.mmdb
|
||||
var GeoLite2CityData []byte
|
||||
73
geoip/geolite/geolite.go
Normal file
73
geoip/geolite/geolite.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package geolite
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/log"
|
||||
"github.com/oschwald/geoip2-golang"
|
||||
"github.com/tx7do/kratos-utils/geoip/geolite/assets"
|
||||
)
|
||||
|
||||
type Result struct {
|
||||
Country string // 国家
|
||||
Province string // 省
|
||||
City string // 城市
|
||||
}
|
||||
|
||||
const defaultOutputLanguage = "zh-CN"
|
||||
|
||||
// Client 地理位置解析结构体
|
||||
type Client struct {
|
||||
db *geoip2.Reader
|
||||
outputLanguage string
|
||||
}
|
||||
|
||||
// NewClient .
|
||||
func NewClient() (*Client, error) {
|
||||
db, err := geoip2.FromBytes(assets.GeoLite2CityData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Client{db: db, outputLanguage: defaultOutputLanguage}, nil
|
||||
}
|
||||
|
||||
// Close 关闭客户端
|
||||
func (g *Client) Close() error {
|
||||
if g.db == nil {
|
||||
return nil
|
||||
}
|
||||
return g.db.Close()
|
||||
}
|
||||
|
||||
// SetLanguage 设置输出的语言,默认为:zh-CN
|
||||
func (g *Client) SetLanguage(code string) {
|
||||
g.outputLanguage = code
|
||||
}
|
||||
|
||||
// query 查询城市级别数据
|
||||
func (g *Client) query(rawIP string) (city *geoip2.City, err error) {
|
||||
ip := net.ParseIP(rawIP)
|
||||
if ip == nil {
|
||||
return nil, errors.New("invalid ip")
|
||||
}
|
||||
|
||||
return g.db.City(ip)
|
||||
}
|
||||
|
||||
// Query 通过IP获取地区
|
||||
func (g *Client) Query(rawIP string) (ret Result, err error) {
|
||||
record, err := g.query(rawIP)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
ret.Country = record.Country.Names[g.outputLanguage]
|
||||
if len(record.Subdivisions) > 0 {
|
||||
ret.Province = record.Subdivisions[0].Names[g.outputLanguage]
|
||||
}
|
||||
ret.City = record.City.Names[g.outputLanguage]
|
||||
|
||||
return
|
||||
}
|
||||
17
geoip/geolite/geolite_test.go
Normal file
17
geoip/geolite/geolite_test.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package geolite
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGeoLite(t *testing.T) {
|
||||
g, err := NewClient()
|
||||
assert.Nil(t, err)
|
||||
|
||||
ret, err := g.Query("47.108.149.89")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, ret.Country, "中国")
|
||||
assert.Equal(t, ret.Province, "四川省")
|
||||
assert.Equal(t, ret.City, "成都")
|
||||
}
|
||||
Reference in New Issue
Block a user