mirror of
https://github.com/zu1k/nali.git
synced 2025-01-22 13:19:02 +08:00
add cdn parse
This commit is contained in:
parent
250d90ee24
commit
87071a4244
47
cmd/cdn.go
Normal file
47
cmd/cdn.go
Normal file
@ -0,0 +1,47 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/zu1k/nali/internal/app"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// cdnCmd represents the cdn command
|
||||
var cdnCmd = &cobra.Command{
|
||||
Use: "cdn",
|
||||
Short: "Query cdn service provider",
|
||||
Long: `Query cdn service provider`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if update {
|
||||
app.UpdateDB()
|
||||
}
|
||||
|
||||
app.InitCDNDB()
|
||||
|
||||
if len(args) == 0 {
|
||||
stdin := bufio.NewScanner(os.Stdin)
|
||||
for stdin.Scan() {
|
||||
line := stdin.Text()
|
||||
if line == "quit" || line == "exit" {
|
||||
return
|
||||
}
|
||||
fmt.Println(app.ReplaceCDNInString(line))
|
||||
}
|
||||
} else {
|
||||
app.ParseCDNs(args)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var (
|
||||
update = false
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(cdnCmd)
|
||||
cdnCmd.Flags().BoolVarP(&update, "update", "u", false, "Update CDN database")
|
||||
}
|
93
internal/app/cdn.go
Normal file
93
internal/app/cdn.go
Normal file
@ -0,0 +1,93 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/zu1k/nali/constant"
|
||||
|
||||
"github.com/zu1k/nali/pkg/cdn"
|
||||
)
|
||||
|
||||
var (
|
||||
cdnDB cdn.CDN
|
||||
domainRe *regexp.Regexp
|
||||
)
|
||||
|
||||
func init() {
|
||||
domainRe = regexp.MustCompile(`[0-9A-Za-z]{2,}\.[0-9A-Za-z]{2,3}\.[0-9A-Za-z]{2,3}|[0-9A-Za-z]{2,}\.[0-9A-Za-z]{2,3}`)
|
||||
}
|
||||
|
||||
func InitCDNDB() {
|
||||
cdnDB = cdn.NewCDN(filepath.Join(constant.HomePath, "cdn.json"))
|
||||
}
|
||||
|
||||
func ParseCDNs(str []string) {
|
||||
for _, cname := range str {
|
||||
name := find(cname)
|
||||
fmt.Printf("%s [%s]\n", cname, name)
|
||||
}
|
||||
}
|
||||
|
||||
func find(cname string) string {
|
||||
baseCname := parseBaseCname(cname)
|
||||
if baseCname == "" {
|
||||
return "无法解析"
|
||||
}
|
||||
cdnResult, found := cdnDB.Data[baseCname]
|
||||
if found {
|
||||
return cdnResult.Name
|
||||
}
|
||||
return "未找到"
|
||||
}
|
||||
|
||||
func ReplaceCDNInString(str string) (result string) {
|
||||
cnames := domainRe.FindAllString(str, -1)
|
||||
result = str
|
||||
for _, cname := range cnames {
|
||||
name := find(cname)
|
||||
if name != "未找到" && name != "无法解析" {
|
||||
result = strings.ReplaceAll(result, cname, fmt.Sprintf("%s [%s]", cname, name))
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseBaseCname(domain string) string {
|
||||
hostParts := strings.Split(domain, ".")
|
||||
if len(hostParts) < 2 {
|
||||
return domain
|
||||
}
|
||||
baseCname := hostParts[len(hostParts)-2] + "." + hostParts[len(hostParts)-1]
|
||||
return baseCname
|
||||
}
|
||||
|
||||
func UpdateDB() {
|
||||
filePath := filepath.Join(constant.HomePath, "cdn.json")
|
||||
|
||||
log.Println("正在下载最新 CDN数据库...")
|
||||
tmpData, err := cdn.Download()
|
||||
if err != nil {
|
||||
log.Fatalln("下载失败", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 文件存在就删除
|
||||
_, err = os.Stat(filePath)
|
||||
if err == nil {
|
||||
err = os.Remove(filePath)
|
||||
if err != nil {
|
||||
log.Fatalln("旧文件删除失败", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(filePath, tmpData, 0644); err == nil {
|
||||
log.Printf("已将最新的CDN数据库保存到本地 %s ", filePath)
|
||||
}
|
||||
}
|
56
pkg/cdn/cdn.go
Normal file
56
pkg/cdn/cdn.go
Normal file
@ -0,0 +1,56 @@
|
||||
package cdn
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
type CDN struct {
|
||||
Data CDNDist
|
||||
}
|
||||
|
||||
type CDNDist map[string]CDNResult
|
||||
|
||||
type CDNResult struct {
|
||||
Name string `json:"name"`
|
||||
Link string `json:"link"`
|
||||
}
|
||||
|
||||
func NewCDN(filePath string) CDN {
|
||||
cdnDist := make(CDNDist)
|
||||
cdnData := make([]byte, 0)
|
||||
|
||||
// 判断文件是否存在
|
||||
_, err := os.Stat(filePath)
|
||||
if err != nil && os.IsNotExist(err) {
|
||||
log.Println("文件不存在,尝试从网络获取最新CDN数据库")
|
||||
cdnData, err = Download()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
} else {
|
||||
if err := ioutil.WriteFile(filePath, cdnData, 0644); err == nil {
|
||||
log.Printf("已将最新的 CDN数据库 保存到本地: %s ", filePath)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 打开文件句柄
|
||||
cdnFile, err := os.OpenFile(filePath, os.O_RDONLY, 0400)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer cdnFile.Close()
|
||||
|
||||
cdnData, err = ioutil.ReadAll(cdnFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
err = json.Unmarshal(cdnData, &cdnDist)
|
||||
if err != nil {
|
||||
panic("cdn data parse failed!")
|
||||
}
|
||||
return CDN{Data: cdnDist}
|
||||
}
|
21
pkg/cdn/update.go
Normal file
21
pkg/cdn/update.go
Normal file
@ -0,0 +1,21 @@
|
||||
package cdn
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func Download() (data []byte, err error) {
|
||||
//resp, err := http.Get("https://raw.githubusercontent.com/SukkaLab/cdn/master/dist/cdn.json")
|
||||
resp, err := http.Get("https://cdn.jsdelivr.net/gh/SukkaLab/cdn/dist/cdn.json")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return body, nil
|
||||
}
|
@ -2,8 +2,8 @@ package common
|
||||
|
||||
import "os"
|
||||
|
||||
// FileInfo: info of db file
|
||||
type FileInfo struct {
|
||||
// FileData: info of db file
|
||||
type FileData struct {
|
||||
Data []byte
|
||||
FilePath string
|
||||
FileBase *os.File
|
||||
@ -11,7 +11,7 @@ type FileInfo struct {
|
||||
|
||||
// IPDB common ip database
|
||||
type IPDB struct {
|
||||
Data *FileInfo
|
||||
Data *FileData
|
||||
Offset uint32
|
||||
ItemLen uint32
|
||||
IndexLen uint32
|
||||
|
@ -20,7 +20,7 @@ type QQwry struct {
|
||||
// NewQQwry new db from path
|
||||
func NewQQwry(filePath string) QQwry {
|
||||
var fileData []byte
|
||||
var fileInfo common.FileInfo
|
||||
var fileInfo common.FileData
|
||||
|
||||
// 判断文件是否存在
|
||||
_, err := os.Stat(filePath)
|
||||
|
@ -18,7 +18,7 @@ type ZXwry struct {
|
||||
|
||||
func NewZXwry(filePath string) ZXwry {
|
||||
var tmpData []byte
|
||||
var fileInfo common.FileInfo
|
||||
var fileInfo common.FileData
|
||||
|
||||
// 判断文件是否存在
|
||||
_, err := os.Stat(filePath)
|
||||
|
Loading…
Reference in New Issue
Block a user