Init V4 community edition (#2265)
* Init V4 community edition * Init V4 community edition
This commit is contained in:
@@ -1,24 +1,39 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"math/rand"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
var (
|
||||
RandomVariantAll = []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
RandomLowerCases = []rune("1234567890abcdefghijklmnopqrstuvwxyz")
|
||||
)
|
||||
|
||||
// RandStringRunes 返回随机字符串
|
||||
func RandStringRunes(n int) string {
|
||||
var letterRunes = []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letterRunes[rand.Intn(len(letterRunes))]
|
||||
b[i] = RandomVariantAll[rand.Intn(len(RandomVariantAll))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// RandString returns random string in given length and variant
|
||||
func RandString(n int, variant []rune) string {
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = variant[rand.Intn(len(variant))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
@@ -35,13 +50,27 @@ func ContainsUint(s []uint, e uint) bool {
|
||||
|
||||
// IsInExtensionList 返回文件的扩展名是否在给定的列表范围内
|
||||
func IsInExtensionList(extList []string, fileName string) bool {
|
||||
ext := strings.ToLower(filepath.Ext(fileName))
|
||||
ext := Ext(fileName)
|
||||
// 无扩展名时
|
||||
if len(ext) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if ContainsString(extList, ext[1:]) {
|
||||
if ContainsString(extList, ext) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// IsInExtensionList 返回文件的扩展名是否在给定的列表范围内
|
||||
func IsInExtensionListExt(extList []string, ext string) bool {
|
||||
// 无扩展名时
|
||||
if len(ext) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if ContainsString(extList, ext) {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -122,3 +151,115 @@ func SliceDifference(slice1, slice2 []string) []string {
|
||||
}
|
||||
return nn
|
||||
}
|
||||
|
||||
// WithValue inject key-value pair into request context.
|
||||
func WithValue(c *gin.Context, key any, value any) {
|
||||
c.Request = c.Request.WithContext(context.WithValue(c.Request.Context(), key, value))
|
||||
}
|
||||
|
||||
// BoolToString transform bool to string
|
||||
func BoolToString(b bool) string {
|
||||
if b {
|
||||
return "1"
|
||||
}
|
||||
return "0"
|
||||
}
|
||||
|
||||
func EncodeTimeFlowString(str string, timeNow int64) string {
|
||||
timeNow = timeNow / 1000
|
||||
timeDigits := []int{}
|
||||
timeDigitIndex := 0
|
||||
|
||||
if len(str) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
str = fmt.Sprintf("%d|%s", timeNow, str)
|
||||
|
||||
res := make([]int32, 0, utf8.RuneCountInString(str))
|
||||
for timeNow > 0 {
|
||||
timeDigits = append(timeDigits, int(timeNow%int64(10)))
|
||||
timeNow = timeNow / 10
|
||||
}
|
||||
|
||||
add := false
|
||||
for pos, rune := range str {
|
||||
// take single digit with index timeDigitIndex from timeNow
|
||||
newIndex := pos
|
||||
if add {
|
||||
newIndex = pos + timeDigits[timeDigitIndex]*timeDigitIndex
|
||||
} else {
|
||||
newIndex = 2*timeDigitIndex*timeDigits[timeDigitIndex] - pos
|
||||
}
|
||||
|
||||
if newIndex < 0 {
|
||||
newIndex = newIndex * -1
|
||||
}
|
||||
|
||||
res = append(res, rune)
|
||||
newIndex = newIndex % len(res)
|
||||
|
||||
res[newIndex], res[len(res)-1] = res[len(res)-1], res[newIndex]
|
||||
|
||||
add = !add
|
||||
// Add timeDigitIndex by 1, but does not exceed total digits in timeNow
|
||||
timeDigitIndex++
|
||||
timeDigitIndex = timeDigitIndex % len(timeDigits)
|
||||
}
|
||||
|
||||
return string(res)
|
||||
}
|
||||
|
||||
func DecodeTimeFlowStringTime(str string, timeNow int64) string {
|
||||
timeNow = timeNow / 1000
|
||||
timeDigits := []int{}
|
||||
|
||||
if len(str) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
for timeNow > 0 {
|
||||
timeDigits = append(timeDigits, int(timeNow%int64(10)))
|
||||
timeNow = timeNow / 10
|
||||
}
|
||||
|
||||
res := make([]int32, utf8.RuneCountInString(str))
|
||||
secret := []rune(str)
|
||||
add := false
|
||||
if len(secret)%2 == 0 {
|
||||
add = true
|
||||
}
|
||||
timeDigitIndex := (len(secret) - 1) % len(timeDigits)
|
||||
for pos := range secret {
|
||||
// take single digit with index timeDigitIndex from timeNow
|
||||
newIndex := len(res) - 1 - pos
|
||||
if add {
|
||||
newIndex = newIndex + timeDigits[timeDigitIndex]*timeDigitIndex
|
||||
} else {
|
||||
newIndex = 2*timeDigitIndex*timeDigits[timeDigitIndex] - newIndex
|
||||
}
|
||||
|
||||
if newIndex < 0 {
|
||||
newIndex = newIndex * -1
|
||||
}
|
||||
|
||||
newIndex = newIndex % len(secret)
|
||||
|
||||
res[len(res)-1-pos] = secret[newIndex]
|
||||
secret[newIndex], secret[len(res)-1-pos] = secret[len(res)-1-pos], secret[newIndex]
|
||||
secret = secret[:len(secret)-1]
|
||||
|
||||
add = !add
|
||||
// Add timeDigitIndex by 1, but does not exceed total digits in timeNow
|
||||
timeDigitIndex--
|
||||
if timeDigitIndex < 0 {
|
||||
timeDigitIndex = len(timeDigits) - 1
|
||||
}
|
||||
}
|
||||
|
||||
return string(res)
|
||||
}
|
||||
|
||||
func ToPtr[T any](v T) *T {
|
||||
return &v
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ func CreatNestedFile(path string) (*os.File, error) {
|
||||
if !Exists(basePath) {
|
||||
err := os.MkdirAll(basePath, 0700)
|
||||
if err != nil {
|
||||
Log().Warning("Failed to create directory: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -30,6 +29,19 @@ func CreatNestedFile(path string) (*os.File, error) {
|
||||
return os.Create(path)
|
||||
}
|
||||
|
||||
// CreatNestedFolder creates a folder with the given path, if the directory does not exist,
|
||||
// it will be created recursively.
|
||||
func CreatNestedFolder(path string) error {
|
||||
if !Exists(path) {
|
||||
err := os.MkdirAll(path, 0700)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsEmpty 返回给定目录是否为空目录
|
||||
func IsEmpty(name string) (bool, error) {
|
||||
f, err := os.Open(name)
|
||||
@@ -44,3 +56,21 @@ func IsEmpty(name string) (bool, error) {
|
||||
}
|
||||
return false, err // Either not empty or error, suits both cases
|
||||
}
|
||||
|
||||
type CallbackReader struct {
|
||||
reader io.Reader
|
||||
callback func(int64)
|
||||
}
|
||||
|
||||
func NewCallbackReader(reader io.Reader, callback func(int64)) *CallbackReader {
|
||||
return &CallbackReader{
|
||||
reader: reader,
|
||||
callback: callback,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *CallbackReader) Read(p []byte) (n int, err error) {
|
||||
n, err = r.reader.Read(p)
|
||||
r.callback(int64(n))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ func (ll *Logger) Debug(format string, v ...interface{}) {
|
||||
// return
|
||||
// }
|
||||
// msg := fmt.Sprintf("[SQL] %s", v...)
|
||||
// ll.Println(msg)
|
||||
// ll.println(msg)
|
||||
//}
|
||||
|
||||
// BuildLogger 构建logger
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
DataFolder = "data"
|
||||
)
|
||||
|
||||
var UseWorkingDir = false
|
||||
|
||||
// DotPathToStandardPath 将","分割的路径转换为标准路径
|
||||
func DotPathToStandardPath(path string) string {
|
||||
return "/" + strings.Replace(path, ",", "/", -1)
|
||||
@@ -50,6 +57,10 @@ func FormSlash(old string) string {
|
||||
|
||||
// RelativePath 获取相对可执行文件的路径
|
||||
func RelativePath(name string) string {
|
||||
if UseWorkingDir {
|
||||
return name
|
||||
}
|
||||
|
||||
if filepath.IsAbs(name) {
|
||||
return name
|
||||
}
|
||||
@@ -57,3 +68,41 @@ func RelativePath(name string) string {
|
||||
return filepath.Join(filepath.Dir(e), name)
|
||||
}
|
||||
|
||||
// DataPath relative path for store persist data file
|
||||
func DataPath(child string) string {
|
||||
dataPath := RelativePath(DataFolder)
|
||||
if !Exists(dataPath) {
|
||||
os.MkdirAll(dataPath, 0700)
|
||||
}
|
||||
|
||||
if filepath.IsAbs(child) {
|
||||
return child
|
||||
}
|
||||
|
||||
return filepath.Join(dataPath, child)
|
||||
}
|
||||
|
||||
// MkdirIfNotExist create directory if not exist
|
||||
func MkdirIfNotExist(ctx context.Context, p string) {
|
||||
if !Exists(p) {
|
||||
os.MkdirAll(p, 0700)
|
||||
}
|
||||
}
|
||||
|
||||
// SlashClean is equivalent to but slightly more efficient than
|
||||
// path.Clean("/" + name).
|
||||
func SlashClean(name string) string {
|
||||
if name == "" || name[0] != '/' {
|
||||
name = "/" + name
|
||||
}
|
||||
return path.Clean(name)
|
||||
}
|
||||
|
||||
// Ext returns the file name extension used by path, without the dot.
|
||||
func Ext(name string) string {
|
||||
ext := strings.ToLower(filepath.Ext(name))
|
||||
if len(ext) > 0 {
|
||||
ext = ext[1:]
|
||||
}
|
||||
return ext
|
||||
}
|
||||
|
||||
@@ -19,13 +19,13 @@ func SetSession(c *gin.Context, list map[string]interface{}) {
|
||||
}
|
||||
|
||||
// GetSession 获取session
|
||||
func GetSession(c *gin.Context, key string) interface{} {
|
||||
func GetSession(c *gin.Context, key any) interface{} {
|
||||
s := sessions.Default(c)
|
||||
return s.Get(key)
|
||||
}
|
||||
|
||||
// DeleteSession 删除session
|
||||
func DeleteSession(c *gin.Context, key string) {
|
||||
func DeleteSession(c *gin.Context, key any) {
|
||||
s := sessions.Default(c)
|
||||
s.Delete(key)
|
||||
s.Save()
|
||||
|
||||
Reference in New Issue
Block a user