mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-05-07 02:26:00 +08:00
v3 - main to cut out
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func CorsHandler() gin.HandlerFunc {
|
||||
return func(context *gin.Context) {
|
||||
context.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
context.Header("Access-Control-Allow-Methods", "*")
|
||||
context.Header("Access-Control-Allow-Headers", "*")
|
||||
context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") // 跨域关键设置 让浏览器可以解析
|
||||
context.Header("Access-Control-Max-Age", "172800") // 缓存请求信息 单位为秒
|
||||
context.Header("Access-Control-Allow-Credentials", "false") // 跨域请求是否需要带cookie信息 默认设置为true
|
||||
context.Header("content-type", "application/json") // 设置返回格式是json
|
||||
//Release all option pre-requests
|
||||
if context.Request.Method == http.MethodOptions {
|
||||
context.JSON(http.StatusOK, "Options Request!")
|
||||
}
|
||||
context.Next()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/constant"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Determine whether the given path is a folder
|
||||
func IsDir(path string) bool {
|
||||
s, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return s.IsDir()
|
||||
}
|
||||
|
||||
// Determine whether the given path is a file
|
||||
func IsFile(path string) bool {
|
||||
return !IsDir(path)
|
||||
}
|
||||
|
||||
// Create a directory
|
||||
func MkDir(path string) error {
|
||||
return os.MkdirAll(path, os.ModePerm)
|
||||
}
|
||||
|
||||
func GetNewFileNameAndContentType(fileName string, fileType int) (string, string) {
|
||||
suffix := path.Ext(fileName)
|
||||
newName := fmt.Sprintf("%d-%d%s", time.Now().UnixNano(), rand.Int(), fileName)
|
||||
contentType := ""
|
||||
if fileType == constant.ImageType {
|
||||
contentType = "image/" + suffix[1:]
|
||||
}
|
||||
return newName, contentType
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/config"
|
||||
"net"
|
||||
)
|
||||
|
||||
var ServerIP = ""
|
||||
|
||||
func init() {
|
||||
//fixme In the configuration file, ip takes precedence, if not, get the valid network card ip of the machine
|
||||
if config.Config.ServerIP != "" {
|
||||
ServerIP = config.Config.ServerIP
|
||||
return
|
||||
}
|
||||
|
||||
// see https://gist.github.com/jniltinho/9787946#gistcomment-3019898
|
||||
conn, err := net.Dial("udp", "8.8.8.8:80")
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
|
||||
defer conn.Close()
|
||||
localAddr := conn.LocalAddr().(*net.UDPAddr)
|
||||
ServerIP = localAddr.IP.String()
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/nfnt/resize"
|
||||
"golang.org/x/image/bmp"
|
||||
"image"
|
||||
"image/gif"
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func GenSmallImage(src, dst string) error {
|
||||
fIn, _ := os.Open(src)
|
||||
defer fIn.Close()
|
||||
|
||||
fOut, _ := os.Create(dst)
|
||||
defer fOut.Close()
|
||||
|
||||
if err := scale(fIn, fOut, 0, 0, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func scale(in io.Reader, out io.Writer, width, height, quality int) error {
|
||||
origin, fm, err := image.Decode(in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if width == 0 || height == 0 {
|
||||
width = origin.Bounds().Max.X / 2
|
||||
height = origin.Bounds().Max.Y / 2
|
||||
}
|
||||
if quality == 0 {
|
||||
quality = 25
|
||||
}
|
||||
canvas := resize.Thumbnail(uint(width), uint(height), origin, resize.Lanczos3)
|
||||
|
||||
switch fm {
|
||||
case "jpeg":
|
||||
return jpeg.Encode(out, canvas, &jpeg.Options{quality})
|
||||
case "png":
|
||||
return png.Encode(out, canvas)
|
||||
case "gif":
|
||||
return gif.Encode(out, canvas, &gif.Options{})
|
||||
case "bmp":
|
||||
return bmp.Encode(out, canvas)
|
||||
default:
|
||||
return errors.New("ERROR FORMAT")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Map struct {
|
||||
sync.RWMutex
|
||||
m map[interface{}]interface{}
|
||||
}
|
||||
|
||||
func (m *Map) init() {
|
||||
if m.m == nil {
|
||||
m.m = make(map[interface{}]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Map) UnsafeGet(key interface{}) interface{} {
|
||||
if m.m == nil {
|
||||
return nil
|
||||
} else {
|
||||
return m.m[key]
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Map) Get(key interface{}) interface{} {
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
return m.UnsafeGet(key)
|
||||
}
|
||||
|
||||
func (m *Map) UnsafeSet(key interface{}, value interface{}) {
|
||||
m.init()
|
||||
m.m[key] = value
|
||||
}
|
||||
|
||||
func (m *Map) Set(key interface{}, value interface{}) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
m.UnsafeSet(key, value)
|
||||
}
|
||||
|
||||
func (m *Map) TestAndSet(key interface{}, value interface{}) interface{} {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
m.init()
|
||||
|
||||
if v, ok := m.m[key]; ok {
|
||||
return v
|
||||
} else {
|
||||
m.m[key] = value
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Map) UnsafeDel(key interface{}) {
|
||||
m.init()
|
||||
delete(m.m, key)
|
||||
}
|
||||
|
||||
func (m *Map) Del(key interface{}) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
m.UnsafeDel(key)
|
||||
}
|
||||
|
||||
func (m *Map) UnsafeLen() int {
|
||||
if m.m == nil {
|
||||
return 0
|
||||
} else {
|
||||
return len(m.m)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Map) Len() int {
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
return m.UnsafeLen()
|
||||
}
|
||||
|
||||
func (m *Map) UnsafeRange(f func(interface{}, interface{})) {
|
||||
if m.m == nil {
|
||||
return
|
||||
}
|
||||
for k, v := range m.m {
|
||||
f(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Map) RLockRange(f func(interface{}, interface{})) {
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
m.UnsafeRange(f)
|
||||
}
|
||||
|
||||
func (m *Map) LockRange(f func(interface{}, interface{})) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
m.UnsafeRange(f)
|
||||
}
|
||||
|
||||
func MapToJsonString(param map[string]interface{}) string {
|
||||
dataType, _ := json.Marshal(param)
|
||||
dataString := string(dataType)
|
||||
return dataString
|
||||
}
|
||||
func MapIntToJsonString(param map[string]int32) string {
|
||||
dataType, _ := json.Marshal(param)
|
||||
dataString := string(dataType)
|
||||
return dataString
|
||||
}
|
||||
func JsonStringToMap(str string) (tempMap map[string]int32) {
|
||||
_ = json.Unmarshal([]byte(str), &tempMap)
|
||||
return tempMap
|
||||
}
|
||||
func GetSwitchFromOptions(Options map[string]bool, key string) (result bool) {
|
||||
if flag, ok := Options[key]; !ok || flag {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
func SetSwitchFromOptions(options map[string]bool, key string, value bool) {
|
||||
if options == nil {
|
||||
options = make(map[string]bool, 5)
|
||||
}
|
||||
options[key] = value
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
func Md5(s string) string {
|
||||
h := md5.New()
|
||||
h.Write([]byte(s))
|
||||
cipher := h.Sum(nil)
|
||||
return hex.EncodeToString(cipher)
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
** description("").
|
||||
** copyright('tuoyun,www.tuoyun.net').
|
||||
** author("fg,Gordon@tuoyun.net").
|
||||
** time(2021/4/8 15:09).
|
||||
*/
|
||||
package utils
|
||||
|
||||
import (
|
||||
"Open_IM/pkg/common/constant"
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func IntToString(i int) string {
|
||||
return strconv.FormatInt(int64(i), 10)
|
||||
}
|
||||
|
||||
func StringToInt(i string) int {
|
||||
j, _ := strconv.Atoi(i)
|
||||
return j
|
||||
}
|
||||
func StringToInt64(i string) int64 {
|
||||
j, _ := strconv.ParseInt(i, 10, 64)
|
||||
return j
|
||||
}
|
||||
func StringToInt32(i string) int32 {
|
||||
j, _ := strconv.ParseInt(i, 10, 64)
|
||||
return int32(j)
|
||||
}
|
||||
func Int32ToString(i int32) string {
|
||||
return strconv.FormatInt(int64(i), 10)
|
||||
}
|
||||
|
||||
//judge a string whether in the string list
|
||||
func IsContain(target string, List []string) bool {
|
||||
for _, element := range List {
|
||||
|
||||
if target == element {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func IsContainInt32(target int32, List []int32) bool {
|
||||
for _, element := range List {
|
||||
if target == element {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func InterfaceArrayToStringArray(data []interface{}) (i []string) {
|
||||
for _, param := range data {
|
||||
i = append(i, param.(string))
|
||||
}
|
||||
return i
|
||||
}
|
||||
func StructToJsonString(param interface{}) string {
|
||||
dataType, _ := json.Marshal(param)
|
||||
dataString := string(dataType)
|
||||
return dataString
|
||||
}
|
||||
|
||||
func StructToJsonBytes(param interface{}) []byte {
|
||||
dataType, _ := json.Marshal(param)
|
||||
return dataType
|
||||
}
|
||||
|
||||
//The incoming parameter must be a pointer
|
||||
func JsonStringToStruct(s string, args interface{}) error {
|
||||
err := json.Unmarshal([]byte(s), args)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetMsgID(sendID string) string {
|
||||
t := int64ToString(GetCurrentTimestampByNano())
|
||||
return Md5(t + sendID + int64ToString(rand.Int63n(GetCurrentTimestampByNano())))
|
||||
}
|
||||
func GetConversationIDBySessionType(sourceID string, sessionType int) string {
|
||||
switch sessionType {
|
||||
case constant.SingleChatType:
|
||||
return "single_" + sourceID
|
||||
case constant.GroupChatType:
|
||||
return "group_" + sourceID
|
||||
}
|
||||
return ""
|
||||
}
|
||||
func int64ToString(i int64) string {
|
||||
return strconv.FormatInt(i, 10)
|
||||
}
|
||||
func Int64ToString(i int64) string {
|
||||
return strconv.FormatInt(i, 10)
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
** description("").
|
||||
** copyright('tuoyun,www.tuoyun.net').
|
||||
** author("fg,Gordon@tuoyun.net").
|
||||
** time(2021/2/22 11:52).
|
||||
*/
|
||||
package utils
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
TimeOffset = 8 * 3600 //8 hour offset
|
||||
HalfOffset = 12 * 3600 //Half-day hourly offset
|
||||
)
|
||||
|
||||
//Get the current timestamp by Second
|
||||
func GetCurrentTimestampBySecond() int64 {
|
||||
return time.Now().Unix()
|
||||
}
|
||||
|
||||
//Convert timestamp to time.Time type
|
||||
func UnixSecondToTime(second int64) time.Time {
|
||||
return time.Unix(second, 0)
|
||||
}
|
||||
|
||||
//Convert nano timestamp to time.Time type
|
||||
func UnixNanoSecondToTime(nanoSecond int64) time.Time {
|
||||
return time.Unix(0, nanoSecond)
|
||||
}
|
||||
func UnixMillSecondToTime(millSecond int64) time.Time {
|
||||
return time.Unix(0, millSecond*1e6)
|
||||
}
|
||||
|
||||
//Get the current timestamp by Nano
|
||||
func GetCurrentTimestampByNano() int64 {
|
||||
return time.Now().UnixNano()
|
||||
}
|
||||
|
||||
//Get the current timestamp by Mill
|
||||
func GetCurrentTimestampByMill() int64 {
|
||||
return time.Now().UnixNano() / 1e6
|
||||
}
|
||||
|
||||
//Get the timestamp at 0 o'clock of the day
|
||||
func GetCurDayZeroTimestamp() int64 {
|
||||
timeStr := time.Now().Format("2006-01-02")
|
||||
t, _ := time.Parse("2006-01-02", timeStr)
|
||||
return t.Unix() - TimeOffset
|
||||
}
|
||||
|
||||
//Get the timestamp at 12 o'clock on the day
|
||||
func GetCurDayHalfTimestamp() int64 {
|
||||
return GetCurDayZeroTimestamp() + HalfOffset
|
||||
|
||||
}
|
||||
|
||||
//Get the formatted time at 0 o'clock of the day, the format is "2006-01-02_00-00-00"
|
||||
func GetCurDayZeroTimeFormat() string {
|
||||
return time.Unix(GetCurDayZeroTimestamp(), 0).Format("2006-01-02_15-04-05")
|
||||
}
|
||||
|
||||
//Get the formatted time at 12 o'clock of the day, the format is "2006-01-02_12-00-00"
|
||||
func GetCurDayHalfTimeFormat() string {
|
||||
return time.Unix(GetCurDayZeroTimestamp()+HalfOffset, 0).Format("2006-01-02_15-04-05")
|
||||
}
|
||||
func GetTimeStampByFormat(datetime string) string {
|
||||
timeLayout := "2006-01-02 15:04:05"
|
||||
loc, _ := time.LoadLocation("Local")
|
||||
tmp, _ := time.ParseInLocation(timeLayout, datetime, loc)
|
||||
timestamp := tmp.Unix()
|
||||
return strconv.FormatInt(timestamp, 10)
|
||||
}
|
||||
|
||||
func TimeStringFormatTimeUnix(timeFormat string, timeSrc string) int64 {
|
||||
tm, _ := time.Parse(timeFormat, timeSrc)
|
||||
return tm.Unix()
|
||||
}
|
||||
|
||||
func TimeStringToTime(timeString string) (time.Time, error) {
|
||||
t, err := time.Parse("2006-01-02", timeString)
|
||||
return t, err
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/pkg/errors"
|
||||
"math/rand"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// copy a by b b->a
|
||||
func CopyStructFields(a interface{}, b interface{}, fields ...string) (err error) {
|
||||
return copier.Copy(a, b)
|
||||
}
|
||||
|
||||
func Wrap(err error, message string) error {
|
||||
return errors.Wrap(err, "==> "+printCallerNameAndLine()+message)
|
||||
}
|
||||
|
||||
func WithMessage(err error, message string) error {
|
||||
return errors.WithMessage(err, "==> "+printCallerNameAndLine()+message)
|
||||
}
|
||||
|
||||
func printCallerNameAndLine() string {
|
||||
pc, _, line, _ := runtime.Caller(2)
|
||||
return runtime.FuncForPC(pc).Name() + "()@" + strconv.Itoa(line) + ": "
|
||||
}
|
||||
|
||||
func GetSelfFuncName() string {
|
||||
pc, _, _, _ := runtime.Caller(1)
|
||||
return cleanUpFuncName(runtime.FuncForPC(pc).Name())
|
||||
}
|
||||
func cleanUpFuncName(funcName string) string {
|
||||
end := strings.LastIndex(funcName, ".")
|
||||
if end == -1 {
|
||||
return ""
|
||||
}
|
||||
return funcName[end+1:]
|
||||
}
|
||||
|
||||
//Get the intersection of two slices
|
||||
func Intersect(slice1, slice2 []uint32) []uint32 {
|
||||
m := make(map[uint32]bool)
|
||||
n := make([]uint32, 0)
|
||||
for _, v := range slice1 {
|
||||
m[v] = true
|
||||
}
|
||||
for _, v := range slice2 {
|
||||
flag, _ := m[v]
|
||||
if flag {
|
||||
n = append(n, v)
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
//Get the diff of two slices
|
||||
func Difference(slice1, slice2 []uint32) []uint32 {
|
||||
m := make(map[uint32]bool)
|
||||
n := make([]uint32, 0)
|
||||
inter := Intersect(slice1, slice2)
|
||||
for _, v := range inter {
|
||||
m[v] = true
|
||||
}
|
||||
for _, v := range slice1 {
|
||||
if !m[v] {
|
||||
n = append(n, v)
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range slice2 {
|
||||
if !m[v] {
|
||||
n = append(n, v)
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
func OperationIDGenerator() string {
|
||||
return strconv.FormatInt(time.Now().UnixNano()+int64(rand.Uint32()), 10)
|
||||
}
|
||||
|
||||
func RemoveRepeatedStringInList(slc []string) []string {
|
||||
var result []string
|
||||
tempMap := map[string]byte{}
|
||||
for _, e := range slc {
|
||||
l := len(tempMap)
|
||||
tempMap[e] = 0
|
||||
if len(tempMap) != l {
|
||||
result = append(result, e)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user