2019-12-18 15:52:31 +08:00
|
|
|
|
package utils
|
|
|
|
|
|
|
|
|
|
import (
|
2021-10-02 00:38:18 +08:00
|
|
|
|
"bufio"
|
2019-12-18 15:52:31 +08:00
|
|
|
|
"bytes"
|
2019-12-27 16:16:10 +08:00
|
|
|
|
"compress/gzip"
|
2019-12-19 17:28:26 +08:00
|
|
|
|
"crypto/md5"
|
2019-12-24 14:56:34 +08:00
|
|
|
|
"crypto/rand"
|
2019-12-19 17:28:26 +08:00
|
|
|
|
"encoding/hex"
|
2020-09-07 15:36:17 +08:00
|
|
|
|
"encoding/json"
|
2019-12-18 15:52:31 +08:00
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
2021-10-02 00:38:18 +08:00
|
|
|
|
"github.com/cnsilvan/UnblockNeteaseMusic/cookiestxt"
|
2021-11-02 17:22:38 +08:00
|
|
|
|
"golang.org/x/text/unicode/norm"
|
2019-12-27 16:16:10 +08:00
|
|
|
|
"io"
|
|
|
|
|
"io/ioutil"
|
2020-09-07 15:36:17 +08:00
|
|
|
|
"log"
|
2021-10-02 00:38:18 +08:00
|
|
|
|
"math"
|
|
|
|
|
"net/http"
|
2019-12-18 15:52:31 +08:00
|
|
|
|
"os"
|
|
|
|
|
"os/exec"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"regexp"
|
2023-09-23 05:18:19 +08:00
|
|
|
|
"runtime/debug"
|
2019-12-24 14:56:34 +08:00
|
|
|
|
"sort"
|
2019-12-18 15:52:31 +08:00
|
|
|
|
"strings"
|
|
|
|
|
|
2020-09-07 15:36:17 +08:00
|
|
|
|
"golang.org/x/text/width"
|
|
|
|
|
)
|
2019-12-18 15:52:31 +08:00
|
|
|
|
|
2019-12-27 16:16:10 +08:00
|
|
|
|
func UnGzipV2(gzipData io.Reader) (io.Reader, error) {
|
|
|
|
|
r, err := gzip.NewReader(gzipData)
|
|
|
|
|
if err != nil {
|
2020-09-07 15:36:17 +08:00
|
|
|
|
log.Println("UnGzipV2 error:", err)
|
2019-12-27 16:16:10 +08:00
|
|
|
|
return gzipData, err
|
|
|
|
|
}
|
|
|
|
|
//defer r.Close()
|
|
|
|
|
return r, nil
|
|
|
|
|
}
|
|
|
|
|
func UnGzip(gzipData []byte) ([]byte, error) {
|
|
|
|
|
r, err := gzip.NewReader(bytes.NewReader(gzipData))
|
|
|
|
|
if err != nil {
|
2020-09-07 15:36:17 +08:00
|
|
|
|
log.Println("UnGzip error:", err)
|
2019-12-27 16:16:10 +08:00
|
|
|
|
return gzipData, err
|
|
|
|
|
}
|
|
|
|
|
defer r.Close()
|
|
|
|
|
var decryptECBBytes = gzipData
|
|
|
|
|
decryptECBBytes, err = ioutil.ReadAll(r)
|
|
|
|
|
if err != nil {
|
2020-09-07 15:36:17 +08:00
|
|
|
|
log.Println("UnGzip")
|
2019-12-27 16:16:10 +08:00
|
|
|
|
return gzipData, err
|
|
|
|
|
}
|
|
|
|
|
return decryptECBBytes, nil
|
|
|
|
|
}
|
2020-07-03 18:01:12 +08:00
|
|
|
|
func LogInterface(i interface{}) string {
|
|
|
|
|
return fmt.Sprintf("%+v", i)
|
2019-12-18 15:52:31 +08:00
|
|
|
|
}
|
|
|
|
|
func ReplaceAll(str string, expr string, replaceStr string) string {
|
|
|
|
|
reg := regexp.MustCompile(expr)
|
|
|
|
|
str = reg.ReplaceAllString(str, replaceStr)
|
|
|
|
|
return str
|
|
|
|
|
}
|
|
|
|
|
func ParseJson(data []byte) map[string]interface{} {
|
|
|
|
|
var result map[string]interface{}
|
2020-09-07 15:36:17 +08:00
|
|
|
|
d := json.NewDecoder(bytes.NewReader(data))
|
2019-12-18 15:52:31 +08:00
|
|
|
|
d.UseNumber()
|
|
|
|
|
d.Decode(&result)
|
|
|
|
|
return result
|
|
|
|
|
}
|
2019-12-27 16:16:10 +08:00
|
|
|
|
func ParseJsonV2(reader io.Reader) map[string]interface{} {
|
|
|
|
|
var result map[string]interface{}
|
2020-09-07 15:36:17 +08:00
|
|
|
|
d := json.NewDecoder(reader)
|
2019-12-27 16:16:10 +08:00
|
|
|
|
d.UseNumber()
|
|
|
|
|
d.Decode(&result)
|
|
|
|
|
return result
|
|
|
|
|
}
|
2020-07-27 11:51:19 +08:00
|
|
|
|
func ParseJsonV3(data []byte, dest interface{}) error {
|
2020-09-07 15:36:17 +08:00
|
|
|
|
d := json.NewDecoder(bytes.NewReader(data))
|
2020-07-27 11:51:19 +08:00
|
|
|
|
d.UseNumber()
|
2020-09-07 15:36:17 +08:00
|
|
|
|
return d.Decode(dest)
|
2020-07-27 11:51:19 +08:00
|
|
|
|
}
|
2020-09-07 15:36:17 +08:00
|
|
|
|
func ParseJsonV4(reader io.Reader, dest interface{}) error {
|
|
|
|
|
d := json.NewDecoder(reader)
|
|
|
|
|
d.UseNumber()
|
|
|
|
|
return d.Decode(dest)
|
|
|
|
|
}
|
|
|
|
|
func PanicWrapper(f func()) {
|
|
|
|
|
defer func() {
|
|
|
|
|
if r := recover(); r != nil {
|
2023-09-23 05:18:19 +08:00
|
|
|
|
log.Println("Recover panic : "+"\n"+string(debug.Stack()), r)
|
2020-09-07 15:36:17 +08:00
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
f()
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-18 15:52:31 +08:00
|
|
|
|
func ToJson(object interface{}) string {
|
2021-11-03 17:47:33 +08:00
|
|
|
|
result := bytes.NewBuffer([]byte{})
|
|
|
|
|
jsonEncoder := json.NewEncoder(result)
|
|
|
|
|
jsonEncoder.SetEscapeHTML(false)
|
|
|
|
|
err := jsonEncoder.Encode(object)
|
2019-12-18 15:52:31 +08:00
|
|
|
|
if err != nil {
|
2020-09-07 15:36:17 +08:00
|
|
|
|
log.Println("ToJson Error:", err)
|
2019-12-18 15:52:31 +08:00
|
|
|
|
return "{}"
|
|
|
|
|
}
|
2021-11-03 17:47:33 +08:00
|
|
|
|
return result.String()
|
2019-12-18 15:52:31 +08:00
|
|
|
|
}
|
|
|
|
|
func Exists(keys []string, h map[string]interface{}) bool {
|
|
|
|
|
for _, key := range keys {
|
2023-09-23 05:18:19 +08:00
|
|
|
|
if Exist(key, h) {
|
|
|
|
|
return true
|
2019-12-18 15:52:31 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-23 05:18:19 +08:00
|
|
|
|
return false
|
2019-12-18 15:52:31 +08:00
|
|
|
|
}
|
|
|
|
|
func Exist(key string, h map[string]interface{}) bool {
|
|
|
|
|
_, ok := h[key]
|
|
|
|
|
return ok
|
|
|
|
|
}
|
|
|
|
|
func GetCurrentPath() (string, error) {
|
|
|
|
|
file, err := exec.LookPath(os.Args[0])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
path, err := filepath.Abs(file)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return "", err
|
|
|
|
|
}
|
|
|
|
|
i := strings.LastIndex(path, "/")
|
|
|
|
|
if i < 0 {
|
|
|
|
|
i = strings.LastIndex(path, "\\")
|
|
|
|
|
}
|
|
|
|
|
if i < 0 {
|
|
|
|
|
return "", errors.New(`error: Can't find "/" or "\".`)
|
|
|
|
|
}
|
2020-09-07 15:36:17 +08:00
|
|
|
|
return path[0 : i+1], nil
|
2019-12-18 15:52:31 +08:00
|
|
|
|
}
|
2019-12-19 17:28:26 +08:00
|
|
|
|
func MD5(data []byte) string {
|
|
|
|
|
h := md5.New()
|
|
|
|
|
h.Write(data)
|
|
|
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
|
|
|
}
|
2019-12-24 14:56:34 +08:00
|
|
|
|
func GenRandomBytes(size int) (blk []byte, err error) {
|
|
|
|
|
blk = make([]byte, size)
|
|
|
|
|
_, err = rand.Read(blk)
|
|
|
|
|
return
|
|
|
|
|
}
|
2020-02-10 14:40:50 +08:00
|
|
|
|
|
|
|
|
|
func CalMatchScoresV2(beMatchedData string, beSplitedData string, matchType string) float32 {
|
|
|
|
|
var score float32 = 0.0
|
2021-11-02 17:22:38 +08:00
|
|
|
|
beMatchedData = width.Narrow.String(strings.ToUpper(strings.TrimSpace(norm.NFC.String(beMatchedData))))
|
|
|
|
|
beSplitedData = width.Narrow.String(strings.ToUpper(strings.TrimSpace(norm.NFC.String(beSplitedData))))
|
2020-02-10 14:40:50 +08:00
|
|
|
|
orginData := beMatchedData
|
|
|
|
|
if len(beMatchedData) < len(beSplitedData) {
|
|
|
|
|
orginData = beSplitedData
|
|
|
|
|
beSplitedData = beMatchedData
|
|
|
|
|
beMatchedData = orginData
|
|
|
|
|
|
|
|
|
|
}
|
2020-09-07 15:36:17 +08:00
|
|
|
|
//log.Printf("1:orginData:%s,beMatchedData:%s,beSplitedData:%s\n",orginData,beMatchedData,beSplitedData)
|
2020-02-10 14:40:50 +08:00
|
|
|
|
var keyword []string
|
|
|
|
|
if matchType == "songName" {
|
|
|
|
|
keyword = ParseSongNameKeyWord(beSplitedData)
|
|
|
|
|
} else if matchType == "singerName" {
|
|
|
|
|
keyword = ParseSingerKeyWord(beSplitedData)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, key := range keyword {
|
|
|
|
|
beMatchedData = strings.Replace(beMatchedData, key, "", 1)
|
|
|
|
|
}
|
2020-09-07 15:36:17 +08:00
|
|
|
|
//log.Printf("2:orginData:%s,beMatchedData:%s,beSplitedData:%s\n",orginData,beMatchedData,beSplitedData)
|
2020-02-10 14:40:50 +08:00
|
|
|
|
if beMatchedData == orginData {
|
|
|
|
|
return 0.0
|
|
|
|
|
}
|
|
|
|
|
//beMatchedData = ReplaceAll(beMatchedData, "[`~!@#$%^&*()_\\-+=|{}':;',\\[\\]\\\\.<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]", "")
|
|
|
|
|
//beMatchedData = strings.ReplaceAll(beMatchedData, " ", "")
|
|
|
|
|
score = 1 - (float32(len(beMatchedData)) / (float32(len(orginData))))
|
|
|
|
|
return score
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-24 14:56:34 +08:00
|
|
|
|
func CalMatchScores(beMatchedData string, keyword []string) float32 {
|
|
|
|
|
var score float32 = 0.0
|
|
|
|
|
beMatchedData = width.Narrow.String(strings.ToUpper(beMatchedData))
|
|
|
|
|
orginData := beMatchedData
|
|
|
|
|
for _, key := range keyword {
|
|
|
|
|
beMatchedData = strings.Replace(beMatchedData, key, "", 1)
|
|
|
|
|
}
|
|
|
|
|
if beMatchedData == orginData {
|
|
|
|
|
return 0.0
|
|
|
|
|
}
|
|
|
|
|
//beMatchedData = ReplaceAll(beMatchedData, "[`~!@#$%^&*()_\\-+=|{}':;',\\[\\]\\\\.<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]", "")
|
|
|
|
|
//beMatchedData = strings.ReplaceAll(beMatchedData, " ", "")
|
|
|
|
|
score = 1 - (float32(len(beMatchedData)) / (float32(len(orginData))))
|
|
|
|
|
return score
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var leftPairedSymbols = width.Narrow.String("((《<[{「【『\"'")
|
|
|
|
|
var rightPairedSymbols = width.Narrow.String("))》>]}」】』\"'")
|
|
|
|
|
|
|
|
|
|
func parsePairedSymbols(data string, sub string, substr []string, keyword map[string]int) string {
|
|
|
|
|
data = strings.TrimSpace(data)
|
|
|
|
|
leftIndex := strings.Index(leftPairedSymbols, sub)
|
|
|
|
|
rightIndex := strings.Index(rightPairedSymbols, sub)
|
|
|
|
|
subIndex := 0
|
|
|
|
|
for index, key := range substr {
|
|
|
|
|
if key == sub {
|
|
|
|
|
subIndex = index
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
index := -1
|
|
|
|
|
if leftIndex != -1 {
|
|
|
|
|
index = leftIndex
|
|
|
|
|
} else if rightIndex != -1 {
|
|
|
|
|
index = rightIndex
|
|
|
|
|
}
|
|
|
|
|
if index != -1 {
|
|
|
|
|
leftSymbol := leftPairedSymbols[index : index+len(sub)]
|
|
|
|
|
rightSymbol := rightPairedSymbols[index : index+len(sub)]
|
|
|
|
|
leftCount := strings.Count(data, leftSymbol)
|
|
|
|
|
rightCount := strings.Count(data, rightSymbol)
|
|
|
|
|
if leftCount == rightCount && leftCount > 0 {
|
|
|
|
|
for i := 0; i < leftCount; i++ {
|
|
|
|
|
lastLeftIndex := strings.LastIndex(data, leftSymbol)
|
|
|
|
|
matchedRightIndex := strings.Index(data[lastLeftIndex:], rightSymbol)
|
|
|
|
|
if matchedRightIndex == -1 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
key := strings.TrimSpace(data[lastLeftIndex+len(leftSymbol) : lastLeftIndex+matchedRightIndex])
|
|
|
|
|
data = data[:lastLeftIndex] + " " + data[lastLeftIndex+matchedRightIndex+len(rightSymbol):]
|
|
|
|
|
substr2 := substr[subIndex+1:]
|
|
|
|
|
parseKeyWord(key, substr2, keyword)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return data
|
|
|
|
|
}
|
|
|
|
|
func parseKeyWord(data string, substr []string, keyword map[string]int) {
|
|
|
|
|
if len(data) == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data = strings.TrimSpace(data)
|
|
|
|
|
for _, sub := range substr {
|
|
|
|
|
if strings.Contains(data, sub) {
|
|
|
|
|
if strings.Contains(leftPairedSymbols, sub) || strings.Contains(rightPairedSymbols, sub) {
|
|
|
|
|
data = parsePairedSymbols(data, sub, substr, keyword)
|
|
|
|
|
} else {
|
|
|
|
|
splitData := strings.Split(data, sub)
|
|
|
|
|
for _, key := range splitData {
|
|
|
|
|
newKey := strings.TrimSpace(key)
|
|
|
|
|
parseKeyWord(newKey, substr, keyword)
|
|
|
|
|
data = strings.Replace(data, key, "", 1)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
data = strings.ReplaceAll(data, sub, "")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
data = strings.TrimSpace(data)
|
|
|
|
|
if len(data) > 0 {
|
|
|
|
|
if strings.EqualFold(data, "LIVE版") {
|
|
|
|
|
data = "LIVE"
|
|
|
|
|
}
|
|
|
|
|
keyword[data] = 1
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ByLenSort []string
|
|
|
|
|
|
|
|
|
|
func (a ByLenSort) Len() int {
|
|
|
|
|
return len(a)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (a ByLenSort) Less(i, j int) bool {
|
|
|
|
|
return len(a[i]) > len(a[j])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (a ByLenSort) Swap(i, j int) {
|
|
|
|
|
a[i], a[j] = a[j], a[i]
|
|
|
|
|
}
|
|
|
|
|
func ParseSongNameKeyWord(data string) []string {
|
|
|
|
|
var keyword = make(map[string]int)
|
|
|
|
|
if len(data) > 0 {
|
|
|
|
|
data = width.Narrow.String(strings.ToUpper(data))
|
|
|
|
|
substr := []string{"(", "[", "{", "<", "《", "「", "【", "『", "+", "/", ":", ",", "。", " "}
|
|
|
|
|
for index, sub := range substr {
|
|
|
|
|
substr[index] = width.Narrow.String(sub)
|
|
|
|
|
}
|
|
|
|
|
parseKeyWord(data, substr, keyword)
|
|
|
|
|
}
|
|
|
|
|
keys := make([]string, 0, len(keyword))
|
|
|
|
|
for k, _ := range keyword {
|
|
|
|
|
keys = append(keys, k)
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(ByLenSort(keys))
|
|
|
|
|
return keys
|
|
|
|
|
}
|
|
|
|
|
func ParseSingerKeyWord(data string) []string {
|
|
|
|
|
var keyword = make(map[string]int)
|
|
|
|
|
if len(data) > 0 {
|
|
|
|
|
data = strings.TrimSpace(strings.ToUpper(data))
|
2020-07-03 18:01:12 +08:00
|
|
|
|
substr := []string{"、", ",", " ", "、"}
|
2019-12-24 14:56:34 +08:00
|
|
|
|
parseKeyWord(data, substr, keyword)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
keys := make([]string, 0, len(keyword))
|
|
|
|
|
for k, _ := range keyword {
|
|
|
|
|
keys = append(keys, k)
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(ByLenSort(keys))
|
|
|
|
|
return keys
|
|
|
|
|
}
|
2021-10-02 00:38:18 +08:00
|
|
|
|
|
|
|
|
|
func round(num float64) int {
|
|
|
|
|
return int(num + math.Copysign(0.5, num))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ToFixed(num float64, precision int) float64 {
|
|
|
|
|
output := math.Pow(10, float64(precision))
|
|
|
|
|
return float64(round(num*output)) / output
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ParseCookies(file string) []*http.Cookie {
|
|
|
|
|
fl, err := os.Open(file)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(file, err)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
defer fl.Close()
|
|
|
|
|
r := bufio.NewReader(fl)
|
|
|
|
|
cl, err := cookiestxt.Parse(r)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return cl
|
|
|
|
|
}
|
2021-11-04 00:12:56 +08:00
|
|
|
|
|
2021-11-04 20:27:32 +08:00
|
|
|
|
func Combination(WordList []string) (result []string) {
|
|
|
|
|
if WordList == nil || len(WordList) == 0 {
|
2021-11-04 00:12:56 +08:00
|
|
|
|
return []string{
|
|
|
|
|
"",
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-04 20:27:32 +08:00
|
|
|
|
if len(WordList) == 1 {
|
|
|
|
|
return []string{
|
|
|
|
|
"",
|
|
|
|
|
WordList[0],
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
tmp := Combination(WordList[1:])
|
2021-11-04 00:12:56 +08:00
|
|
|
|
result = append(result, tmp...)
|
|
|
|
|
for _, v := range tmp {
|
2021-11-04 20:27:32 +08:00
|
|
|
|
result = append(result, WordList[0]+" "+v)
|
2021-11-04 00:12:56 +08:00
|
|
|
|
}
|
|
|
|
|
return result
|
|
|
|
|
}
|