From e637095290031ee223555fe31cc353d0004683c1 Mon Sep 17 00:00:00 2001 From: ZeroDeng Date: Sat, 1 Jun 2024 12:11:31 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20imgur=20image=20uploa?= =?UTF-8?q?d=20(#247)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### 新增环境变量 STORAGE_ALIOSS_ENDPOINT:Endpoint(地域节点),比如`oss-cn-beijing.aliyuncs.com` STORAGE_ALIOSS_BUCKET_NAME:Bucket名称,比如`zerodeng-superai` STORAGE_ALIOSS_ACCESS_KEY_ID:阿里授权KEY,在RAM获取 STORAGE_ALIOSS_ACCESS_KEY_SECRET:阿里授权SECRET,在RAM获取 --- common/storage/drives/alioss.go | 56 +++++++++++++++++++++++++++++++++ common/storage/storage.go | 24 ++++++++++++++ common/storage/storage_test.go | 17 ++++++++++ config.example.yaml | 7 ++++- go.mod | 2 ++ go.sum | 4 +++ 6 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 common/storage/drives/alioss.go diff --git a/common/storage/drives/alioss.go b/common/storage/drives/alioss.go new file mode 100644 index 00000000..24747505 --- /dev/null +++ b/common/storage/drives/alioss.go @@ -0,0 +1,56 @@ +package drives + +import ( + "bytes" + "fmt" + "github.com/aliyun/aliyun-oss-go-sdk/oss" +) + +type AliOSSUpload struct { + Endpoint string + AccessKeyId string + AccessKeySecret string + BucketName string +} + +func NewAliOSSUpload(endpoint, accessKeyId, accessKeySecret, bucketName string) *AliOSSUpload { + return &AliOSSUpload{ + Endpoint: endpoint, + AccessKeyId: accessKeyId, + AccessKeySecret: accessKeySecret, + BucketName: bucketName, + } +} + +func (a *AliOSSUpload) Name() string { + return "AliOSS" +} + +func (a *AliOSSUpload) Upload(data []byte, fileName string) (string, error) { + // Create OSS Client + client, err := oss.New(a.Endpoint, a.AccessKeyId, a.AccessKeySecret) + if err != nil { + return "", fmt.Errorf("creating OSS client: %w", err) + } + + // Create Bucket + bucket, err := client.Bucket(a.BucketName) + if err != nil { + return "", fmt.Errorf("getting bucket: %w", err) + } + + // Upload File + reader := bytes.NewReader(data) + err = bucket.PutObject(fileName, reader) + if err != nil { + return "", fmt.Errorf("uploading file: %w", err) + } + + // Get Object URL + objectURL, err := bucket.SignURL(fileName, oss.HTTPGet, 3600) + if err != nil { + return "", fmt.Errorf("signing object URL: %w", err) + } + + return objectURL, nil +} diff --git a/common/storage/storage.go b/common/storage/storage.go index 7aa64626..1aaee47e 100644 --- a/common/storage/storage.go +++ b/common/storage/storage.go @@ -13,6 +13,30 @@ type Storage struct { func InitStorage() { InitImgurStorage() InitSMStorage() + InitALIOSSStorage() +} + +func InitALIOSSStorage() { + endpoint := viper.GetString("storage.alioss.endpoint") + if endpoint == "" { + return + } + accessKeyId := viper.GetString("storage.alioss.accessKeyId") + if accessKeyId == "" { + return + } + accessKeySecret := viper.GetString("storage.alioss.accessKeySecret") + if accessKeySecret == "" { + return + } + bucketName := viper.GetString("storage.alioss.bucketName") + if bucketName == "" { + + return + } + + aliUpload := drives.NewAliOSSUpload(endpoint, accessKeyId, accessKeySecret, bucketName) + AddStorageDrive(aliUpload) } func InitSMStorage() { diff --git a/common/storage/storage_test.go b/common/storage/storage_test.go index d3a00704..c6b3ad28 100644 --- a/common/storage/storage_test.go +++ b/common/storage/storage_test.go @@ -22,7 +22,24 @@ func InitConfig() { viper.ReadInConfig() requester.InitHttpClient() } +func TestALIOSSUpload(t *testing.T) { + InitConfig() + endpoint := viper.GetString("storage.alioss.endpoint") + accessKeyId := viper.GetString("storage.alioss.accessKeyId") + accessKeySecret := viper.GetString("storage.alioss.accessKeySecret") + bucketName := viper.GetString("storage.alioss.bucketName") + aliUpload := drives.NewAliOSSUpload(endpoint, accessKeyId, accessKeySecret, bucketName) + image, err := base64.StdEncoding.DecodeString(testImageB64) + if err != nil { + fmt.Println(err) + } + + url, err := aliUpload.Upload(image, utils.GetUUID()+".png") + fmt.Println(url) + fmt.Println(err) + assert.Nil(t, err) +} func TestSMMSUpload(t *testing.T) { InitConfig() smSecret := viper.GetString("storage.smms.secret") diff --git a/config.example.yaml b/config.example.yaml index 6fd19ed9..c8063d15 100644 --- a/config.example.yaml +++ b/config.example.yaml @@ -68,4 +68,9 @@ storage: # 存储设置 (可选,主要用于图片生成,有些供应商不提 smms: # sm.ms 图床设置 secret: "" # 你的 sm.ms API 密钥 imgur: - client_id: "" # 你的 imgur client_id \ No newline at end of file + client_id: "" # 你的 imgur client_id + alioss: # 阿里云OSS对象存储 + endpoint: "" # Endpoint(地域节点),比如oss-cn-beijing.aliyuncs.com + bucketName: "" # Bucket名称,比如zerodeng-superai + accessKeyId: "" # 阿里授权KEY,在阿里云后台用户RAM控制部分获取 + accessKeySecret: "" # 阿里授权SECRET,在阿里云后台用户RAM控制部分获取 \ No newline at end of file diff --git a/go.mod b/go.mod index 1d297960..f6f09dbf 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.18 require ( github.com/MartialBE/tiktoken-go v0.1.7 + github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 github.com/aws/smithy-go v1.20.1 github.com/gin-contrib/cors v1.7.0 @@ -53,6 +54,7 @@ require ( go.uber.org/multierr v1.9.0 // indirect golang.org/x/exp v0.0.0-20231219180239-dc181d75b848 // indirect golang.org/x/sync v0.6.0 // indirect + golang.org/x/time v0.5.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/go.sum b/go.sum index 629b0b48..ad73d3d6 100644 --- a/go.sum +++ b/go.sum @@ -4,6 +4,8 @@ github.com/MartialBE/tiktoken-go v0.1.7 h1:QwYqiONL1+kc/bYtNIbfQ//bcRqyw8ETZ2HKK github.com/MartialBE/tiktoken-go v0.1.7/go.mod h1:BTUpeOlungENRv13+nWc4IwWbBJvvR/8gOUTiXsrEXg= github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.25 h1:VCZg3OsKY19PcXBRRYk2ExeZ3mC8Hm4LqcXcINuFyY4= github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.25/go.mod h1:kL1v4iIjlalwm3gCYGvF4NLa3hs+aKEfRkNJvj4aoDU= +github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g= +github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/antonlindstrom/pgstore v0.0.0-20200229204646-b08ebf1105e0/go.mod h1:2Ti6VUHVxpC0VSmTZzEvpzysnaGAfGBOoMIz5ykPyyw= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 h1:gTK2uhtAPtFcdRRJilZPx8uJLL2J85xK11nKtWL0wfU= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1/go.mod h1:sxpLb+nZk7tIfCWChfd+h4QwHNUR57d8hA1cleTkjJo= @@ -261,6 +263,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=