mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-05-13 13:35:59 +08:00
fix: reset branch. (#1277)
* fix: to start im or chat, ZooKeeper must be started first. * fix: msg gateway start output err info Signed-off-by: Gordon <1432970085@qq.com> * fix: msg gateway start output err info Signed-off-by: Gordon <1432970085@qq.com> * chore: package path changes Signed-off-by: withchao <993506633@qq.com> * fix: go mod update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * chore: package path changes Signed-off-by: withchao <993506633@qq.com> * chore: package path changes Signed-off-by: withchao <993506633@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * fix: token update Signed-off-by: Gordon <1432970085@qq.com> * fix: get all userID Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: msggateway add online status call Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * refactor: log change Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * refactor: log change Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * chore: network mode change Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * cicd: robot automated Change Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * cicd: robot automated Change Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * cicd: robot automated Change Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * feat: add api of get server time Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * feat: remove go work sum Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * cicd: robot automated Change Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix: pull message add isRead field Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: check msg-transfer script Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: script update Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: start don't kill old process Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * cicd: robot automated Change Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix: check component Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: pull message set isRead only message come from single. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * cicd: robot automated Change Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix: multiple gateway kick user each other. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: multiple gateway kick user each other. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: multiple gateway kick user each other. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: multiple gateway kick user each other. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: multiple gateway kick user each other. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: multiple gateway kick user each other. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * cicd: robot automated Change Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * fix: multiple gateway kick user each other. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: add ex field to update group info. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * cicd: robot automated Change * cicd: robot automated Change * refactor: change project module name. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * refactor: change project module name. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * refactor: change project module name. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * cicd: robot automated Change * test: for pressure test. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * test: for pressure test. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * test: for pressure test. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * test: message log. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * cicd: robot automated Change * fxi: component check output valid info. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fxi: component check output valid info. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * test: send message test log. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * cicd: robot automated Change * cicd: robot automated Change * test: remove info log. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * feat: api of send message add sendTime field. Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> * fix: add callback for update user's info. * cicd: robot automated Change * fix: change callback command name. * cicd: robot automated Change * fix: single chat unread status change. * fix: single chat unread status change. * fix: single chat unread status change. * fix: user status change. * cicd: robot automated Change * fix: user status change. * fix: user status change. * fix: user status change. * cicd: robot automated Change * fix: ws close when user logout. * fix: remove repeat platform on online status. * cicd: robot automated Change * fix: api send messages for notification conversation . * fix: api send messages for notification conversation . * fix: api send messages for notification conversation . * fix: api send messages for notification conversation . * fix: api send messages for notification conversation . * fix: api send messages for notification conversation. * fix: api send messages for notification conversation. * fix: api send messages for notification conversation. * fix: api send messages for notification conversation. * fix: api send messages for notification conversation. * fix: api send messages for notification conversation. * re: remove router of unsubscribeStatus. * re: remove router of unsubscribeStatus. * re: remove router of unsubscribeStatus. * re: remove router of unsubscribeStatus. * fix: reset branch * fix: not support redis cluster. CROSSSLOT Keys in request don't hash to the same slot * fix: update user.FaceURL do not trigger GroupMemberInfoSetNotification * cicd: robot automated Change * fix: api send messages for notification conversation. * fix: api send messages for notification conversation. --------- Signed-off-by: Gordon <1432970085@qq.com> Signed-off-by: withchao <993506633@qq.com> Signed-off-by: Gordon <46924906+FGadvancer@users.noreply.github.com> Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: withchao <993506633@qq.com> Co-authored-by: Xinwei Xiong <3293172751NSS@gmail.com> Co-authored-by: FGadvancer <FGadvancer@users.noreply.github.com> Co-authored-by: withchao <withchao@users.noreply.github.com>
This commit is contained in:
@@ -39,7 +39,6 @@ func ImageStat(reader io.Reader) (image.Image, string, error) {
|
||||
|
||||
func ImageWidthHeight(img image.Image) (int, int) {
|
||||
bounds := img.Bounds().Max
|
||||
|
||||
return bounds.X, bounds.Y
|
||||
}
|
||||
|
||||
@@ -48,27 +47,27 @@ func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
||||
imgWidth := bounds.Max.X
|
||||
imgHeight := bounds.Max.Y
|
||||
|
||||
// Calculate scaling ratio
|
||||
// 计算缩放比例
|
||||
scaleWidth := float64(maxWidth) / float64(imgWidth)
|
||||
scaleHeight := float64(maxHeight) / float64(imgHeight)
|
||||
|
||||
// If both maxWidth and maxHeight are 0, return the original image
|
||||
// 如果都为0,则不缩放,返回原始图片
|
||||
if maxWidth == 0 && maxHeight == 0 {
|
||||
return img
|
||||
}
|
||||
|
||||
// If both maxWidth and maxHeight are greater than 0, choose the smaller scaling ratio to maintain aspect ratio
|
||||
// 如果宽度和高度都大于0,则选择较小的缩放比例,以保持宽高比
|
||||
if maxWidth > 0 && maxHeight > 0 {
|
||||
scale := scaleWidth
|
||||
if scaleHeight < scaleWidth {
|
||||
scale = scaleHeight
|
||||
}
|
||||
|
||||
// Calculate thumbnail size
|
||||
// 计算缩略图尺寸
|
||||
thumbnailWidth := int(float64(imgWidth) * scale)
|
||||
thumbnailHeight := int(float64(imgHeight) * scale)
|
||||
|
||||
// Generate thumbnail using the Resample method of the "image" library
|
||||
// 使用"image"库的Resample方法生成缩略图
|
||||
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
||||
for y := 0; y < thumbnailHeight; y++ {
|
||||
for x := 0; x < thumbnailWidth; x++ {
|
||||
@@ -81,12 +80,12 @@ func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
||||
return thumbnail
|
||||
}
|
||||
|
||||
// If only maxWidth or maxHeight is specified, generate thumbnail according to the "max not exceed" rule
|
||||
// 如果只指定了宽度或高度,则根据最大不超过的规则生成缩略图
|
||||
if maxWidth > 0 {
|
||||
thumbnailWidth := maxWidth
|
||||
thumbnailHeight := int(float64(imgHeight) * scaleWidth)
|
||||
|
||||
// Generate thumbnail using the Resample method of the "image" library
|
||||
// 使用"image"库的Resample方法生成缩略图
|
||||
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
||||
for y := 0; y < thumbnailHeight; y++ {
|
||||
for x := 0; x < thumbnailWidth; x++ {
|
||||
@@ -103,7 +102,7 @@ func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
||||
thumbnailWidth := int(float64(imgWidth) * scaleHeight)
|
||||
thumbnailHeight := maxHeight
|
||||
|
||||
// Generate thumbnail using the Resample method of the "image" library
|
||||
// 使用"image"库的Resample方法生成缩略图
|
||||
thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight))
|
||||
for y := 0; y < thumbnailHeight; y++ {
|
||||
for x := 0; x < thumbnailWidth; x++ {
|
||||
@@ -116,6 +115,6 @@ func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image {
|
||||
return thumbnail
|
||||
}
|
||||
|
||||
// By default, return the original image
|
||||
// 默认情况下,返回原始图片
|
||||
return img
|
||||
}
|
||||
|
||||
+49
-126
@@ -111,7 +111,6 @@ func NewMinio() (s3.Interface, error) {
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
fmt.Println("init minio error:", err)
|
||||
}
|
||||
|
||||
return m, nil
|
||||
}
|
||||
|
||||
@@ -142,9 +141,8 @@ func (m *Minio) initMinio(ctx context.Context) error {
|
||||
return fmt.Errorf("check bucket exists error: %w", err)
|
||||
}
|
||||
if !exists {
|
||||
err2 := m.core.Client.MakeBucket(ctx, conf.Bucket, minio.MakeBucketOptions{})
|
||||
if err2 != nil {
|
||||
return fmt.Errorf("make bucket error: %w", err2)
|
||||
if err := m.core.Client.MakeBucket(ctx, conf.Bucket, minio.MakeBucketOptions{}); err != nil {
|
||||
return fmt.Errorf("make bucket error: %w", err)
|
||||
}
|
||||
}
|
||||
if conf.PublicRead {
|
||||
@@ -152,9 +150,8 @@ func (m *Minio) initMinio(ctx context.Context) error {
|
||||
`{"Version": "2012-10-17","Statement": [{"Action": ["s3:GetObject","s3:PutObject"],"Effect": "Allow","Principal": {"AWS": ["*"]},"Resource": ["arn:aws:s3:::%s/*"],"Sid": ""}]}`,
|
||||
conf.Bucket,
|
||||
)
|
||||
err2 := m.core.Client.SetBucketPolicy(ctx, conf.Bucket, policy)
|
||||
if err2 != nil {
|
||||
return err2
|
||||
if err := m.core.Client.SetBucketPolicy(ctx, conf.Bucket, policy); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
m.location, err = m.core.Client.GetBucketLocation(ctx, conf.Bucket)
|
||||
@@ -185,7 +182,6 @@ func (m *Minio) initMinio(ctx context.Context) error {
|
||||
vblc.Elem().Elem().Interface().(interface{ Set(string, string) }).Set(conf.Bucket, m.location)
|
||||
}()
|
||||
m.init = true
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -209,7 +205,6 @@ func (m *Minio) InitiateMultipartUpload(ctx context.Context, name string) (*s3.I
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.InitiateMultipartUploadResult{
|
||||
Bucket: m.bucket,
|
||||
Key: name,
|
||||
@@ -232,7 +227,6 @@ func (m *Minio) CompleteMultipartUpload(ctx context.Context, uploadID string, na
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.CompleteMultipartUploadResult{
|
||||
Location: upload.Location,
|
||||
Bucket: upload.Bucket,
|
||||
@@ -255,7 +249,6 @@ func (m *Minio) PartSize(ctx context.Context, size int64) (int64, error) {
|
||||
if size%maxNumSize != 0 {
|
||||
partSize++
|
||||
}
|
||||
|
||||
return partSize, nil
|
||||
}
|
||||
|
||||
@@ -289,7 +282,6 @@ func (m *Minio) AuthSign(ctx context.Context, uploadID string, name string, expi
|
||||
if m.prefix != "" {
|
||||
result.URL = m.signEndpoint + m.prefix + "/" + m.bucket + "/" + name
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -304,7 +296,6 @@ func (m *Minio) PresignedPutObject(ctx context.Context, name string, expire time
|
||||
if m.prefix != "" {
|
||||
rawURL.Path = path.Join(m.prefix, rawURL.Path)
|
||||
}
|
||||
|
||||
return rawURL.String(), nil
|
||||
}
|
||||
|
||||
@@ -312,7 +303,6 @@ func (m *Minio) DeleteObject(ctx context.Context, name string) error {
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.core.Client.RemoveObject(ctx, m.bucket, name, minio.RemoveObjectOptions{})
|
||||
}
|
||||
|
||||
@@ -324,7 +314,6 @@ func (m *Minio) StatObject(ctx context.Context, name string) (*s3.ObjectInfo, er
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.ObjectInfo{
|
||||
ETag: strings.ToLower(info.ETag),
|
||||
Key: info.Key,
|
||||
@@ -347,7 +336,6 @@ func (m *Minio) CopyObject(ctx context.Context, src string, dst string) (*s3.Cop
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &s3.CopyObjectInfo{
|
||||
Key: dst,
|
||||
ETag: strings.ToLower(result.ETag),
|
||||
@@ -358,23 +346,20 @@ func (m *Minio) IsNotFound(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
var minioErr minio.ErrorResponse
|
||||
if errors.As(err, &minio.ErrorResponse{}) {
|
||||
return minioErr.StatusCode == http.StatusNotFound || minioErr.Code == "NoSuchKey"
|
||||
switch e := err.(type) {
|
||||
case minio.ErrorResponse:
|
||||
return e.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
||||
case *minio.ErrorResponse:
|
||||
return e.StatusCode == http.StatusNotFound || e.Code == "NoSuchKey"
|
||||
default:
|
||||
return false
|
||||
}
|
||||
var minioErr2 *minio.ErrorResponse
|
||||
if errors.As(err, &minioErr2) {
|
||||
return minioErr2.StatusCode == http.StatusNotFound || minioErr2.Code == "NoSuchKey"
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *Minio) AbortMultipartUpload(ctx context.Context, uploadID string, name string) error {
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.core.AbortMultipartUpload(ctx, m.bucket, name, uploadID)
|
||||
}
|
||||
|
||||
@@ -401,7 +386,6 @@ func (m *Minio) ListUploadedParts(ctx context.Context, uploadID string, name str
|
||||
Size: part.Size,
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -426,17 +410,14 @@ func (m *Minio) presignedGetObject(ctx context.Context, name string, expire time
|
||||
if m.prefix != "" {
|
||||
rawURL.Path = path.Join(m.prefix, rawURL.Path)
|
||||
}
|
||||
|
||||
return rawURL.String(), nil
|
||||
}
|
||||
|
||||
func (m *Minio) getImageInfoForAccessURL(
|
||||
ctx context.Context,
|
||||
name string,
|
||||
expire time.Duration,
|
||||
opt *s3.AccessURLOption,
|
||||
reqParams url.Values,
|
||||
) (fileInfo *s3.ObjectInfo, objectInfoPath, msg string, err error) {
|
||||
func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||
if err := m.initMinio(ctx); err != nil {
|
||||
return "", err
|
||||
}
|
||||
reqParams := make(url.Values)
|
||||
if opt != nil {
|
||||
if opt.ContentType != "" {
|
||||
reqParams.Set("response-content-type", opt.ContentType)
|
||||
@@ -446,47 +427,35 @@ func (m *Minio) getImageInfoForAccessURL(
|
||||
}
|
||||
}
|
||||
if opt.Image == nil || (opt.Image.Width < 0 && opt.Image.Height < 0 && opt.Image.Format == "") || (opt.Image.Width > maxImageWidth || opt.Image.Height > maxImageHeight) {
|
||||
msg, err = m.presignedGetObject(ctx, name, expire, reqParams)
|
||||
|
||||
return nil, "", msg, err
|
||||
return m.presignedGetObject(ctx, name, expire, reqParams)
|
||||
}
|
||||
fileInfo, err = m.StatObject(ctx, name)
|
||||
objectInfoPath = path.Join(pathInfo, fileInfo.ETag, "image.json")
|
||||
fileInfo, err := m.StatObject(ctx, name)
|
||||
if err != nil {
|
||||
return nil, "", msg, err
|
||||
return "", err
|
||||
}
|
||||
if fileInfo.Size > maxImageSize {
|
||||
return nil, "", "", errors.New("file size too large")
|
||||
return "", errors.New("file size too large")
|
||||
}
|
||||
|
||||
return fileInfo, objectInfoPath, "", nil
|
||||
}
|
||||
|
||||
func (m *Minio) loadImgDataForAccessURL(objectInfoPath string, ctx context.Context, name string, info *minioImageInfo) (img image.Image, msg string, err error) {
|
||||
var data []byte
|
||||
data, err = m.getObjectData(ctx, objectInfoPath, 1024)
|
||||
|
||||
//nolint:nestif //easy enough to understand
|
||||
objectInfoPath := path.Join(pathInfo, fileInfo.ETag, "image.json")
|
||||
var (
|
||||
img image.Image
|
||||
info minioImageInfo
|
||||
)
|
||||
data, err := m.getObjectData(ctx, objectInfoPath, 1024)
|
||||
if err == nil {
|
||||
err = json.Unmarshal(data, &info)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("unmarshal minio image info.json error: %w", err)
|
||||
if err := json.Unmarshal(data, &info); err != nil {
|
||||
return "", fmt.Errorf("unmarshal minio image info.json error: %w", err)
|
||||
}
|
||||
if info.NotImage {
|
||||
return nil, "", errors.New("not image")
|
||||
return "", errors.New("not image")
|
||||
}
|
||||
} else if m.IsNotFound(err) {
|
||||
var reader *minio.Object
|
||||
reader, err = m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
||||
reader, err := m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
||||
if err != nil {
|
||||
return img, msg, err
|
||||
return "", err
|
||||
}
|
||||
defer reader.Close()
|
||||
var (
|
||||
imageInfo image.Image
|
||||
format string
|
||||
)
|
||||
imageInfo, format, err = ImageStat(reader)
|
||||
imageInfo, format, err := ImageStat(reader)
|
||||
if err == nil {
|
||||
info.NotImage = false
|
||||
info.Format = format
|
||||
@@ -495,22 +464,16 @@ func (m *Minio) loadImgDataForAccessURL(objectInfoPath string, ctx context.Conte
|
||||
} else {
|
||||
info.NotImage = true
|
||||
}
|
||||
|
||||
data, err = json.Marshal(&info)
|
||||
data, err := json.Marshal(&info)
|
||||
if err != nil {
|
||||
return img, msg, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
_, err = m.core.Client.PutObject(ctx, m.bucket, objectInfoPath, bytes.NewReader(data), int64(len(data)), minio.PutObjectOptions{})
|
||||
if err != nil {
|
||||
return img, msg, err
|
||||
if _, err := m.core.Client.PutObject(ctx, m.bucket, objectInfoPath, bytes.NewReader(data), int64(len(data)), minio.PutObjectOptions{}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return img, msg, err
|
||||
}
|
||||
|
||||
func (m *Minio) formatImgInfoForAccessURL(opt *s3.AccessURLOption, info *minioImageInfo, reqParams url.Values) {
|
||||
if opt.Image.Width > info.Width || opt.Image.Width <= 0 {
|
||||
opt.Image.Width = info.Width
|
||||
}
|
||||
@@ -533,24 +496,24 @@ func (m *Minio) formatImgInfoForAccessURL(opt *s3.AccessURLOption, info *minioIm
|
||||
}
|
||||
}
|
||||
reqParams.Set("response-content-type", "image/"+opt.Image.Format)
|
||||
}
|
||||
|
||||
func (m *Minio) cacheImgInfoForAccessURL(ctx context.Context, name, cacheKey string, img image.Image, expire time.Duration, opt *s3.AccessURLOption, reqParams url.Values) (string, error) {
|
||||
_, err := m.core.Client.StatObject(ctx, m.bucket, cacheKey, minio.StatObjectOptions{})
|
||||
if err == nil {
|
||||
if opt.Image.Width == info.Width && opt.Image.Height == info.Height && opt.Image.Format == info.Format {
|
||||
return m.presignedGetObject(ctx, name, expire, reqParams)
|
||||
}
|
||||
cacheKey := filepath.Join(pathInfo, fileInfo.ETag, fmt.Sprintf("image_w%d_h%d.%s", opt.Image.Width, opt.Image.Height, opt.Image.Format))
|
||||
if _, err := m.core.Client.StatObject(ctx, m.bucket, cacheKey, minio.StatObjectOptions{}); err == nil {
|
||||
return m.presignedGetObject(ctx, cacheKey, expire, reqParams)
|
||||
} else if !m.IsNotFound(err) {
|
||||
return "", err
|
||||
}
|
||||
if img == nil {
|
||||
reader, err2 := m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
||||
if err2 != nil {
|
||||
return "", err2
|
||||
reader, err := m.core.Client.GetObject(ctx, m.bucket, name, minio.GetObjectOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer reader.Close()
|
||||
img, _, err2 = ImageStat(reader)
|
||||
if err2 != nil {
|
||||
return "", err2
|
||||
img, _, err = ImageStat(reader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
thumbnail := resizeImage(img, opt.Image.Width, opt.Image.Height)
|
||||
@@ -563,48 +526,9 @@ func (m *Minio) cacheImgInfoForAccessURL(ctx context.Context, name, cacheKey str
|
||||
case formatGif:
|
||||
err = gif.Encode(buf, thumbnail, nil)
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if _, err := m.core.Client.PutObject(ctx, m.bucket, cacheKey, buf, int64(buf.Len()), minio.PutObjectOptions{}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (m *Minio) AccessURL(ctx context.Context, name string, expire time.Duration, opt *s3.AccessURLOption) (string, error) {
|
||||
errInit := m.initMinio(ctx)
|
||||
if errInit != nil {
|
||||
return "", errInit
|
||||
}
|
||||
reqParams := make(url.Values)
|
||||
fileInfo, objectInfoPath, msg, err := m.getImageInfoForAccessURL(ctx, name, expire, opt, reqParams)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
// load-cache img data
|
||||
var (
|
||||
img image.Image
|
||||
info minioImageInfo
|
||||
)
|
||||
img, msg, err = m.loadImgDataForAccessURL(objectInfoPath, ctx, name, &info)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
// format img info
|
||||
m.formatImgInfoForAccessURL(opt, &info, reqParams)
|
||||
// no need resize
|
||||
if opt.Image.Width == info.Width && opt.Image.Height == info.Height && opt.Image.Format == info.Format {
|
||||
return m.presignedGetObject(ctx, name, expire, reqParams)
|
||||
}
|
||||
// cache img
|
||||
cacheKey := filepath.Join(pathInfo, fileInfo.ETag, fmt.Sprintf("image_w%d_h%d.%s", opt.Image.Width, opt.Image.Height, opt.Image.Format))
|
||||
msg, err = m.cacheImgInfoForAccessURL(ctx, name, cacheKey, img, expire, opt, reqParams)
|
||||
if err != nil {
|
||||
return msg, err
|
||||
}
|
||||
// return cache img
|
||||
return m.presignedGetObject(ctx, cacheKey, expire, reqParams)
|
||||
}
|
||||
|
||||
@@ -617,6 +541,5 @@ func (m *Minio) getObjectData(ctx context.Context, name string, limit int64) ([]
|
||||
if limit < 0 {
|
||||
return io.ReadAll(object)
|
||||
}
|
||||
|
||||
return io.ReadAll(io.LimitReader(object, 1024))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user