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 }