243 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Go
		
	
	
	
| /*
 | |
|  * Copyright 2025 coze-dev Authors
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at
 | |
|  *
 | |
|  *     http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  */
 | |
| 
 | |
| package veimagex
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"errors"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/volcengine/volc-sdk-golang/base"
 | |
| 	veimagex "github.com/volcengine/volc-sdk-golang/service/imagex/v2"
 | |
| 
 | |
| 	"github.com/coze-dev/coze-studio/backend/infra/contract/imagex"
 | |
| 	"github.com/coze-dev/coze-studio/backend/pkg/logs"
 | |
| )
 | |
| 
 | |
| func New(ak, sk, domain, uploadHost, template string, serverIDs []string) (imagex.ImageX, error) {
 | |
| 	instance := veimagex.DefaultInstance
 | |
| 	instance.SetCredential(base.Credentials{
 | |
| 		AccessKeyID:     ak,
 | |
| 		SecretAccessKey: sk,
 | |
| 	})
 | |
| 
 | |
| 	if len(serverIDs) == 0 {
 | |
| 		return nil, errors.New("imageX serverIDs is empty")
 | |
| 	}
 | |
| 
 | |
| 	return &veImageX{
 | |
| 		ak:         ak,
 | |
| 		sk:         sk,
 | |
| 		domain:     domain,
 | |
| 		uploadHost: uploadHost,
 | |
| 		template:   template,
 | |
| 		serverIDs:  serverIDs,
 | |
| 	}, nil
 | |
| }
 | |
| 
 | |
| type veImageX struct {
 | |
| 	ak         string
 | |
| 	sk         string
 | |
| 	domain     string
 | |
| 	uploadHost string
 | |
| 	template   string
 | |
| 	serverIDs  []string
 | |
| }
 | |
| 
 | |
| func (v *veImageX) GetUploadAuth(ctx context.Context, opt ...imagex.UploadAuthOpt) (*imagex.SecurityToken, error) {
 | |
| 	return v.GetUploadAuthWithExpire(ctx, time.Hour, opt...)
 | |
| }
 | |
| 
 | |
| func (v *veImageX) GetUploadAuthWithExpire(ctx context.Context, expire time.Duration, opt ...imagex.UploadAuthOpt) (*imagex.SecurityToken, error) {
 | |
| 	// opt 转 UploadAuthOption
 | |
| 	option := &imagex.UploadAuthOption{}
 | |
| 	for _, o := range opt {
 | |
| 		o(option)
 | |
| 	}
 | |
| 	policy := &veimagex.UploadPolicy{}
 | |
| 	if len(option.ContentTypeBlackList) > 0 {
 | |
| 		policy.ContentTypeBlackList = option.ContentTypeBlackList
 | |
| 	}
 | |
| 
 | |
| 	if len(option.ContentTypeWhiteList) > 0 {
 | |
| 		policy.ContentTypeWhiteList = option.ContentTypeWhiteList
 | |
| 	}
 | |
| 
 | |
| 	if option.FileSizeUpLimit != nil {
 | |
| 		policy.FileSizeUpLimit = *option.FileSizeUpLimit
 | |
| 	}
 | |
| 
 | |
| 	if option.FileSizeBottomLimit != nil {
 | |
| 		policy.FileSizeBottomLimit = *option.FileSizeBottomLimit
 | |
| 	}
 | |
| 
 | |
| 	keyPtn := "*"
 | |
| 	if option.KeyPtn != nil {
 | |
| 		keyPtn = *option.KeyPtn
 | |
| 	}
 | |
| 
 | |
| 	instance := veimagex.DefaultInstance
 | |
| 	token, err := instance.GetUploadAuth(v.serverIDs,
 | |
| 		veimagex.WithUploadOverwrite(false),
 | |
| 		veimagex.WithUploadKeyPtn(keyPtn),
 | |
| 		veimagex.WithUploadPolicy(policy))
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return &imagex.SecurityToken{
 | |
| 		AccessKeyID:     token.AccessKeyID,
 | |
| 		SecretAccessKey: token.SecretAccessKey,
 | |
| 		SessionToken:    token.SessionToken,
 | |
| 		ExpiredTime:     token.ExpiredTime,
 | |
| 		CurrentTime:     token.CurrentTime,
 | |
| 		HostScheme:      "https",
 | |
| 	}, nil
 | |
| }
 | |
| 
 | |
