feat: omc原始代码

This commit is contained in:
TsMask
2024-03-12 10:58:33 +08:00
parent 5133c93971
commit 2d01bb86d1
432 changed files with 66597 additions and 1 deletions

698
lib/global/kits.go Normal file
View File

@@ -0,0 +1,698 @@
package global
import (
"archive/zip"
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"os"
"path/filepath"
"reflect"
"regexp"
"sort"
"strings"
"time"
)
const (
IsIPv4 = "IPv4"
IsIPv6 = "IPv6"
NonIP = "NonIp"
)
type em struct{}
func GetPkgName() string {
return reflect.TypeOf(em{}).PkgPath()
}
// interface{} change to map[string]interface{}
// interface{} data is []interface{}
func ListToMap(list interface{}, key string) map[string]interface{} {
res := make(map[string]interface{})
arr := ToSlice(list)
for _, row := range arr {
immutable := reflect.ValueOf(row)
val := immutable.FieldByName(key).String()
res[val] = row
}
return res
}
// interface{} change to []interface{}
func ToSlice(arr interface{}) []interface{} {
ret := make([]interface{}, 0)
v := reflect.ValueOf(arr)
if v.Kind() != reflect.Slice {
ret = append(ret, arr)
return ret
}
l := v.Len()
for i := 0; i < l; i++ {
ret = append(ret, v.Index(i).Interface())
}
return ret
}
var TodoList []Todo
type Todo struct {
Id int64
Item string
}
// JSON序列化方式
func jsonStructToMap(TodoList Todo) (map[string]interface{}, error) {
// 结构体转json
strRet, err := json.Marshal(TodoList)
if err != nil {
return nil, err
}
// json转map
var mRet map[string]interface{}
err1 := json.Unmarshal(strRet, &mRet)
if err1 != nil {
return nil, err1
}
return mRet, nil
}
func IsContain(item string, items []string) bool {
for _, e := range items {
if e == item {
return true
}
}
return false
}
func IsContainP(item string, items *[]string, size int) bool {
for i := 0; i < size; i++ {
if (*items)[i] == item {
return true
}
}
return false
}
// 将字符串 分割成 字符串数组
// @s分割符
func SplitString(str string, s string) []string {
sa := strings.Split(str, s)
return sa
}
//  合并字符串数组
func MergeStringArr(a, b []string) []string {
var arr []string
for _, i := range a {
arr = append(arr, i)
}
for _, j := range b {
arr = append(arr, j)
}
return arr
}
// 数组去重
func UniqueStringArr(m []string) []string {
d := make([]string, 0)
tempMap := make(map[string]bool, len(m))
for _, v := range m { // 以值作为键名
if tempMap[v] == false {
tempMap[v] = true
d = append(d, v)
}
}
return d
}
//  合并整型数组
func MergeArr(a, b []int) []int {
var arr []int
for _, i := range a {
arr = append(arr, i)
}
for _, j := range b {
arr = append(arr, j)
}
return arr
}
// 数组去重
func UniqueArr(m []int) []int {
d := make([]int, 0)
tempMap := make(map[int]bool, len(m))
for _, v := range m { // 以值作为键名
if tempMap[v] == false {
tempMap[v] = true
d = append(d, v)
}
}
return d
}
// 升序
func AscArr(e []int) []int {
sort.Ints(e[:])
return e
}
// 降序
func DescArr(e []int) []int {
sort.Sort(sort.Reverse(sort.IntSlice(e)))
return e
}
func MatchRmUID(p string, s string) bool {
match, _ := regexp.MatchString(p, s)
return match
}
type OrderedMap struct {
Order []string
Map map[string]interface{}
}
func (om *OrderedMap) UnmarshalJson(b []byte) error {
json.Unmarshal(b, &om.Map)
index := make(map[string]int)
for key := range om.Map {
om.Order = append(om.Order, key)
esc, _ := json.Marshal(key) //Escape the key
index[key] = bytes.Index(b, esc)
}
sort.Slice(om.Order, func(i, j int) bool { return index[om.Order[i]] < index[om.Order[j]] })
return nil
}
func (om OrderedMap) MarshalJson() ([]byte, error) {
var b []byte
buf := bytes.NewBuffer(b)
buf.WriteRune('{')
l := len(om.Order)
for i, key := range om.Order {
km, err := json.Marshal(key)
if err != nil {
return nil, err
}
buf.Write(km)
buf.WriteRune(':')
vm, err := json.Marshal(om.Map[key])
if err != nil {
return nil, err
}
buf.Write(vm)
if i != l-1 {
buf.WriteRune(',')
}
fmt.Println(buf.String())
}
buf.WriteRune('}')
fmt.Println(buf.String())
return buf.Bytes(), nil
}
func GetBodyCopy(r *http.Request) (*bytes.Buffer, error) {
// If r.bodyBuf present, return the copy
// if r.bodyBuf != nil {
// return bytes.NewBuffer(r.bodyBuf.Bytes()), nil
// }
// Maybe body is `io.Reader`.
// Note: Resty user have to watchout for large body size of `io.Reader`
if r.Body != nil {
b, err := io.ReadAll(r.Body)
if err != nil {
return nil, err
}
// Restore the Body
// close(r.Body)
r.Body = io.NopCloser(bytes.NewReader(b))
// Return the Body bytes
return bytes.NewBuffer(b), nil
}
return nil, nil
}
func UnmarshalBody(r *http.Request, v *interface{}, maxLen int64) error {
body, err := io.ReadAll(io.LimitReader(r.Body, maxLen))
if err != nil {
return err
}
return json.Unmarshal(body, v)
}
func SetNotifyUrl(ip string, port uint16, uri string) string {
return fmt.Sprintf("http://%s:%d%s", ip, port, uri)
}
func GetIps() (ips []string, err error) {
interfaceAddr, err := net.InterfaceAddrs()
if err != nil {
return ips, err
}
for _, address := range interfaceAddr {
ipNet, isVailIpNet := address.(*net.IPNet)
// 检查ip地址判断是否回环地址
if isVailIpNet && !ipNet.IP.IsLoopback() {
if ipNet.IP.To4() != nil {
ips = append(ips, ipNet.IP.String())
}
}
}
return ips, nil
}
func GetCurrentTimeSliceIndexByPeriod(t time.Time, period int) int {
index := int((t.Hour()*60+t.Minute())/period) - 1
if index < 0 {
return int(24*60/period) - 1
}
return index
}
var (
cst *time.Location
)
// RFC3339ToDateTime convert rfc3339 value to china standard time layout
func RFC3339ToDateTime(value string) (string, error) {
ts, err := time.Parse(time.RFC3339, value)
if err != nil {
return "", err
}
return ts.In(cst).Format("2006-01-02 15:04:05"), nil
}
// CreateTimeDir 根据当前时间格式来创建文件夹
func CreateTimeDir(fmt string, path string) string {
folderName := time.Now().Format(fmt)
folderPath := filepath.Join(path, folderName)
if _, err := os.Stat(folderPath); os.IsNotExist(err) {
// 必须分成两步:先创建文件夹、再修改权限
os.Mkdir(folderPath, 0664) //0644也可以os.ModePerm
os.Chmod(folderPath, 0664)
}
return folderPath
}
// CreateDir 根据传入的目录名和路径来创建文件夹
func CreateDir(folderName string, path string) string {
folderPath := filepath.Join(path, folderName)
if _, err := os.Stat(folderPath); os.IsNotExist(err) {
// 必须分成两步:先创建文件夹、再修改权限
os.MkdirAll(folderPath, 0664) //0644也可以os.ModePerm
os.Chmod(folderPath, 0664)
}
return folderPath
}
func GetFmtTimeString(srcFmt string, timeString string, dstFmt string) string {
t, _ := time.ParseInLocation(srcFmt, timeString, time.Local)
return t.Format(dstFmt)
}
func GetFileMD5Sum(filePath string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", err
}
defer file.Close()
md5 := md5.New()
_, err = io.Copy(md5, file)
if err != nil {
return "", err
}
md5str := hex.EncodeToString(md5.Sum(nil))
return md5str, nil
}
// PathExists check path is exist or no
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
}
// PathExists check path is exist or no
func FilePathExists(filePath string) (bool, error) {
_, err := os.Stat(filePath)
if err == nil { //文件或者目录存在
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
func GetDayDuration(d1, d2 string) int64 {
a, _ := time.Parse("2006-01-02", d1)
b, _ := time.Parse("2006-01-02", d2)
d := a.Sub(b)
return (int64)(d.Hours() / 24)
}
func GetSecondsSinceDatetime(datetimeStr string) (int64, error) {
loc1, _ := time.LoadLocation("Local")
// 解析日期时间字符串为时间对象
datetime, err := time.ParseInLocation(time.DateTime, datetimeStr, loc1)
if err != nil {
return 0, err
}
// 计算时间差
duration := time.Since(datetime)
// 获取时间差的秒数
seconds := int64(duration.Seconds())
return seconds, nil
}
func GetSecondDuration(time1, time2 string) (int64, error) {
loc1, _ := time.LoadLocation("Local")
// 解析日期时间字符串为时间对象
t1, err := time.ParseInLocation(time.DateTime, time1, loc1)
if err != nil {
return 0, err
}
t2, err := time.ParseInLocation(time.DateTime, time2, loc1)
if err != nil {
return 0, err
}
// 计算时间差
duration := t2.Sub(t1)
// 获取时间差的秒数
seconds := int64(duration.Seconds())
return seconds, nil
}
// 0: invalid ip
// 4: IPv4
// 6: IPv6
func ParseIP(s string) (net.IP, int) {
ip := net.ParseIP(s)
if ip == nil {
return nil, 0
}
for i := 0; i < len(s); i++ {
switch s[i] {
case '.':
return ip, 4
case ':':
return ip, 6
}
}
return nil, 0
}
func BytesCombine1(pBytes ...[]byte) []byte {
return bytes.Join(pBytes, []byte(""))
}
func BytesCombine(pBytes ...[]byte) []byte {
length := len(pBytes)
s := make([][]byte, length)
for index := 0; index < length; index++ {
s[index] = pBytes[index]
}
sep := []byte("")
return bytes.Join(s, sep)
}
func ParseIPAddr(ip string) string {
ipAddr := net.ParseIP(ip)
if ipAddr != nil {
if ipAddr.To4() != nil {
return IsIPv4
} else {
return IsIPv6
}
}
return NonIP
}
func CombineHostUri(ip string, port string) string {
var hostUri string = ""
ipType := ParseIPAddr(ip)
if ipType == IsIPv4 {
hostUri = fmt.Sprintf("http://%s:%v", ip, port)
} else {
hostUri = fmt.Sprintf("http://[%s]:%v", ip, port)
}
return hostUri
}
func StructToMap(obj interface{}) map[string]interface{} {
objValue := reflect.ValueOf(obj)
objType := objValue.Type()
m := make(map[string]interface{})
for i := 0; i < objValue.NumField(); i++ {
field := objValue.Field(i)
fieldName := objType.Field(i).Name
m[fieldName] = field.Interface()
}
return m
}
// ToMap 结构体转为Map[string]interface{}
func ToMap(in interface{}, tagName string) (map[string]interface{}, error) {
out := make(map[string]interface{})
v := reflect.ValueOf(in)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() != reflect.Struct { // 非结构体返回错误提示
return nil, fmt.Errorf("ToMap only accepts struct or struct pointer; got %T", v)
}
t := v.Type()
// 遍历结构体字段
// 指定tagName值为map中key;字段值为map中value
for i := 0; i < v.NumField(); i++ {
fi := t.Field(i)
if tagValue := fi.Tag.Get(tagName); tagValue != "" {
out[tagValue] = v.Field(i).Interface()
}
}
return out, nil
}
func ZipOneFile(srcFile, dstZip string, pathFlag bool) error {
zipFile, err := os.Create(dstZip)
if err != nil {
return err
}
defer zipFile.Close()
zipWriter := zip.NewWriter(zipFile)
defer zipWriter.Close()
fileToCompress, err := os.Open(srcFile)
if err != nil {
return err
}
defer fileToCompress.Close()
var fileInZip io.Writer
if pathFlag {
fileInZip, err = zipWriter.Create(srcFile)
if err != nil {
return err
}
} else {
// 获取文件的基本名称
fileName := filepath.Base(fileToCompress.Name())
fileInZip, err = zipWriter.Create(fileName)
if err != nil {
return err
}
}
_, err = io.Copy(fileInZip, fileToCompress)
if err != nil {
return err
}
return nil
}
func ZipDirectoryFile(srcDir, dstZip string) error {
// Create a new zip file
zipfileWriter, err := os.Create(dstZip)
if err != nil {
return err
}
defer zipfileWriter.Close()
// Create a new zip archive
zipWriter := zip.NewWriter(zipfileWriter)
defer zipWriter.Close()
// Walk through the directory and add files to the zip archive
err = filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Create a new file header for the current file
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
// Set the name of the file within the zip archive
header.Name = filepath.Join(filepath.Base(srcDir), path[len(srcDir):])
// If the current file is a directory, skip it
if info.IsDir() {
return nil
}
// Create a new file in the zip archive
fileWriter, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
// Open the current file
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
// Copy the contents of the current file to the zip archive
_, err = io.Copy(fileWriter, file)
if err != nil {
return err
}
return nil
})
return err
}
// 判断软件包是rpm或者deb, 1:rpm, 2:deb, 0:unknown format
func JudgeRpmOrDebPackage(filePath string) (int, error) {
var fileType int = 0
file, err := os.Open(filePath)
if err != nil {
return fileType, err
}
defer file.Close()
// Read the first 6 bytes of the file
header := make([]byte, 6)
_, err = file.Read(header)
if err != nil {
return fileType, err
}
// Check the magic numbers to determine the package format
if string(header) == "!<arch>" {
fileType = 1
} else if string(header) == "!<arch\n" || string(header) == "!<arch\r" {
fileType = 2
} else {
fileType = 0
}
return fileType, nil
}
func isRpmPackage(file *os.File) bool {
// RPM packages start with the magic number "EDABEEDB"
magic := []byte{0xED, 0xAB, 0xEE, 0xDB}
buffer := make([]byte, len(magic))
_, err := file.Read(buffer)
if err != nil && err != io.EOF {
return false
}
return string(buffer) == string(magic)
}
func isDebPackage(file *os.File) bool {
// DEB packages start with the magic number "!<arch>\n"
magic := []byte("!<arch>\n")
buffer := make([]byte, len(magic))
_, err := file.Read(buffer)
if err != nil && err != io.EOF {
return false
}
return string(buffer) == string(magic)
}
func CheckRpmOrDebPackage(filePath string) (int, error) {
var fileType int = 0
file, err := os.Open(filePath)
if err != nil {
return fileType, err
}
defer file.Close()
isRpm := isRpmPackage(file)
isDeb := isDebPackage(file)
if isRpm {
fileType = 1
} else if isDeb {
fileType = 2
} else {
fileType = 0
}
return fileType, nil
}
func IsRpmOrDebPackage(filePath string) int {
var fileType int = 0
if strings.Contains(filePath, ".rpm") {
fileType = 1
} else if strings.Contains(filePath, ".deb") {
fileType = 2
} else {
fileType = 0
}
return fileType
}