123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- package tencent_cos
- import (
- "bytes"
- "context"
- "io"
- "net/http"
- "net/url"
- "strings"
- "time"
- "github.com/langgenius/dify-plugin-daemon/internal/oss"
- "github.com/tencentyun/cos-go-sdk-v5"
- )
- type TencentCOSStorage struct {
- bucket string
- region string
- client *cos.Client
- }
- func NewTencentCOSStorage(secretID string, secretKey string, region string, bucket string) (oss.OSS, error) {
- u, err := url.Parse("https://" + bucket + ".cos." + region + ".myqcloud.com")
- if err != nil {
- return nil, err
- }
- b := &cos.BaseURL{BucketURL: u}
- client := cos.NewClient(b, &http.Client{
- Transport: &cos.AuthorizationTransport{
- SecretID: secretID,
- SecretKey: secretKey,
- },
- })
- _, err = client.Bucket.Head(context.Background())
- if err != nil {
- return nil, err
- }
- return &TencentCOSStorage{
- bucket: bucket,
- region: region,
- client: client,
- }, nil
- }
- func (s *TencentCOSStorage) Save(key string, data []byte) error {
- _, err := s.client.Object.Put(context.Background(), key, bytes.NewReader(data), nil)
- return err
- }
- func (s *TencentCOSStorage) Load(key string) ([]byte, error) {
- resp, err := s.client.Object.Get(context.Background(), key, nil)
- if err != nil {
- return nil, err
- }
- return io.ReadAll(resp.Body)
- }
- func (s *TencentCOSStorage) Exists(key string) (bool, error) {
- ok, err := s.client.Object.IsExist(context.Background(), key)
- if err == nil && ok {
- return true, nil
- } else if err != nil {
- return false, err
- } else {
- return false, nil
- }
- }
- func (s *TencentCOSStorage) Delete(key string) error {
- _, err := s.client.Object.Delete(context.Background(), key)
- return err
- }
- func (s *TencentCOSStorage) List(prefix string) ([]oss.OSSPath, error) {
- if !strings.HasSuffix(prefix, "/") {
- prefix = prefix + "/"
- }
- var keys []oss.OSSPath
- opt := &cos.BucketGetOptions{
- Prefix: prefix,
- Delimiter: "/",
- }
- isTruncated := true
- var marker string
- for isTruncated {
- if marker != "" {
- opt.Marker = marker
- }
- result, _, err := s.client.Bucket.Get(context.Background(), opt)
- if err != nil {
- return nil, err
- }
- // 处理文件
- for _, obj := range result.Contents {
- key := strings.TrimPrefix(obj.Key, prefix)
- key = strings.TrimPrefix(key, "/")
- if key == "" {
- continue
- }
- keys = append(keys, oss.OSSPath{
- Path: key,
- IsDir: false,
- })
- }
- for _, commonPrefix := range result.CommonPrefixes {
- dir := strings.TrimPrefix(commonPrefix, prefix)
- dir = strings.TrimPrefix(dir, "/")
- dir = strings.TrimSuffix(dir, "/")
- if dir == "" {
- continue
- }
- keys = append(keys, oss.OSSPath{
- Path: dir,
- IsDir: true,
- })
- }
- isTruncated = result.IsTruncated
- marker = result.NextMarker
- }
- return keys, nil
- }
- func (s *TencentCOSStorage) State(key string) (oss.OSSState, error) {
- resp, err := s.client.Object.Head(context.Background(), key, nil)
- if err != nil {
- return oss.OSSState{}, err
- }
- contentLength := resp.ContentLength
- lastModified, err := time.Parse(time.RFC1123, resp.Header.Get("Last-Modified"))
- if err != nil {
- lastModified = time.Time{}
- }
- return oss.OSSState{
- Size: contentLength,
- LastModified: lastModified,
- }, nil
- }
|