mirror of
				https://github.com/TeaOSLab/EdgeAPI.git
				synced 2025-11-04 16:00:24 +08:00 
			
		
		
		
	初步完成新版IP库
This commit is contained in:
		@@ -95,9 +95,6 @@ function build() {
 | 
				
			|||||||
	cp -R "$ROOT"/deploy "$DIST/"
 | 
						cp -R "$ROOT"/deploy "$DIST/"
 | 
				
			||||||
	rm -f "$DIST"/deploy/.gitignore
 | 
						rm -f "$DIST"/deploy/.gitignore
 | 
				
			||||||
	cp -R "$ROOT"/installers "$DIST"/
 | 
						cp -R "$ROOT"/installers "$DIST"/
 | 
				
			||||||
	cp -R "$ROOT"/resources "$DIST"/
 | 
					 | 
				
			||||||
	rm -f "$DIST"/resources/ipdata/ip2region/global_region.csv
 | 
					 | 
				
			||||||
	rm -f "$DIST"/resources/ipdata/ip2region/ip.merge.txt
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	# building edge installer
 | 
						# building edge installer
 | 
				
			||||||
	echo "building node installer ..."
 | 
						echo "building node installer ..."
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -1,193 +0,0 @@
 | 
				
			|||||||
package main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/db/models/regions"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
					 | 
				
			||||||
	_ "github.com/iwind/TeaGo/bootstrap"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/dbs"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/lists"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/logs"
 | 
					 | 
				
			||||||
	"io/ioutil"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"regexp"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					 | 
				
			||||||
	// 导入数据
 | 
					 | 
				
			||||||
	if lists.ContainsString(os.Args, "import") {
 | 
					 | 
				
			||||||
		dbs.NotifyReady()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		data, err := ioutil.ReadFile(Tea.Root + "/resources/ipdata/ip2region/global_region.csv")
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(data) == 0 {
 | 
					 | 
				
			||||||
			logs.Println("[ERROR]file content should not be empty")
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		lines := bytes.Split(data, []byte{'\n'})
 | 
					 | 
				
			||||||
		for _, line := range lines {
 | 
					 | 
				
			||||||
			line = bytes.TrimSpace(line)
 | 
					 | 
				
			||||||
			if len(line) == 0 {
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			s := string(line)
 | 
					 | 
				
			||||||
			reg := regexp.MustCompile(`(?U)(\d+),(\d+),(.+),(\d+),`)
 | 
					 | 
				
			||||||
			if !reg.MatchString(s) {
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			result := reg.FindStringSubmatch(s)
 | 
					 | 
				
			||||||
			dataId := result[1]
 | 
					 | 
				
			||||||
			parentDataId := result[2]
 | 
					 | 
				
			||||||
			name := result[3]
 | 
					 | 
				
			||||||
			level := result[4]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			switch level {
 | 
					 | 
				
			||||||
			case "1": // 国家|地区
 | 
					 | 
				
			||||||
				countryId, err := regions.SharedRegionCountryDAO.FindCountryIdWithDataId(nil, dataId)
 | 
					 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if countryId == 0 {
 | 
					 | 
				
			||||||
					logs.Println("creating country or region ", name)
 | 
					 | 
				
			||||||
					_, err = regions.SharedRegionCountryDAO.CreateCountry(nil, name, dataId)
 | 
					 | 
				
			||||||
					if err != nil {
 | 
					 | 
				
			||||||
						logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
						return
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			case "2": // 省份|地区
 | 
					 | 
				
			||||||
				provinceId, err := regions.SharedRegionProvinceDAO.FindProvinceIdWithDataId(nil, dataId)
 | 
					 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if provinceId == 0 {
 | 
					 | 
				
			||||||
					logs.Println("creating province", name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					countryId, err := regions.SharedRegionCountryDAO.FindCountryIdWithDataId(nil, parentDataId)
 | 
					 | 
				
			||||||
					if err != nil {
 | 
					 | 
				
			||||||
						logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
						return
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					if countryId == 0 {
 | 
					 | 
				
			||||||
						logs.Println("[ERROR]can not find country from data id '" + parentDataId + "'")
 | 
					 | 
				
			||||||
						return
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					_, err = regions.SharedRegionProvinceDAO.CreateProvince(nil, countryId, name, dataId)
 | 
					 | 
				
			||||||
					if err != nil {
 | 
					 | 
				
			||||||
						logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
						return
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			case "3": // 城市
 | 
					 | 
				
			||||||
				cityId, err := regions.SharedRegionCityDAO.FindCityWithDataId(nil, dataId)
 | 
					 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if cityId == 0 {
 | 
					 | 
				
			||||||
					logs.Println("creating city", name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					provinceId, err := regions.SharedRegionProvinceDAO.FindProvinceIdWithDataId(nil, parentDataId)
 | 
					 | 
				
			||||||
					if err != nil {
 | 
					 | 
				
			||||||
						logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
						return
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					_, err = regions.SharedRegionCityDAO.CreateCity(nil, provinceId, name, dataId)
 | 
					 | 
				
			||||||
					if err != nil {
 | 
					 | 
				
			||||||
						logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
						return
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		logs.Println("done")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 检查数据
 | 
					 | 
				
			||||||
	if lists.ContainsString(os.Args, "check") {
 | 
					 | 
				
			||||||
		dbs.NotifyReady()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		data, err := ioutil.ReadFile(Tea.Root + "/resources/ipdata/ip2region/ip.merge.txt")
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(data) == 0 {
 | 
					 | 
				
			||||||
			logs.Println("[ERROR]file should not be empty")
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		lines := bytes.Split(data, []byte("\n"))
 | 
					 | 
				
			||||||
		for index, line := range lines {
 | 
					 | 
				
			||||||
			s := string(bytes.TrimSpace(line))
 | 
					 | 
				
			||||||
			if len(s) == 0 {
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			pieces := strings.Split(s, "|")
 | 
					 | 
				
			||||||
			countryName := pieces[2]
 | 
					 | 
				
			||||||
			provinceName := pieces[4]
 | 
					 | 
				
			||||||
			providerName := pieces[6]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// 记录provider
 | 
					 | 
				
			||||||
			if len(providerName) > 0 && providerName != "0" {
 | 
					 | 
				
			||||||
				providerId, err := regions.SharedRegionProviderDAO.FindProviderIdWithNameCacheable(nil, providerName)
 | 
					 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					logs.Println("[ERROR]find provider id failed: " + err.Error())
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if providerId == 0 {
 | 
					 | 
				
			||||||
					logs.Println("creating new provider '"+providerName+"' ... ", index, "line")
 | 
					 | 
				
			||||||
					_, err = regions.SharedRegionProviderDAO.CreateProvider(nil, providerName)
 | 
					 | 
				
			||||||
					if err != nil {
 | 
					 | 
				
			||||||
						logs.Println("create new provider failed: " + providerName)
 | 
					 | 
				
			||||||
						return
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					logs.Println("created new provider '" + providerName + "'")
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if lists.ContainsString([]string{"0", "欧洲", "北美地区", "法国南部领地", "非洲地区", "亚太地区"}, countryName) {
 | 
					 | 
				
			||||||
				continue
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// 检查国家
 | 
					 | 
				
			||||||
			countryId, err := regions.SharedRegionCountryDAO.FindCountryIdWithNameCacheable(nil, countryName)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if countryId == 0 {
 | 
					 | 
				
			||||||
				logs.Println("[ERROR]can not find country '"+countryName+"', index: ", index, "data: "+s)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// 检查省份
 | 
					 | 
				
			||||||
			if countryName == "中国" {
 | 
					 | 
				
			||||||
				if lists.ContainsString([]string{"0"}, provinceName) {
 | 
					 | 
				
			||||||
					continue
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				provinceId, err := regions.SharedRegionProvinceDAO.FindProvinceIdWithNameCacheable(nil, countryId, provinceName)
 | 
					 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					logs.Println("[ERROR]" + err.Error())
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if provinceId == 0 {
 | 
					 | 
				
			||||||
					logs.Println("[ERROR]can not find province '"+provinceName+"', index: ", index, "data: "+s)
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		logs.Println("done")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -72,8 +72,9 @@ func (this *IPLibraryFileDAO) FindEnabledIPLibraryFile(tx *dbs.Tx, id int64) (*I
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CreateLibraryFile 创建文件
 | 
					// CreateLibraryFile 创建文件
 | 
				
			||||||
func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, template string, emptyValues []string, fileId int64, countries []string, provinces [][2]string, cities [][3]string, towns [][4]string, providers []string) (int64, error) {
 | 
					func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, name string, template string, emptyValues []string, fileId int64, countries []string, provinces [][2]string, cities [][3]string, towns [][4]string, providers []string) (int64, error) {
 | 
				
			||||||
	var op = NewIPLibraryFileOperator()
 | 
						var op = NewIPLibraryFileOperator()
 | 
				
			||||||
 | 
						op.Name = name
 | 
				
			||||||
	op.Template = template
 | 
						op.Template = template
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if emptyValues == nil {
 | 
						if emptyValues == nil {
 | 
				
			||||||
@@ -137,6 +138,18 @@ func (this *IPLibraryFileDAO) CreateLibraryFile(tx *dbs.Tx, template string, emp
 | 
				
			|||||||
	return this.SaveInt64(tx, op)
 | 
						return this.SaveInt64(tx, op)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FindAllFinishedLibraryFiles 查找所有已完成的文件
 | 
				
			||||||
 | 
					func (this *IPLibraryFileDAO) FindAllFinishedLibraryFiles(tx *dbs.Tx) (result []*IPLibraryFile, err error) {
 | 
				
			||||||
 | 
						_, err = this.Query(tx).
 | 
				
			||||||
 | 
							State(IPLibraryFileStateEnabled).
 | 
				
			||||||
 | 
							Result("id", "fileId", "createdAt", "generatedFileId", "generatedAt", "name"). // 这里不需要其他信息
 | 
				
			||||||
 | 
							Attr("isFinished", true).
 | 
				
			||||||
 | 
							DescPk().
 | 
				
			||||||
 | 
							Slice(&result).
 | 
				
			||||||
 | 
							FindAll()
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FindAllUnfinishedLibraryFiles 查找所有未完成的文件
 | 
					// FindAllUnfinishedLibraryFiles 查找所有未完成的文件
 | 
				
			||||||
func (this *IPLibraryFileDAO) FindAllUnfinishedLibraryFiles(tx *dbs.Tx) (result []*IPLibraryFile, err error) {
 | 
					func (this *IPLibraryFileDAO) FindAllUnfinishedLibraryFiles(tx *dbs.Tx) (result []*IPLibraryFile, err error) {
 | 
				
			||||||
	_, err = this.Query(tx).
 | 
						_, err = this.Query(tx).
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,7 @@ import "github.com/iwind/TeaGo/dbs"
 | 
				
			|||||||
// IPLibraryFile IP库上传的文件
 | 
					// IPLibraryFile IP库上传的文件
 | 
				
			||||||
type IPLibraryFile struct {
 | 
					type IPLibraryFile struct {
 | 
				
			||||||
	Id              uint64   `field:"id"`              // ID
 | 
						Id              uint64   `field:"id"`              // ID
 | 
				
			||||||
 | 
						Name            string   `field:"name"`            // IP库名称
 | 
				
			||||||
	FileId          uint64   `field:"fileId"`          // 原始文件ID
 | 
						FileId          uint64   `field:"fileId"`          // 原始文件ID
 | 
				
			||||||
	Template        string   `field:"template"`        // 模板
 | 
						Template        string   `field:"template"`        // 模板
 | 
				
			||||||
	EmptyValues     dbs.JSON `field:"emptyValues"`     // 空值列表
 | 
						EmptyValues     dbs.JSON `field:"emptyValues"`     // 空值列表
 | 
				
			||||||
@@ -23,6 +24,7 @@ type IPLibraryFile struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type IPLibraryFileOperator struct {
 | 
					type IPLibraryFileOperator struct {
 | 
				
			||||||
	Id              any // ID
 | 
						Id              any // ID
 | 
				
			||||||
 | 
						Name            any // IP库名称
 | 
				
			||||||
	FileId          any // 原始文件ID
 | 
						FileId          any // 原始文件ID
 | 
				
			||||||
	Template        any // 模板
 | 
						Template        any // 模板
 | 
				
			||||||
	EmptyValues     any // 空值列表
 | 
						EmptyValues     any // 空值列表
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -162,3 +162,19 @@ func (this *RegionTownDAO) FindSimilarTowns(towns []*RegionTown, townName string
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CreateTown 创建区县
 | 
				
			||||||
 | 
					func (this *RegionTownDAO) CreateTown(tx *dbs.Tx, cityId int64, townName string) (int64, error) {
 | 
				
			||||||
 | 
						var op = NewRegionTownOperator()
 | 
				
			||||||
 | 
						op.CityId = cityId
 | 
				
			||||||
 | 
						op.Name = townName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						codes, err := json.Marshal([]string{townName})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						op.Codes = codes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						op.State = RegionTownStateEnabled
 | 
				
			||||||
 | 
						return this.SaveInt64(tx, op)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +0,0 @@
 | 
				
			|||||||
package iplibrary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,130 +0,0 @@
 | 
				
			|||||||
// 源码改自:https://github.com/lionsoul2014/ip2region/blob/master/binding/golang/ip2region/ip2Region.go
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package iplibrary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	IndexBlockLength = 12
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var err error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type IP2Region struct {
 | 
					 | 
				
			||||||
	headerSip []int64
 | 
					 | 
				
			||||||
	headerPtr []int64
 | 
					 | 
				
			||||||
	headerLen int64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// super block index info
 | 
					 | 
				
			||||||
	firstIndexPtr int64
 | 
					 | 
				
			||||||
	lastIndexPtr  int64
 | 
					 | 
				
			||||||
	totalBlocks   int64
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dbData []byte
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type IpInfo struct {
 | 
					 | 
				
			||||||
	CityId   int64
 | 
					 | 
				
			||||||
	Country  string
 | 
					 | 
				
			||||||
	Region   string
 | 
					 | 
				
			||||||
	Province string
 | 
					 | 
				
			||||||
	City     string
 | 
					 | 
				
			||||||
	ISP      string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (ip IpInfo) String() string {
 | 
					 | 
				
			||||||
	return strconv.FormatInt(ip.CityId, 10) + "|" + ip.Country + "|" + ip.Region + "|" + ip.Province + "|" + ip.City + "|" + ip.ISP
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func getIpInfo(cityId int64, line []byte) *IpInfo {
 | 
					 | 
				
			||||||
	lineSlice := strings.Split(string(line), "|")
 | 
					 | 
				
			||||||
	ipInfo := &IpInfo{}
 | 
					 | 
				
			||||||
	length := len(lineSlice)
 | 
					 | 
				
			||||||
	ipInfo.CityId = cityId
 | 
					 | 
				
			||||||
	if length < 5 {
 | 
					 | 
				
			||||||
		for i := 0; i <= 5-length; i++ {
 | 
					 | 
				
			||||||
			lineSlice = append(lineSlice, "")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ipInfo.Country = lineSlice[0]
 | 
					 | 
				
			||||||
	ipInfo.Region = lineSlice[1]
 | 
					 | 
				
			||||||
	ipInfo.Province = lineSlice[2]
 | 
					 | 
				
			||||||
	ipInfo.City = lineSlice[3]
 | 
					 | 
				
			||||||
	ipInfo.ISP = lineSlice[4]
 | 
					 | 
				
			||||||
	return ipInfo
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewIP2Region(path string) (*IP2Region, error) {
 | 
					 | 
				
			||||||
	var region = &IP2Region{}
 | 
					 | 
				
			||||||
	region.dbData, err = os.ReadFile(path)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	region.firstIndexPtr = region.ipLongAtOffset(0)
 | 
					 | 
				
			||||||
	region.lastIndexPtr = region.ipLongAtOffset(4)
 | 
					 | 
				
			||||||
	region.totalBlocks = (region.lastIndexPtr-region.firstIndexPtr)/IndexBlockLength + 1
 | 
					 | 
				
			||||||
	return region, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (this *IP2Region) MemorySearch(ipStr string) (ipInfo *IpInfo, err error) {
 | 
					 | 
				
			||||||
	ip, err := ip2long(ipStr)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	h := this.totalBlocks
 | 
					 | 
				
			||||||
	var dataPtr, l int64
 | 
					 | 
				
			||||||
	for l <= h {
 | 
					 | 
				
			||||||
		m := (l + h) >> 1
 | 
					 | 
				
			||||||
		p := this.firstIndexPtr + m*IndexBlockLength
 | 
					 | 
				
			||||||
		sip := this.ipLongAtOffset(p)
 | 
					 | 
				
			||||||
		if ip < sip {
 | 
					 | 
				
			||||||
			h = m - 1
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			eip := this.ipLongAtOffset(p + 4)
 | 
					 | 
				
			||||||
			if ip > eip {
 | 
					 | 
				
			||||||
				l = m + 1
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				dataPtr = this.ipLongAtOffset(p + 8)
 | 
					 | 
				
			||||||
				break
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if dataPtr == 0 {
 | 
					 | 
				
			||||||
		return nil, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dataLen := (dataPtr >> 24) & 0xFF
 | 
					 | 
				
			||||||
	dataPtr = dataPtr & 0x00FFFFFF
 | 
					 | 
				
			||||||
	return getIpInfo(this.ipLongAtOffset(dataPtr), this.dbData[(dataPtr)+4:dataPtr+dataLen]), nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (this *IP2Region) ipLongAtOffset(offset int64) int64 {
 | 
					 | 
				
			||||||
	return int64(this.dbData[offset]) |
 | 
					 | 
				
			||||||
		int64(this.dbData[offset+1])<<8 |
 | 
					 | 
				
			||||||
		int64(this.dbData[offset+2])<<16 |
 | 
					 | 
				
			||||||
		int64(this.dbData[offset+3])<<24
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func ip2long(IpStr string) (int64, error) {
 | 
					 | 
				
			||||||
	bits := strings.Split(IpStr, ".")
 | 
					 | 
				
			||||||
	if len(bits) != 4 {
 | 
					 | 
				
			||||||
		return 0, errors.New("ip format error")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var sum int64
 | 
					 | 
				
			||||||
	for i, n := range bits {
 | 
					 | 
				
			||||||
		bit, _ := strconv.ParseInt(n, 10, 64)
 | 
					 | 
				
			||||||
		sum += bit << uint(24-8*i)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return sum, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
package iplibrary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type LibraryInterface interface {
 | 
					 | 
				
			||||||
	// 加载数据库文件
 | 
					 | 
				
			||||||
	Load(dbPath string) error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 查询IP
 | 
					 | 
				
			||||||
	Lookup(ip string) (*Result, error)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 关闭数据库文件
 | 
					 | 
				
			||||||
	Close()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,81 +0,0 @@
 | 
				
			|||||||
package iplibrary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/errors"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/remotelogs"
 | 
					 | 
				
			||||||
	"net"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type IP2RegionLibrary struct {
 | 
					 | 
				
			||||||
	db *IP2Region
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (this *IP2RegionLibrary) Load(dbPath string) error {
 | 
					 | 
				
			||||||
	db, err := NewIP2Region(dbPath)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	this.db = db
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (this *IP2RegionLibrary) Lookup(ip string) (*Result, error) {
 | 
					 | 
				
			||||||
	if this.db == nil {
 | 
					 | 
				
			||||||
		return nil, errors.New("library has not been loaded")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 只支持IPv4
 | 
					 | 
				
			||||||
	if strings.Contains(ip, ":") {
 | 
					 | 
				
			||||||
		return nil, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if net.ParseIP(ip) == nil {
 | 
					 | 
				
			||||||
		return nil, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		// 防止panic发生
 | 
					 | 
				
			||||||
		err := recover()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			remotelogs.Error("IP2RegionLibrary", "panic: "+fmt.Sprintf("%#v", err))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	info, err := this.db.MemorySearch(ip)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if info.Country == "0" {
 | 
					 | 
				
			||||||
		info.Country = ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if info.Region == "0" {
 | 
					 | 
				
			||||||
		info.Region = ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if info.Province == "0" {
 | 
					 | 
				
			||||||
		info.Province = ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if info.City == "0" {
 | 
					 | 
				
			||||||
		info.City = ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if info.ISP == "0" {
 | 
					 | 
				
			||||||
		info.ISP = ""
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &Result{
 | 
					 | 
				
			||||||
		CityId:   info.CityId,
 | 
					 | 
				
			||||||
		Country:  info.Country,
 | 
					 | 
				
			||||||
		Region:   info.Region,
 | 
					 | 
				
			||||||
		Province: info.Province,
 | 
					 | 
				
			||||||
		City:     info.City,
 | 
					 | 
				
			||||||
		ISP:      info.ISP,
 | 
					 | 
				
			||||||
	}, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (this *IP2RegionLibrary) Close() {
 | 
					 | 
				
			||||||
	if this.db != nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,78 +0,0 @@
 | 
				
			|||||||
package iplibrary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
					 | 
				
			||||||
	_ "github.com/iwind/TeaGo/bootstrap"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/logs"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/rands"
 | 
					 | 
				
			||||||
	"runtime"
 | 
					 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestIP2RegionLibrary_Lookup(t *testing.T) {
 | 
					 | 
				
			||||||
	library := &IP2RegionLibrary{}
 | 
					 | 
				
			||||||
	err := library.Load(Tea.Root + "/resources/ipdata/ip2region/ip2region.db")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	result, err := library.Lookup("114.240.223.47")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	logs.PrintAsJSON(result, t)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestIP2RegionLibrary_Lookup_Valid_IP(t *testing.T) {
 | 
					 | 
				
			||||||
	library := &IP2RegionLibrary{}
 | 
					 | 
				
			||||||
	err := library.Load(Tea.Root + "/resources/ipdata/ip2region/ip2region.db")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		result, err := library.Lookup("114.240.223")
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			t.Fatal(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		logs.PrintAsJSON(result, t)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		result, err := library.Lookup("abc")
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			t.Fatal(err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		logs.PrintAsJSON(result, t)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestIP2RegionLibrary_Memory(t *testing.T) {
 | 
					 | 
				
			||||||
	library := &IP2RegionLibrary{}
 | 
					 | 
				
			||||||
	err := library.Load(Tea.Root + "/resources/ipdata/ip2region/ip2region.db")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	before := time.Now()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i := 0; i < 1_000_000; i++ {
 | 
					 | 
				
			||||||
		_, _ = library.Lookup(strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	t.Log("cost:", time.Since(before).Seconds()*1000, "ms")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func BenchmarkIP2RegionLibrary_Lookup(b *testing.B) {
 | 
					 | 
				
			||||||
	runtime.GOMAXPROCS(1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	library := &IP2RegionLibrary{}
 | 
					 | 
				
			||||||
	err := library.Load(Tea.Root + "/resources/ipdata/ip2region/ip2region.db")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		b.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for i := 0; i < b.N; i++ {
 | 
					 | 
				
			||||||
		_, _ = library.Lookup(strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)) + "." + strconv.Itoa(rands.Int(0, 254)))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,90 +0,0 @@
 | 
				
			|||||||
package iplibrary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/db/models"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/errors"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/dbs"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/files"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/logs"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/types"
 | 
					 | 
				
			||||||
	"regexp"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var SharedManager = NewManager()
 | 
					 | 
				
			||||||
var SharedLibrary LibraryInterface
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
	dbs.OnReady(func() {
 | 
					 | 
				
			||||||
		// 初始化
 | 
					 | 
				
			||||||
		library, err := SharedManager.Load()
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			logs.Println("[IP_LIBRARY]" + err.Error())
 | 
					 | 
				
			||||||
			return
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		SharedLibrary = library
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Manager struct {
 | 
					 | 
				
			||||||
	code string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func NewManager() *Manager {
 | 
					 | 
				
			||||||
	return &Manager{}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (this *Manager) Load() (LibraryInterface, error) {
 | 
					 | 
				
			||||||
	// 当前正在使用的IP库代号
 | 
					 | 
				
			||||||
	config, err := models.SharedSysSettingDAO.ReadGlobalConfig(nil)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	code := config.IPLibrary.Code
 | 
					 | 
				
			||||||
	if len(code) == 0 {
 | 
					 | 
				
			||||||
		code = serverconfigs.DefaultIPLibraryType
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	dir := Tea.Root + "/resources/ipdata/" + code
 | 
					 | 
				
			||||||
	var lastVersion int64 = -1
 | 
					 | 
				
			||||||
	lastFilename := ""
 | 
					 | 
				
			||||||
	for _, file := range files.NewFile(dir).List() {
 | 
					 | 
				
			||||||
		filename := file.Name()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		reg := regexp.MustCompile(`^` + regexp.QuoteMeta(code) + `.(\d+)\.`)
 | 
					 | 
				
			||||||
		if reg.MatchString(filename) { // 先查找有版本号的
 | 
					 | 
				
			||||||
			result := reg.FindStringSubmatch(filename)
 | 
					 | 
				
			||||||
			version := types.Int64(result[1])
 | 
					 | 
				
			||||||
			if version > lastVersion {
 | 
					 | 
				
			||||||
				lastVersion = version
 | 
					 | 
				
			||||||
				lastFilename = filename
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else if strings.HasPrefix(filename, code+".") { // 后查找默认的
 | 
					 | 
				
			||||||
			if lastVersion == -1 {
 | 
					 | 
				
			||||||
				lastFilename = filename
 | 
					 | 
				
			||||||
				lastVersion = 0
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if len(lastFilename) == 0 {
 | 
					 | 
				
			||||||
		return nil, errors.New("ip library file not found")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var libraryPtr LibraryInterface
 | 
					 | 
				
			||||||
	switch code {
 | 
					 | 
				
			||||||
	case serverconfigs.IPLibraryTypeIP2Region:
 | 
					 | 
				
			||||||
		libraryPtr = &IP2RegionLibrary{}
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return nil, errors.New("invalid ip library code '" + code + "'")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = libraryPtr.Load(dir + "/" + lastFilename)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return libraryPtr, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
package iplibrary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	_ "github.com/iwind/TeaGo/bootstrap"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/dbs"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestManager_Load(t *testing.T) {
 | 
					 | 
				
			||||||
	dbs.NotifyReady()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	manager := NewManager()
 | 
					 | 
				
			||||||
	lib, err := manager.Load()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	t.Log(lib.Lookup("1.2.3.4"))
 | 
					 | 
				
			||||||
	t.Log(lib.Lookup("2.3.4.5"))
 | 
					 | 
				
			||||||
	t.Log(lib.Lookup("200.200.200.200"))
 | 
					 | 
				
			||||||
	t.Log(lib.Lookup("202.106.0.20"))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestNewManager(t *testing.T) {
 | 
					 | 
				
			||||||
	dbs.NotifyReady()
 | 
					 | 
				
			||||||
	t.Log(SharedLibrary)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,29 +0,0 @@
 | 
				
			|||||||
package iplibrary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/lists"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type Result struct {
 | 
					 | 
				
			||||||
	CityId   int64
 | 
					 | 
				
			||||||
	Country  string
 | 
					 | 
				
			||||||
	Region   string
 | 
					 | 
				
			||||||
	Province string
 | 
					 | 
				
			||||||
	City     string
 | 
					 | 
				
			||||||
	ISP      string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (this *Result) Summary() string {
 | 
					 | 
				
			||||||
	pieces := []string{}
 | 
					 | 
				
			||||||
	if len(this.Country) > 0 {
 | 
					 | 
				
			||||||
		pieces = append(pieces, this.Country)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(this.Province) > 0 && !lists.ContainsString(pieces, this.Province) {
 | 
					 | 
				
			||||||
		pieces = append(pieces, this.Province)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(this.City) > 0 && !lists.ContainsString(pieces, this.City) && !lists.ContainsString(pieces, strings.TrimSuffix(this.City, "市")) {
 | 
					 | 
				
			||||||
		pieces = append(pieces, this.City)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return strings.Join(pieces, " ")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,125 +0,0 @@
 | 
				
			|||||||
package iplibrary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/db/models"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/errors"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/goman"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/Tea"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/dbs"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/logs"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func init() {
 | 
					 | 
				
			||||||
	dbs.OnReady(func() {
 | 
					 | 
				
			||||||
		updater := NewUpdater()
 | 
					 | 
				
			||||||
		updater.Start()
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Updater IP库更新程序
 | 
					 | 
				
			||||||
type Updater struct {
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NewUpdater 获取新对象
 | 
					 | 
				
			||||||
func NewUpdater() *Updater {
 | 
					 | 
				
			||||||
	return &Updater{}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Start 开始更新
 | 
					 | 
				
			||||||
func (this *Updater) Start() {
 | 
					 | 
				
			||||||
	// 这里不需要太频繁检查更新,因为通常不需要更新IP库
 | 
					 | 
				
			||||||
	ticker := time.NewTicker(1 * time.Hour)
 | 
					 | 
				
			||||||
	goman.New(func() {
 | 
					 | 
				
			||||||
		for range ticker.C {
 | 
					 | 
				
			||||||
			err := this.loop()
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				logs.Println("[IP_LIBRARY]" + err.Error())
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// 单次任务
 | 
					 | 
				
			||||||
func (this *Updater) loop() error {
 | 
					 | 
				
			||||||
	config, err := models.SharedSysSettingDAO.ReadGlobalConfig(nil)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	code := config.IPLibrary.Code
 | 
					 | 
				
			||||||
	if len(code) == 0 {
 | 
					 | 
				
			||||||
		code = serverconfigs.DefaultIPLibraryType
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	lib, err := models.SharedIPLibraryDAO.FindLatestIPLibraryWithType(nil, code)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if lib == nil {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	typeInfo := serverconfigs.FindIPLibraryWithType(code)
 | 
					 | 
				
			||||||
	if typeInfo == nil {
 | 
					 | 
				
			||||||
		return errors.New("invalid ip library code '" + code + "'")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	path := Tea.Root + "/resources/ipdata/" + code + "/" + code + "." + fmt.Sprintf("%d", lib.CreatedAt) + typeInfo.GetString("ext")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 是否已经存在
 | 
					 | 
				
			||||||
	_, err = os.Stat(path)
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 开始下载
 | 
					 | 
				
			||||||
	chunkIds, err := models.SharedFileChunkDAO.FindAllFileChunkIds(nil, int64(lib.FileId))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	isOk := false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fp, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0666)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		// 如果保存不成功就直接删除
 | 
					 | 
				
			||||||
		if !isOk {
 | 
					 | 
				
			||||||
			_ = fp.Close()
 | 
					 | 
				
			||||||
			_ = os.Remove(path)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	for _, chunkId := range chunkIds {
 | 
					 | 
				
			||||||
		chunk, err := models.SharedFileChunkDAO.FindFileChunk(nil, chunkId)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if chunk == nil {
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		_, err = fp.Write(chunk.Data)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err = fp.Close()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 重新加载
 | 
					 | 
				
			||||||
	library, err := SharedManager.Load()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	SharedLibrary = library
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	isOk = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
package iplibrary
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	_ "github.com/iwind/TeaGo/bootstrap"
 | 
					 | 
				
			||||||
	"github.com/iwind/TeaGo/dbs"
 | 
					 | 
				
			||||||
	"testing"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestUpdater_loop(t *testing.T) {
 | 
					 | 
				
			||||||
	dbs.NotifyReady()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	updater := NewUpdater()
 | 
					 | 
				
			||||||
	err := updater.loop()
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	t.Log("ok")
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -4,10 +4,9 @@ import (
 | 
				
			|||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/db/models"
 | 
						"github.com/TeaOSLab/EdgeAPI/internal/db/models"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/db/models/regions"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/errors"
 | 
						"github.com/TeaOSLab/EdgeAPI/internal/errors"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/iplibrary"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/utils"
 | 
						"github.com/TeaOSLab/EdgeAPI/internal/utils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
 | 
				
			||||||
	"github.com/iwind/TeaGo/lists"
 | 
						"github.com/iwind/TeaGo/lists"
 | 
				
			||||||
@@ -794,20 +793,14 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// 检查封禁的地区和省份
 | 
						// 检查封禁的地区和省份
 | 
				
			||||||
	info, err := iplibrary.SharedLibrary.Lookup(req.Ip)
 | 
						var info = iplibrary.LookupIP(req.Ip)
 | 
				
			||||||
	if err != nil {
 | 
						if info != nil && info.IsOk() {
 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if info != nil {
 | 
					 | 
				
			||||||
		if firewallPolicy.Inbound != nil &&
 | 
							if firewallPolicy.Inbound != nil &&
 | 
				
			||||||
			firewallPolicy.Inbound.IsOn &&
 | 
								firewallPolicy.Inbound.IsOn &&
 | 
				
			||||||
			firewallPolicy.Inbound.Region != nil &&
 | 
								firewallPolicy.Inbound.Region != nil &&
 | 
				
			||||||
			firewallPolicy.Inbound.Region.IsOn {
 | 
								firewallPolicy.Inbound.Region.IsOn {
 | 
				
			||||||
			// 检查封禁的地区
 | 
								// 检查封禁的地区
 | 
				
			||||||
			countryId, err := regions.SharedRegionCountryDAO.FindCountryIdWithNameCacheable(tx, info.Country)
 | 
								var countryId = info.CountryId()
 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if countryId > 0 && lists.ContainsInt64(firewallPolicy.Inbound.Region.DenyCountryIds, countryId) {
 | 
								if countryId > 0 && lists.ContainsInt64(firewallPolicy.Inbound.Region.DenyCountryIds, countryId) {
 | 
				
			||||||
				return &pb.CheckHTTPFirewallPolicyIPStatusResponse{
 | 
									return &pb.CheckHTTPFirewallPolicyIPStatusResponse{
 | 
				
			||||||
					IsOk:      true,
 | 
										IsOk:      true,
 | 
				
			||||||
@@ -818,7 +811,7 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
 | 
				
			|||||||
					IpItem:    nil,
 | 
										IpItem:    nil,
 | 
				
			||||||
					RegionCountry: &pb.RegionCountry{
 | 
										RegionCountry: &pb.RegionCountry{
 | 
				
			||||||
						Id:   countryId,
 | 
											Id:   countryId,
 | 
				
			||||||
						Name: info.Country,
 | 
											Name: info.CountryName(),
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
					RegionProvince: nil,
 | 
										RegionProvince: nil,
 | 
				
			||||||
				}, nil
 | 
									}, nil
 | 
				
			||||||
@@ -826,10 +819,7 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			// 检查封禁的省份
 | 
								// 检查封禁的省份
 | 
				
			||||||
			if countryId > 0 {
 | 
								if countryId > 0 {
 | 
				
			||||||
				provinceId, err := regions.SharedRegionProvinceDAO.FindProvinceIdWithNameCacheable(tx, countryId, info.Province)
 | 
									var provinceId = info.ProvinceId()
 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					return nil, err
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if provinceId > 0 && lists.ContainsInt64(firewallPolicy.Inbound.Region.DenyProvinceIds, provinceId) {
 | 
									if provinceId > 0 && lists.ContainsInt64(firewallPolicy.Inbound.Region.DenyProvinceIds, provinceId) {
 | 
				
			||||||
					return &pb.CheckHTTPFirewallPolicyIPStatusResponse{
 | 
										return &pb.CheckHTTPFirewallPolicyIPStatusResponse{
 | 
				
			||||||
						IsOk:      true,
 | 
											IsOk:      true,
 | 
				
			||||||
@@ -840,11 +830,11 @@ func (this *HTTPFirewallPolicyService) CheckHTTPFirewallPolicyIPStatus(ctx conte
 | 
				
			|||||||
						IpItem:    nil,
 | 
											IpItem:    nil,
 | 
				
			||||||
						RegionCountry: &pb.RegionCountry{
 | 
											RegionCountry: &pb.RegionCountry{
 | 
				
			||||||
							Id:   countryId,
 | 
												Id:   countryId,
 | 
				
			||||||
							Name: info.Country,
 | 
												Name: info.CountryName(),
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
						RegionProvince: &pb.RegionProvince{
 | 
											RegionProvince: &pb.RegionProvince{
 | 
				
			||||||
							Id:   provinceId,
 | 
												Id:   provinceId,
 | 
				
			||||||
							Name: info.Province,
 | 
												Name: info.ProvinceName(),
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
					}, nil
 | 
										}, nil
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,9 +3,8 @@ package services
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/db/models"
 | 
						"github.com/TeaOSLab/EdgeAPI/internal/db/models"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/db/models/regions"
 | 
					 | 
				
			||||||
	"github.com/TeaOSLab/EdgeAPI/internal/iplibrary"
 | 
					 | 
				
			||||||
	rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
 | 
						rpcutils "github.com/TeaOSLab/EdgeAPI/internal/rpc/utils"
 | 
				
			||||||
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
 | 
				
			||||||
	"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
						"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -183,34 +182,19 @@ func (this *IPLibraryService) LookupIPRegion(ctx context.Context, req *pb.Lookup
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result, err := iplibrary.SharedLibrary.Lookup(req.Ip)
 | 
						var result = iplibrary.LookupIP(req.Ip)
 | 
				
			||||||
	if err != nil {
 | 
						if result == nil || !result.IsOk() {
 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if result == nil {
 | 
					 | 
				
			||||||
		return &pb.LookupIPRegionResponse{IpRegion: nil}, nil
 | 
							return &pb.LookupIPRegionResponse{IpRegion: nil}, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var tx = this.NullTx()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	countryId, err := regions.SharedRegionCountryDAO.FindCountryIdWithNameCacheable(tx, result.Country)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	provinceId, err := regions.SharedRegionProvinceDAO.FindProvinceIdWithNameCacheable(tx, countryId, result.Province)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &pb.LookupIPRegionResponse{IpRegion: &pb.IPRegion{
 | 
						return &pb.LookupIPRegionResponse{IpRegion: &pb.IPRegion{
 | 
				
			||||||
		Country:    result.Country,
 | 
							Country:    result.CountryName(),
 | 
				
			||||||
		Region:     result.Region,
 | 
							Region:     "",
 | 
				
			||||||
		Province:   result.Province,
 | 
							Province:   result.ProvinceName(),
 | 
				
			||||||
		City:       result.City,
 | 
							City:       result.CityName(),
 | 
				
			||||||
		Isp:        result.ISP,
 | 
							Isp:        result.ProviderName(),
 | 
				
			||||||
		CountryId:  countryId,
 | 
							CountryId:  result.CountryId(),
 | 
				
			||||||
		ProvinceId: provinceId,
 | 
							ProvinceId: result.ProvinceId(),
 | 
				
			||||||
		Summary:    result.Summary(),
 | 
							Summary:    result.Summary(),
 | 
				
			||||||
	}}, nil
 | 
						}}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -223,20 +207,17 @@ func (this *IPLibraryService) LookupIPRegions(ctx context.Context, req *pb.Looku
 | 
				
			|||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result := map[string]*pb.IPRegion{}
 | 
						var result = map[string]*pb.IPRegion{}
 | 
				
			||||||
	if len(req.IpList) > 0 {
 | 
						if len(req.IpList) > 0 {
 | 
				
			||||||
		for _, ip := range req.IpList {
 | 
							for _, ip := range req.IpList {
 | 
				
			||||||
			info, err := iplibrary.SharedLibrary.Lookup(ip)
 | 
								var info = iplibrary.LookupIP(ip)
 | 
				
			||||||
			if err != nil {
 | 
								if info != nil && info.IsOk() {
 | 
				
			||||||
				return nil, err
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if info != nil {
 | 
					 | 
				
			||||||
				result[ip] = &pb.IPRegion{
 | 
									result[ip] = &pb.IPRegion{
 | 
				
			||||||
					Country:  info.Country,
 | 
										Country:  info.CountryName(),
 | 
				
			||||||
					Region:   info.Region,
 | 
										Region:   "",
 | 
				
			||||||
					Province: info.Province,
 | 
										Province: info.ProvinceName(),
 | 
				
			||||||
					City:     info.City,
 | 
										City:     info.CityName(),
 | 
				
			||||||
					Isp:      info.ISP,
 | 
										Isp:      info.ProviderName(),
 | 
				
			||||||
					Summary:  info.Summary(),
 | 
										Summary:  info.Summary(),
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,71 @@ type IPLibraryFileService struct {
 | 
				
			|||||||
	BaseService
 | 
						BaseService
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FindAllFinishedIPLibraryFiles 查找所有已完成的IP库文件
 | 
				
			||||||
 | 
					func (this *IPLibraryFileService) FindAllFinishedIPLibraryFiles(ctx context.Context, req *pb.FindAllFinishedIPLibraryFilesRequest) (*pb.FindAllFinishedIPLibraryFilesResponse, error) {
 | 
				
			||||||
 | 
						_, err := this.ValidateAdmin(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var tx = this.NullTx()
 | 
				
			||||||
 | 
						libraryFiles, err := models.SharedIPLibraryFileDAO.FindAllFinishedLibraryFiles(tx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var pbLibraryFiles = []*pb.IPLibraryFile{}
 | 
				
			||||||
 | 
						for _, libraryFile := range libraryFiles {
 | 
				
			||||||
 | 
							var pbCountryNames = libraryFile.DecodeCountries()
 | 
				
			||||||
 | 
							var pbProviderNames = libraryFile.DecodeProviders()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var pbProvinces = []*pb.IPLibraryFile_Province{}
 | 
				
			||||||
 | 
							for _, province := range libraryFile.DecodeProvinces() {
 | 
				
			||||||
 | 
								pbProvinces = append(pbProvinces, &pb.IPLibraryFile_Province{
 | 
				
			||||||
 | 
									CountryName:  province[0],
 | 
				
			||||||
 | 
									ProvinceName: province[1],
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var pbCities = []*pb.IPLibraryFile_City{}
 | 
				
			||||||
 | 
							for _, city := range libraryFile.DecodeCities() {
 | 
				
			||||||
 | 
								pbCities = append(pbCities, &pb.IPLibraryFile_City{
 | 
				
			||||||
 | 
									CountryName:  city[0],
 | 
				
			||||||
 | 
									ProvinceName: city[1],
 | 
				
			||||||
 | 
									CityName:     city[2],
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var pbTowns = []*pb.IPLibraryFile_Town{}
 | 
				
			||||||
 | 
							for _, town := range libraryFile.DecodeTowns() {
 | 
				
			||||||
 | 
								pbTowns = append(pbTowns, &pb.IPLibraryFile_Town{
 | 
				
			||||||
 | 
									CountryName:  town[0],
 | 
				
			||||||
 | 
									ProvinceName: town[1],
 | 
				
			||||||
 | 
									CityName:     town[2],
 | 
				
			||||||
 | 
									TownName:     town[3],
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pbLibraryFiles = append(pbLibraryFiles, &pb.IPLibraryFile{
 | 
				
			||||||
 | 
								Id:              int64(libraryFile.Id),
 | 
				
			||||||
 | 
								Name:            libraryFile.Name,
 | 
				
			||||||
 | 
								FileId:          int64(libraryFile.FileId),
 | 
				
			||||||
 | 
								IsFinished:      libraryFile.IsFinished,
 | 
				
			||||||
 | 
								CreatedAt:       int64(libraryFile.CreatedAt),
 | 
				
			||||||
 | 
								GeneratedFileId: int64(libraryFile.GeneratedFileId),
 | 
				
			||||||
 | 
								GeneratedAt:     int64(libraryFile.GeneratedAt),
 | 
				
			||||||
 | 
								CountryNames:    pbCountryNames,
 | 
				
			||||||
 | 
								Provinces:       pbProvinces,
 | 
				
			||||||
 | 
								Cities:          pbCities,
 | 
				
			||||||
 | 
								Towns:           pbTowns,
 | 
				
			||||||
 | 
								ProviderNames:   pbProviderNames,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &pb.FindAllFinishedIPLibraryFilesResponse{
 | 
				
			||||||
 | 
							IpLibraryFiles: pbLibraryFiles,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FindAllUnfinishedIPLibraryFiles 查找所有未完成的IP库文件
 | 
					// FindAllUnfinishedIPLibraryFiles 查找所有未完成的IP库文件
 | 
				
			||||||
func (this *IPLibraryFileService) FindAllUnfinishedIPLibraryFiles(ctx context.Context, req *pb.FindAllUnfinishedIPLibraryFilesRequest) (*pb.FindAllUnfinishedIPLibraryFilesResponse, error) {
 | 
					func (this *IPLibraryFileService) FindAllUnfinishedIPLibraryFiles(ctx context.Context, req *pb.FindAllUnfinishedIPLibraryFilesRequest) (*pb.FindAllUnfinishedIPLibraryFilesResponse, error) {
 | 
				
			||||||
	_, err := this.ValidateAdmin(ctx)
 | 
						_, err := this.ValidateAdmin(ctx)
 | 
				
			||||||
@@ -64,6 +129,7 @@ func (this *IPLibraryFileService) FindAllUnfinishedIPLibraryFiles(ctx context.Co
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		pbLibraryFiles = append(pbLibraryFiles, &pb.IPLibraryFile{
 | 
							pbLibraryFiles = append(pbLibraryFiles, &pb.IPLibraryFile{
 | 
				
			||||||
			Id:            int64(libraryFile.Id),
 | 
								Id:            int64(libraryFile.Id),
 | 
				
			||||||
 | 
								Name:          libraryFile.Name,
 | 
				
			||||||
			FileId:        int64(libraryFile.FileId),
 | 
								FileId:        int64(libraryFile.FileId),
 | 
				
			||||||
			IsFinished:    libraryFile.IsFinished,
 | 
								IsFinished:    libraryFile.IsFinished,
 | 
				
			||||||
			CreatedAt:     int64(libraryFile.CreatedAt),
 | 
								CreatedAt:     int64(libraryFile.CreatedAt),
 | 
				
			||||||
@@ -131,9 +197,13 @@ func (this *IPLibraryFileService) FindIPLibraryFile(ctx context.Context, req *pb
 | 
				
			|||||||
	return &pb.FindIPLibraryFileResponse{
 | 
						return &pb.FindIPLibraryFileResponse{
 | 
				
			||||||
		IpLibraryFile: &pb.IPLibraryFile{
 | 
							IpLibraryFile: &pb.IPLibraryFile{
 | 
				
			||||||
			Id:              int64(libraryFile.Id),
 | 
								Id:              int64(libraryFile.Id),
 | 
				
			||||||
 | 
								Name:            libraryFile.Name,
 | 
				
			||||||
 | 
								Template:        libraryFile.Template,
 | 
				
			||||||
 | 
								EmptyValues:     libraryFile.DecodeEmptyValues(),
 | 
				
			||||||
			FileId:          int64(libraryFile.FileId),
 | 
								FileId:          int64(libraryFile.FileId),
 | 
				
			||||||
			IsFinished:      libraryFile.IsFinished,
 | 
								IsFinished:      libraryFile.IsFinished,
 | 
				
			||||||
			CreatedAt:       int64(libraryFile.CreatedAt),
 | 
								CreatedAt:       int64(libraryFile.CreatedAt),
 | 
				
			||||||
 | 
								GeneratedFileId: int64(libraryFile.GeneratedFileId),
 | 
				
			||||||
			CountryNames:    pbCountryNames,
 | 
								CountryNames:    pbCountryNames,
 | 
				
			||||||
			Provinces:       pbProvinces,
 | 
								Provinces:       pbProvinces,
 | 
				
			||||||
			Cities:          pbCities,
 | 
								Cities:          pbCities,
 | 
				
			||||||
@@ -182,7 +252,7 @@ func (this *IPLibraryFileService) CreateIPLibraryFile(ctx context.Context, req *
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var tx = this.NullTx()
 | 
						var tx = this.NullTx()
 | 
				
			||||||
	libraryFileId, err := models.SharedIPLibraryFileDAO.CreateLibraryFile(tx, req.Template, req.EmptyValues, req.FileId, countries, provinces, cities, towns, providers)
 | 
						libraryFileId, err := models.SharedIPLibraryFileDAO.CreateLibraryFile(tx, req.Name, req.Template, req.EmptyValues, req.FileId, countries, provinces, cities, towns, providers)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -481,6 +551,9 @@ func (this *IPLibraryFileService) CheckTownsWithIPLibraryFileId(ctx context.Cont
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			cityMap[cityKey] = cityId
 | 
								cityMap[cityKey] = cityId
 | 
				
			||||||
 | 
								if cityId > 0 {
 | 
				
			||||||
 | 
									cityIds = append(cityIds, cityId)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// town
 | 
							// town
 | 
				
			||||||
@@ -607,3 +680,34 @@ func (this *IPLibraryFileService) GenerateIPLibraryFile(ctx context.Context, req
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return this.Success()
 | 
						return this.Success()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// UpdateIPLibraryFileFinished 设置某个IP库为已完成
 | 
				
			||||||
 | 
					func (this *IPLibraryFileService) UpdateIPLibraryFileFinished(ctx context.Context, req *pb.UpdateIPLibraryFileFinishedRequest) (*pb.RPCSuccess, error) {
 | 
				
			||||||
 | 
						_, err := this.ValidateAdmin(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var tx = this.NullTx()
 | 
				
			||||||
 | 
						err = models.SharedIPLibraryFileDAO.UpdateLibraryFileIsFinished(tx, req.IpLibraryFileId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DeleteIPLibraryFile 删除IP库文件
 | 
				
			||||||
 | 
					func (this *IPLibraryFileService) DeleteIPLibraryFile(ctx context.Context, req *pb.DeleteIPLibraryFileRequest) (*pb.RPCSuccess, error) {
 | 
				
			||||||
 | 
						_, err := this.ValidateAdmin(ctx)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var tx = this.NullTx()
 | 
				
			||||||
 | 
						err = models.SharedIPLibraryFileDAO.DisableIPLibraryFile(tx, req.IpLibraryFileId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return this.Success()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Reference in New Issue
	
	Block a user