package util
|
|
import (
|
"basic.com/valib/logger.git"
|
"bytes"
|
"crypto/aes"
|
"crypto/cipher"
|
"crypto/md5"
|
"crypto/rand"
|
"crypto/tls"
|
"encoding/base64"
|
"encoding/hex"
|
"encoding/json"
|
"fmt"
|
"github.com/gin-gonic/gin"
|
"github.com/pkg/errors"
|
"io"
|
"io/ioutil"
|
"net"
|
"net/http"
|
"os"
|
"os/exec"
|
"path/filepath"
|
"reflect"
|
"regexp"
|
"strconv"
|
"strings"
|
"time"
|
"vamicro/config"
|
"vamicro/extend/code"
|
)
|
|
const TimeFmtStr = "2006-01-02 15:04:05"
|
|
// iterater field of struct to lowcast.
|
// return type: string slice.
|
func FiledbyStuct(stuct interface{}) []string {
|
var strtmp []string
|
t := reflect.TypeOf(stuct)
|
for i := 0; i < t.NumField(); i++ {
|
strtmp = append(strtmp, strings.ToLower(string(t.Field(i).Name)))
|
}
|
return strtmp
|
}
|
|
//
|
// ResponseFormat 返回数据格式化
|
func ResponseFormat(c *gin.Context, respStatus *code.Code, data interface{}) {
|
if respStatus == nil {
|
respStatus = code.RequestParamError
|
}
|
c.JSON(respStatus.Status, gin.H{
|
"code": respStatus.Status,
|
"success": respStatus.Success,
|
"msg": respStatus.Message,
|
"data": data,
|
})
|
return
|
}
|
|
func PseudoUuid() (uuid string) {
|
b := make([]byte, 16)
|
rand.Read(b)
|
uuid = fmt.Sprintf("%X-%X-%X-%X-%X", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
|
|
return
|
}
|
|
var commonIV = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}
|
var encryptKey = "beijingcompanybasicvideoanalysis"
|
|
func Encrypt(pwd string) (string, error) {
|
key := []byte(encryptKey)
|
pwdBytes := []byte(pwd)
|
c, err := aes.NewCipher(key)
|
if err != nil {
|
return "", err
|
}
|
cfb := cipher.NewCFBEncrypter(c, commonIV)
|
|
ciphertext := make([]byte, len(pwdBytes))
|
cfb.XORKeyStream(ciphertext, pwdBytes)
|
pwdStr := base64.StdEncoding.EncodeToString(ciphertext)
|
return pwdStr, nil
|
}
|
|
func Struct2Map(obj interface{}) map[string]interface{} {
|
resultMap := make(map[string]interface{}, 0)
|
bytesData, err := json.Marshal(obj)
|
if err != nil {
|
return resultMap
|
}
|
json.Unmarshal(bytesData, &resultMap)
|
return resultMap
|
}
|
|
// 获取本机网卡IP
|
func GetLocalIP(networkName string) (ipv4 string, mask string, err error) {
|
interfaces, err := net.Interfaces()
|
if err != nil {
|
return "", "", err
|
}
|
|
for _, i := range interfaces {
|
byName, err := net.InterfaceByName(i.Name)
|
if err != nil {
|
return "", "", err
|
}
|
addresses, err := byName.Addrs()
|
for _, v := range addresses {
|
if ipnet, ok := v.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
if ipnet.IP.To4() != nil {
|
if byName.Name == networkName {
|
maskStr := ipnet.Mask.String()
|
mask64, _ := strconv.ParseUint(maskStr, 16, 32)
|
return ipnet.IP.String(), IpIntToString(int(mask64)), nil
|
}
|
}
|
}
|
}
|
}
|
return "", "", errors.New("ipv4 not found")
|
}
|
|
func GetDefaultRoute(networkName string) (route string, err error) {
|
cmdStr := fmt.Sprintf("route | grep -P \"^default.*%s$\" | awk '{print $2}'", networkName)
|
cmd := exec.Command("/bin/sh", "-c", cmdStr)
|
b, err := cmd.Output()
|
if err != nil {
|
return "", err
|
}
|
return string(b), nil
|
|
}
|
|
func StringIpToInt(ipstring string) int {
|
ipSegs := strings.Split(ipstring, ".")
|
var ipInt int = 0
|
var pos uint = 24
|
for _, ipSeg := range ipSegs {
|
tempInt, _ := strconv.Atoi(ipSeg)
|
tempInt = tempInt << pos
|
ipInt = ipInt | tempInt
|
pos -= 8
|
}
|
return ipInt
|
}
|
|
func IpIntToString(ipInt int) string {
|
ipSegs := make([]string, 4)
|
var len int = len(ipSegs)
|
buffer := bytes.NewBufferString("")
|
for i := 0; i < len; i++ {
|
tempInt := ipInt & 0xFF
|
ipSegs[len-i-1] = strconv.Itoa(tempInt)
|
|
ipInt = ipInt >> 8
|
}
|
for i := 0; i < len; i++ {
|
buffer.WriteString(ipSegs[i])
|
if i < len-1 {
|
buffer.WriteString(".")
|
}
|
}
|
return buffer.String()
|
}
|
|
const ipReg = `^(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`
|
|
func IpCheck(ipStr string) (string, bool) {
|
idx := strings.LastIndex(ipStr, ":")
|
if idx > -1 {
|
ipStr = ipStr[:idx]
|
}
|
if match, _ := regexp.MatchString(ipReg, ipStr); match {
|
return ipStr, true
|
}
|
return "", false
|
}
|
|
func PathExists(path string) (bool, error) {
|
_, err := os.Stat(path)
|
if err == nil {
|
return true, nil
|
}
|
if os.IsNotExist(err) {
|
return false, nil
|
}
|
return false, err
|
}
|
|
func IsFileExist(path string) bool {
|
_, err := os.Stat(path)
|
if err != nil {
|
if os.IsNotExist(err) {
|
return false
|
}
|
}
|
return true
|
}
|
|
const imgReg = `^\.(jpg|png|jpeg)$`
|
|
func ImgCheck(ext string) bool {
|
lowerStr := strings.ToLower(ext)
|
if match, _ := regexp.MatchString(imgReg, lowerStr); match {
|
return true
|
}
|
return false
|
}
|
|
const videoReg = `^\.(mp4|rmvb|flv|mpeg|avi)$`
|
|
func VideoCheck(ext string) bool {
|
lowerStr := strings.ToLower(ext)
|
if match, _ := regexp.MatchString(videoReg, lowerStr); match {
|
return true
|
}
|
return false
|
}
|
|
// 判断所给路径文件/文件夹是否存在
|
func Exists(path string) bool {
|
_, err := os.Stat(path) //os.Stat获取文件信息
|
if err != nil {
|
if os.IsExist(err) {
|
return true
|
}
|
return false
|
}
|
return true
|
}
|
|
func CreateDirectory(path string) bool {
|
if path == "" {
|
return false
|
}
|
if Exists(path) {
|
return true
|
}
|
err := os.MkdirAll(path, os.ModePerm)
|
if err != nil {
|
return false
|
}
|
return true
|
}
|
|
//日期转字符串
|
func FormatDate(date time.Time, layout string) string {
|
layout = strings.Replace(layout, "yyyy", "2006", 1)
|
layout = strings.Replace(layout, "yy", "06", 1)
|
layout = strings.Replace(layout, "MM", "01", 1)
|
layout = strings.Replace(layout, "dd", "02", 1)
|
layout = strings.Replace(layout, "HH", "15", 1)
|
layout = strings.Replace(layout, "mm", "04", 1)
|
layout = strings.Replace(layout, "ss", "05", 1)
|
layout = strings.Replace(layout, "SSS", "000", -1)
|
|
return date.Format(layout)
|
}
|
|
//计算持续时长
|
func TimeSpan(startTime time.Time) string {
|
sp := time.Since(startTime)
|
day := strconv.Itoa(int(sp.Hours() / 24)) //天数
|
hour := strconv.Itoa(int(sp.Hours()) % 24) //小时数
|
minute := strconv.Itoa(int(sp.Minutes()) % 60) //分钟数
|
sec := strconv.Itoa(int(sp.Seconds()) % 60) //秒数
|
return day + "天" + hour + "时" + minute + "分" + sec + "秒"
|
}
|
|
func ComputeFileMd5(filepath string) string {
|
|
f, err := os.Open(filepath)
|
if err != nil {
|
logger.Debug("ComputeFileMd5 Open err:", err)
|
return ""
|
}
|
|
defer f.Close()
|
|
md5hash := md5.New()
|
if _, err := io.Copy(md5hash, f); err != nil {
|
logger.Debug("ComputeFileMd5 Copy err:", err)
|
return ""
|
}
|
|
md5hash.Sum(nil)
|
return fmt.Sprintf("%x", md5hash.Sum(nil))
|
}
|
|
func ParseScore64(compareScore float64) float64 {
|
if compareScore < 1 {
|
compareScore = compareScore * 100
|
}
|
f, _ := strconv.ParseFloat(fmt.Sprintf("%2.2f", compareScore), 64)
|
return f
|
}
|
|
func GetAppRootPath() string {
|
file, err := exec.LookPath(os.Args[0])
|
if err != nil {
|
return ""
|
}
|
p, err := filepath.Abs(file)
|
if err != nil {
|
return ""
|
}
|
return filepath.Dir(p)
|
}
|
|
func FormatNum(oNum int, n int) string {
|
m := 0
|
for {
|
oNum = oNum / 10
|
m++
|
if oNum == 0 {
|
break
|
}
|
}
|
fmtStr := "%0" + strconv.Itoa(m) + "d"
|
return fmt.Sprintf(fmtStr, n)
|
}
|
|
func FileMd5(path string) (string, error) {
|
file, err := os.Open(path)
|
if err != nil {
|
return "", err
|
}
|
|
defer file.Close()
|
|
_md5 := md5.New()
|
if _, err := io.Copy(_md5, file); err != nil {
|
return "", err
|
}
|
|
return hex.EncodeToString(_md5.Sum(nil)), nil
|
}
|
|
func DownLoad(url string) ([]byte, error) {
|
connectTimeout := 5 * time.Second
|
readWriteTimeout := 10000 * time.Millisecond
|
c := &http.Client{
|
Transport: &http.Transport{
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
Dial: TimeoutDialer(connectTimeout, readWriteTimeout),
|
},
|
}
|
req, err := http.NewRequest("GET", url, nil)
|
if err != nil {
|
return nil, err
|
}
|
resp, err := c.Do(req)
|
|
body, err1 := ioutil.ReadAll(resp.Body)
|
if err1 != nil {
|
resp.Body.Close()
|
return nil, err
|
} else {
|
logger.Debug("Download success")
|
}
|
resp.Body.Close()
|
return body, nil
|
}
|
|
func TimeoutDialer(cTimeout time.Duration, rwTimeout time.Duration) func(net, addr string) (c net.Conn, err error) {
|
return func(netw, addr string) (net.Conn, error) {
|
conn, err := net.DialTimeout(netw, addr, cTimeout)
|
if err != nil {
|
return nil, err
|
}
|
conn.SetDeadline(time.Now().Add(rwTimeout))
|
return conn, nil
|
}
|
}
|
|
//判断一个数组是否包含某个元素
|
func ArrayContains(list []string, ele string) bool {
|
if list == nil {
|
return false
|
}
|
for _, s := range list {
|
if s == ele {
|
return true
|
}
|
}
|
return false
|
}
|
|
//获取当前平台的CPU-GPU架构
|
func GetPlatform() string {
|
dt := config.Server.DeviceType
|
if len(dt) >= 6 {
|
s := dt[4:6]
|
if s == "01" {
|
return "X86-NVIDIA"
|
} else if s == "02" {
|
return "X86-Bitmain"
|
} else if s == "03" {
|
return "ARM-NVIDIA"
|
} else if s == "04" {
|
return "ARM-Bitmain"
|
}
|
}
|
return ""
|
}
|
|
//验证platform是否匹配
|
func PlatformMatch(pt string) bool {
|
curPt := GetPlatform()
|
if pt == "" || curPt == "" {
|
return false
|
}
|
i1 := strings.Index(pt, "-")
|
i2 := strings.Index(curPt, "-")
|
if i1 == -1 || i2 == -1 {
|
return false
|
}
|
return pt[:i1] == curPt[:i2]
|
}
|
|
func GetVGpu() string {
|
plat := GetPlatform()
|
if strings.HasPrefix(plat, "X86") {
|
rGpu, _ := NvidiaVGpu()
|
return rGpu
|
}
|
return ""
|
}
|
|
/*
|
获取英伟达显卡的型号
|
*/
|
func NvidiaVGpu() (vGpu string, err error) {
|
resultMsg, e := ExeCmd("nvidia-smi -L")
|
if e != nil {
|
return vGpu, errors.New("无可用GPU!请检查是否正常安显卡及显卡驱动,通过nvidia-smi查询状态")
|
}
|
indeces := strings.Split(string(resultMsg), "\n")[0]
|
if len(indeces) > 0 {
|
vGpu = strings.Split(strings.Split(indeces, " (")[0], ": ")[1]
|
} else {
|
return vGpu, errors.New("无可用GPU!请检查是否正常安显卡及显卡驱动,通过nvidia-smi查询状态")
|
}
|
return vGpu, nil
|
}
|
|
/*
|
ARM机器不用匹配显卡
|
X86需要检验显卡型号是否与算法匹配
|
*/
|
func GpuMatch(vus string) bool {
|
platform := GetPlatform()
|
arr := strings.Split(vus, ",")
|
if strings.HasPrefix(platform, "X86") {
|
//获取机器实际的显卡型号
|
vGpu, err := NvidiaVGpu()
|
if err == nil {
|
isTi := strings.Contains(vGpu, " Ti")
|
for _, s := range arr {
|
aliasGpu := s
|
tix := strings.Index(aliasGpu, "ti")
|
if tix > 0 {
|
aliasGpu = aliasGpu[:tix] + " Ti"
|
}
|
if isTi {
|
if strings.Contains(vGpu, aliasGpu) && strings.Contains(aliasGpu, " Ti") {
|
return true
|
}
|
} else {
|
if strings.Contains(vGpu, aliasGpu) && !strings.Contains(aliasGpu, " Ti") {
|
return true
|
}
|
}
|
|
}
|
return false
|
}
|
return false
|
} else if strings.HasPrefix(platform, "ARM") {
|
return true
|
}
|
return false
|
}
|
|
func PortInUse(port string) bool {
|
number, err := strconv.Atoi(port)
|
if err != nil || number < 1 || number > 65535 {
|
return true
|
}
|
timeout := time.Second
|
conn, err := net.DialTimeout("tcp", net.JoinHostPort("127.0.0.1", port), timeout)
|
if conn != nil {
|
conn.Close()
|
}
|
//logger.Debug("port:", port, " err", err)
|
return err == nil
|
}
|
|
//获取商城地址,如果本地商城配置不为空,则取本地,否则取云端
|
func GetShopUrl() string {
|
s := config.ShopConf.Url
|
if config.ShopConf.LocalShop != "" {
|
s = config.ShopConf.LocalShop
|
}
|
logger.Debug("GetShopUrl addr:", s)
|
return s
|
}
|