| func (v *veImageX) GetResourceURL(ctx context.Context, uri string, opts ...imagex.GetResourceOpt) (*imagex.ResourceURL, error) {
 | |
| 	if len(v.serverIDs) == 0 {
 | |
| 		return nil, errors.New("serverIDs is empty")
 | |
| 	}
 | |
| 
 | |
| 	serverID := v.serverIDs[0]
 | |
| 
 | |
| 	option := &imagex.GetResourceOption{}
 | |
| 	for _, o := range opts {
 | |
| 		o(option)
 | |
| 	}
 | |
| 
 | |
| 	if option.Expire < 3600 {
 | |
| 		option.Expire = 3600
 | |
| 	}
 | |
| 
 | |
| 	if option.Template == "" {
 | |
| 		option.Template = v.template
 | |
| 	}
 | |
| 
 | |
| 	if option.Template == "" {
 | |
| 		p1 := &veimagex.GetAllImageTemplatesQuery{
 | |
| 			ServiceID: serverID,
 | |
| 			Limit:     1,
 | |
| 		}
 | |
| 
 | |
| 		instance := veimagex.DefaultInstance
 | |
| 		r1, err := instance.GetAllImageTemplates(ctx, p1)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 
 | |
| 		if len(r1.Result.Templates) == 0 {
 | |
| 			return nil, errors.New("templates is empty")
 | |
| 		}
 | |
| 
 | |
| 		option.Template = r1.Result.Templates[0].TemplateName
 | |
| 	}
 | |
| 
 | |
| 	param := &veimagex.GetResourceURLQuery{
 | |
| 		Domain:    v.domain,
 | |
| 		ServiceID: serverID,
 | |
| 		URI:       uri,
 | |
| 		Format:    option.Format,
 | |
| 		Proto:     option.Proto,
 | |
| 		Timestamp: option.Expire,
 | |
| 		Tpl:       option.Template,
 | |
| 	}
 | |
| 
 | |
| 	logs.CtxInfof(ctx, "GetResourceURL param: %+v", param)
 | |
| 
 | |
| 	instance := veimagex.DefaultInstance
 | |
| 	resp, err := instance.GetResourceURL(context.Background(), param)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return &imagex.ResourceURL{
 | |
| 		URL:        resp.Result.URL,
 | |
| 		CompactURL: resp.Result.CompactURL,
 | |
| 	}, nil
 | |
| }
 | |
| 
 | |
| func (v *veImageX) Upload(ctx context.Context, data []byte, opts ...imagex.UploadAuthOpt) (*imagex.UploadResult, error) {
 | |
| 	if len(v.serverIDs) == 0 {
 | |
| 		return nil, errors.New("serverIDs is empty")
 | |
| 	}
 | |
| 
 | |
| 	serverID := v.serverIDs[0]
 | |
| 
 | |
| 	option := &imagex.UploadAuthOption{}
 | |
| 	for _, o := range opts {
 | |
| 		o(option)
 | |
| 	}
 | |
| 
 | |
| 	overWrite := false
 | |
| 	if option.UploadOverWrite != nil {
 | |
| 		overWrite = *option.UploadOverWrite
 | |
| 	}
 | |
| 
 | |
| 	params := &veimagex.ApplyUploadImageParam{
 | |
| 		ServiceId: serverID,
 | |
| 		Overwrite: overWrite,
 | |
| 	}
 | |
| 
 | |
| 	if option.StoreKey != nil {
 | |
| 		params.StoreKeys = []string{*option.StoreKey}
 | |
| 	}
 | |
| 
 | |
| 	instance := veimagex.DefaultInstance
 | |
| 	resp, err := instance.UploadImages(params, [][]byte{data})
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if len(resp.Results) == 0 {
 | |
| 		return nil, errors.New("results is empty")
 | |
| 	}
 | |
| 
 | |
| 	r := &imagex.UploadResult{
 | |
| 		RequestId: resp.RequestId,
 | |
| 		Result: &imagex.Result{
 | |
| 			Uri:       resp.Results[0].Uri,
 | |
| 			UriStatus: resp.Results[0].UriStatus,
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	if len(resp.ImageInfos) > 0 {
 | |
| 		r.FileInfo = &imagex.FileInfo{
 | |
| 			Name:        resp.ImageInfos[0].FileName,
 | |
| 			Uri:         resp.ImageInfos[0].ImageUri,
 | |
| 			ImageWidth:  resp.ImageInfos[0].ImageWidth,
 | |
| 			ImageHeight: resp.ImageInfos[0].ImageHeight,
 | |
| 			Md5:         resp.ImageInfos[0].ImageMd5,
 | |
| 			ImageFormat: resp.ImageInfos[0].ImageFormat,
 | |
| 			ImageSize:   resp.ImageInfos[0].ImageSize,
 | |
| 			FrameCnt:    resp.ImageInfos[0].FrameCnt,
 | |
| 			Duration:    resp.ImageInfos[0].Duration,
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return r, nil
 | |
| }
 | |
| 
 | |
| func (v *veImageX) GetServerID() string {
 | |
| 	return v.serverIDs[0]
 | |
| }
 | |
| 
 | |
| func (v *veImageX) GetUploadHost(ctx context.Context) string {
 | |
| 	return v.uploadHost
 | |
| }
 |