Initial commit (code only without large binaries)

This commit is contained in:
robin
2026-02-15 18:58:44 +08:00
commit 35df75498f
9442 changed files with 1495866 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package library
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/types"
)
type DownloadAction struct {
actionutils.ParentAction
}
func (this *DownloadAction) Init() {
this.Nav("", "", "")
}
func (this *DownloadAction) RunGet(params struct {
LibraryFileId int64
}) {
libraryResp, err := this.RPC().IPLibraryFileRPC().FindIPLibraryFile(this.AdminContext(), &pb.FindIPLibraryFileRequest{IpLibraryFileId: params.LibraryFileId})
if err != nil {
this.ErrorPage(err)
return
}
var library = libraryResp.IpLibraryFile
if library == nil {
this.NotFound("IPLibraryFile", params.LibraryFileId)
return
}
var fileId = library.GeneratedFileId
if fileId <= 0 {
this.WriteString("ip library file not generated")
return
}
fileResp, err := this.RPC().FileRPC().FindEnabledFile(this.AdminContext(), &pb.FindEnabledFileRequest{FileId: fileId})
if err != nil {
this.ErrorPage(err)
return
}
var file = fileResp.File
if file == nil {
this.WriteString("file not found")
return
}
chunkIdsResp, err := this.RPC().FileChunkRPC().FindAllFileChunkIds(this.AdminContext(), &pb.FindAllFileChunkIdsRequest{FileId: file.Id})
if err != nil {
this.ErrorPage(err)
return
}
this.AddHeader("Content-Disposition", "attachment; filename=\"ip-library.db\";")
this.AddHeader("Content-Length", types.String(file.Size))
for _, chunkId := range chunkIdsResp.FileChunkIds {
chunkResp, err := this.RPC().FileChunkRPC().DownloadFileChunk(this.AdminContext(), &pb.DownloadFileChunkRequest{FileChunkId: chunkId})
if err != nil {
this.ErrorPage(err)
return
}
var chunk = chunkResp.FileChunk
if chunk == nil {
break
}
_, _ = this.Write(chunkResp.FileChunk.Data)
}
this.Show()
}

View File

@@ -0,0 +1,18 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package library
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "", "")
}
func (this *IndexAction) RunGet(params struct{}) {
// TODO
this.Show()
}

View File

