utils/utils.go
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")
}