fzxiao233/Vtb_Record

View on GitHub
utils/utils.go

Summary

Maintainability
A
3 hrs
Test Coverage
package utils

import (
    "bytes"
    "context"
    "fmt"
    "github.com/mitchellh/mapstructure"
    "io"
    "math/rand"
    "net/http"
    "os"
    "path"
    "path/filepath"
    "strconv"
    "strings"
    "time"
)

//var client *http.Client

func init() {
    //client = createClient()
}

func MapToStruct(mapVal map[string]interface{}, structVal interface{}) error {
    config := &mapstructure.DecoderConfig{
        Metadata:         nil,
        Result:           structVal,
        WeaklyTypedInput: true,
    }
    decoder, err := mapstructure.NewDecoder(config)
    if err != nil {
        return err
    }
    decoder.Decode(mapVal)
    return nil
}

func HttpGetBuffer(client *http.Client, url string, header map[string]string, buf *bytes.Buffer) (*bytes.Buffer, error) {
    return HttpDoWithBufferEx(context.Background(), client, "GET", url, header, nil, buf)
}

func HttpDoWithBufferEx(ctx context.Context, client *http.Client, meth string, url string, header map[string]string, data []byte, buf *bytes.Buffer) (*bytes.Buffer, error) {
    if client == nil {
        client = &http.Client{}
    }
    var dataReader io.Reader
    if data != nil {
        dataReader = bytes.NewReader(data)
    }
    req, _ := http.NewRequestWithContext(ctx, meth, url, dataReader)
    req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36")
    req.Header.Set("Accept-Language", "en-US,en;q=0.8")
    for k, v := range header {
        req.Header.Set(k, v)
    }
    res, err := client.Do(req)
    if res != nil {
        defer res.Body.Close()
    }
    if err != nil || res == nil {
        err = fmt.Errorf("HttpGet error %w", err)
        //log.Warn(err)
        return nil, err
    }

    if res.StatusCode != 200 && res.StatusCode != 206 {
        if res.StatusCode == 404 {
            err = fmt.Errorf("HttpGet status error %d", res.StatusCode)
            return nil, err
        } else {
            //buf := bytes.NewBuffer(make([]byte, 0))
            //_, _ = io.Copy(buf, res.Body)
            err = fmt.Errorf("HttpGet status error %d with header %v", res.StatusCode, req.Header) //, string(buf.Bytes()))
            //log.Warn(err)
            return nil, err
        }
    }

    //log.Infof("%v", res.ContentLength)
    //var htmlBody []byte
    if res.ContentLength >= 0 {
        if buf == nil {
            buf = bytes.NewBuffer(make([]byte, res.ContentLength))
        }
        buf.Reset()
        if int64(buf.Cap()) < res.ContentLength {
            buf.Grow(int(res.ContentLength) - buf.Cap())
        }
        //buf := bytes.NewBuffer(make([]byte, 0, res.ContentLength))
        n, err := io.Copy(buf, res.Body)
        if err != nil {
            return nil, err
        }
        if n != res.ContentLength {
            return nil, fmt.Errorf("Got unexpected payload: expected: %v, got %v", res.ContentLength, n)
        }
        //htmlBody = buf.Bytes()
    } else {
        if buf == nil {
            buf = bytes.NewBuffer(make([]byte, 2048))
        }
        buf.Reset()
        _, err := io.Copy(buf, res.Body)
        if err != nil {
            return nil, err
        }
        //htmlBody, _ = ioutil.ReadAll(res.Body)
    }
    return buf, nil
}

func HttpGet(client *http.Client, url string, header map[string]string) ([]byte, error) {
    buf, err := HttpGetBuffer(client, url, header, nil)
    if err != nil {
        return nil, err
    } else {
        return buf.Bytes(), nil
    }
}

func HttpPost(client *http.Client, url string, header map[string]string, data []byte) ([]byte, error) {
    buf, err := HttpDoWithBufferEx(context.Background(), client, "POST", url, header, data, nil)
    if buf == nil {
        return nil, err
    } else {
        return buf.Bytes(), err
    }
}

func IsFileExist(aFilepath string) bool {
    if _, err := os.Stat(aFilepath); err == nil {
        return true
    } else {
        //log.Errorf("File not exist %s, stat err %s", aFilepath, err)
        return false
    }
}
func GenerateFilepath(DownDir string, VideoTitle string) string {
    pathSlice := []string{DownDir, VideoTitle}
    aFilepath := strings.Join(pathSlice, "/")
    /*if IsFileExist(aFilepath) {
        return ChangeName(aFilepath)
    } else {
        return aFilepath
    }*/
    return ChangeName(aFilepath)
}
func MakeDir(dirPath string) (ret string, err error) {
    if !IsFileExist(dirPath) {
        err := os.MkdirAll(dirPath, 0775)
        if err != nil {
            return "", err
        }
        return dirPath, nil
    }
    return dirPath, nil
}

func AddSuffix(aFilepath string, suffix string) string {
    dir, file := filepath.Split(aFilepath)
    ext := path.Ext(file)
    filename := strings.TrimSuffix(path.Base(file), ext)
    filename += "_"
    filename += suffix
    return dir + filename + ext
}

func ChangeName(aFilepath string) string {
    return AddSuffix(aFilepath, strconv.FormatInt(time.Now().Unix(), 10))
}
func GetTimeNow() string {
    return time.Now().Format("2006-01-02 15:04:05")
}
func RemoveIllegalChar(Title string) string {
    illegalChars := []string{"|", "/", "\\", ":", "?"}
    //"github.com/fzxiao233/Go-Emoji-Utils"
    //Title = emoji.RemoveAll(Title)
    for _, char := range illegalChars {
        Title = strings.ReplaceAll(Title, char, "#")
    }
    return Title
}

func I2b(i int) bool {
    if i != 0 {
        return true
    } else {
        return false
    }
}

func Min(a, b int) int {
    if a < b {
        return a
    }
    return b
}

func RPartition(s string, sep string) (string, string, string) {
    parts := strings.SplitAfter(s, sep)
    if len(parts) == 1 {
        return "", "", parts[0]
    }
    return strings.Join(parts[0:len(parts)-1], ""), sep, parts[len(parts)-1]
}

func RandChooseStr(arr []string) string {
    return arr[rand.Intn(len(arr))]
}

func GenRandBuf(p []byte) (n int, err error) {
    r := rand.NewSource(time.Now().Unix())
    todo := len(p)
    offset := 0
    for {
        val := int64(r.Int63())
        for i := 0; i < 8; i++ {
            p[offset] = byte(val & 0xff)
            todo--
            if todo == 0 {
                return len(p), nil
            }
            offset++
            val >>= 8
        }
    }

    panic("unreachable")
}