@@ -0,0 +1,157 @@
// Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
package library
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/iplibrary"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/actions"
"github.com/iwind/TeaGo/logs"
"github.com/iwind/TeaGo/maps"
"os"
)
type TestAction struct {
actionutils.ParentAction
}
func (this *TestAction) Init() {
this.Nav("", "ipLibrary", "test")
}
func (this *TestAction) RunGet(params struct{}) {
// 通过 RPC 查询 EdgeAPI 的 MaxMind 文件状态
statusResp, err := this.RPC().IPLibraryRPC().FindMaxMindFileStatus(this.AdminContext(), &pb.FindMaxMindFileStatusRequest{})
if err != nil {
// RPC 调用失败,记录错误并使用本地检查作为后备
logs.Println("[IP_LIBRARY_TEST]RPC call failed: " + err.Error())
// RPC 调用失败,使用本地检查作为后备
iplibDir := Tea.Root + "/data/iplibrary"
cityDBPath := iplibDir + "/maxmind-city.mmdb"
asnDBPath := iplibDir + "/maxmind-asn.mmdb"
uploadedCityExists := false
uploadedASNExists := false
if _, err := os.Stat(cityDBPath); err == nil {
uploadedCityExists = true
}
if _, err := os.Stat(asnDBPath); err == nil {
uploadedASNExists = true
}
// 检查是否使用了MaxMind库通过测试查询来判断
testIP := "8.8.8.8"
testResult := iplibrary.LookupIP(testIP)
usingMaxMind := false
if testResult != nil && testResult.IsOk() {
if testResult.CountryId() == 0 && len(testResult.CountryName()) > 0 {
usingMaxMind = true
}
}
this.Data["maxMindCityExists"] = uploadedCityExists
this.Data["maxMindASNExists"] = uploadedASNExists
this.Data["usingMaxMind"] = usingMaxMind
this.Data["usingEmbeddedMaxMind"] = usingMaxMind && !uploadedCityExists
} else {
// 使用 RPC 返回的状态
this.Data["maxMindCityExists"] = statusResp.CityExists
this.Data["maxMindASNExists"] = statusResp.AsnExists
this.Data["usingMaxMind"] = statusResp.UsingMaxMind
this.Data["usingEmbeddedMaxMind"] = statusResp.UsingEmbeddedMaxMind
}
this.Show()
}
func (this *TestAction) RunPost(params struct {
Ip string
Must *actions.Must
}) {
if len(params.Ip) == 0 {
this.Fail("请输入IP地址")
return
}
// 查询IP信息
var result = iplibrary.LookupIP(params.Ip)
if result == nil || !result.IsOk() {
this.Data["result"] = maps.Map{
"isOk": false,
"ip": params.Ip,
"error": "未找到该IP的地理位置信息",
}
this.Success()
return
}
// 判断IP库类型
// MaxMind库的特征CountryId 和 ProvinceId 通常为 0因为MaxMind不使用ID系统
// 只要查询结果中CountryId为0且有国家名称就认为是MaxMind不管文件是否存在可能是嵌入的
iplibDir := Tea.Root + "/data/iplibrary"
cityDBPath := iplibDir + "/maxmind-city.mmdb"
var libraryType = "默认IP库"
var libraryVersion = ""
// 如果查询结果中CountryId为0MaxMind特征且有国家名称则认为是MaxMind
// 不管文件是否存在,因为可能是使用嵌入的 MaxMind 库
if result.CountryId() == 0 && len(result.CountryName()) > 0 {
libraryType = "MaxMind GeoIP2"
libraryVersion = "3"
}
// 通过 RPC 查询 EdgeAPI 的 MaxMind 文件状态
statusResp, err := this.RPC().IPLibraryRPC().FindMaxMindFileStatus(this.AdminContext(), &pb.FindMaxMindFileStatusRequest{})
uploadedCityExists := false
uploadedASNExists := false
if err == nil {
uploadedCityExists = statusResp.CityExists
uploadedASNExists = statusResp.AsnExists
} else {
// RPC 调用失败,使用本地检查作为后备
if _, err := os.Stat(cityDBPath); err == nil {
uploadedCityExists = true
}
asnDBPath := iplibDir + "/maxmind-asn.mmdb"
if _, err := os.Stat(asnDBPath); err == nil {
uploadedASNExists = true
}
}
// 判断是否使用了MaxMind库即使没有上传文件也可能使用嵌入的默认MaxMind库
usingMaxMind := false
if result.CountryId() == 0 && len(result.CountryName()) > 0 {
usingMaxMind = true
}
this.Data["result"] = maps.Map{
"isDone": true,
"isOk": true,
"ip": params.Ip,
"libraryType": libraryType,
"libraryVersion": libraryVersion,
"country": result.CountryName(),
"countryId": result.CountryId(),
"province": result.ProvinceName(),
"provinceId": result.ProvinceId(),
"city": result.CityName(),
"cityId": result.CityId(),
"town": result.TownName(),
"townId": result.TownId(),
"provider": result.ProviderName(),
"providerId": result.ProviderId(),
"summary": result.Summary(),
"regionSummary": result.RegionSummary(),
}
this.Data["maxMindCityExists"] = uploadedCityExists
this.Data["maxMindASNExists"] = uploadedASNExists
this.Data["usingMaxMind"] = usingMaxMind
this.Data["usingEmbeddedMaxMind"] = usingMaxMind && !uploadedCityExists
this.Success()
}