1
0
mirror of https://github.com/zu1k/nali.git synced 2025-01-22 21:29:02 +08:00

add cdn parse

This commit is contained in:
zu1k 2020-07-18 14:18:54 +08:00
parent 250d90ee24
commit 87071a4244
7 changed files with 222 additions and 5 deletions

47
cmd/cdn.go Normal file
View 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
View 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
View 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
View 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
}

View File

@ -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

View File

@ -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)

View File

@ -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)