🎉 开始项目
feat: 完成基础界面; 列表展示 todo: uplevel button function todo: download/upload
This commit is contained in:
101
internal/s3/list.go
Normal file
101
internal/s3/list.go
Normal file
@ -0,0 +1,101 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/samber/lo"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ListBucketRes struct {
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type ListFileType int64
|
||||
|
||||
const (
|
||||
ListFileTypeFile ListFileType = iota
|
||||
ListFileTypeDir
|
||||
)
|
||||
|
||||
type ListFileRes struct {
|
||||
Name string `json:"name"`
|
||||
Key string `json:"key"`
|
||||
LastModified time.Time `json:"last_modified"`
|
||||
Size int64 `json:"size"`
|
||||
Type ListFileType `json:"type"`
|
||||
}
|
||||
|
||||
func (c *Client) ListBucket(ctx context.Context) ([]*ListBucketRes, error) {
|
||||
var (
|
||||
err error
|
||||
input = &s3.ListBucketsInput{
|
||||
MaxBuckets: aws.Int32(100),
|
||||
}
|
||||
output *s3.ListBucketsOutput
|
||||
)
|
||||
|
||||
if output, err = c.client.ListBuckets(ctx, input); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res := lo.Map(
|
||||
output.Buckets,
|
||||
func(item types.Bucket, index int) *ListBucketRes {
|
||||
return &ListBucketRes{CreatedAt: item.CreationDate.UnixMilli(), Name: *item.Name}
|
||||
},
|
||||
)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) ListFile(ctx context.Context, bucket string, prefix string) ([]*ListFileRes, error) {
|
||||
var (
|
||||
err error
|
||||
input = &s3.ListObjectsV2Input{
|
||||
Delimiter: aws.String("/"),
|
||||
MaxKeys: aws.Int32(1000),
|
||||
Bucket: aws.String(bucket),
|
||||
}
|
||||
output *s3.ListObjectsV2Output
|
||||
)
|
||||
|
||||
if prefix != "" {
|
||||
input.Prefix = aws.String(prefix)
|
||||
}
|
||||
|
||||
if output, err = c.client.ListObjectsV2(ctx, input); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
folder := lo.FilterMap(
|
||||
output.CommonPrefixes,
|
||||
func(item types.CommonPrefix, index int) (*ListFileRes, bool) {
|
||||
name := strings.TrimPrefix(*item.Prefix, prefix)
|
||||
return &ListFileRes{
|
||||
Name: name,
|
||||
Key: *item.Prefix,
|
||||
Type: ListFileTypeDir,
|
||||
}, name != ""
|
||||
},
|
||||
)
|
||||
|
||||
list := lo.Map(
|
||||
output.Contents,
|
||||
func(item types.Object, index int) *ListFileRes {
|
||||
return &ListFileRes{
|
||||
Key: strings.Clone(*item.Key),
|
||||
Name: strings.TrimPrefix(*item.Key, prefix),
|
||||
LastModified: *item.LastModified,
|
||||
Size: *item.Size,
|
||||
Type: ListFileTypeFile,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
return append(folder, list...), nil
|
||||
}
|
72
internal/s3/s3.go
Normal file
72
internal/s3/s3.go
Normal file
@ -0,0 +1,72 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
smithyendpoints "github.com/aws/smithy-go/endpoints"
|
||||
"github.com/loveuer/nf-disk/internal/tool"
|
||||
"github.com/loveuer/nf/nft/log"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type resolverV2 struct{}
|
||||
|
||||
func (*resolverV2) ResolveEndpoint(ctx context.Context, params s3.EndpointParameters) (smithyendpoints.Endpoint, error) {
|
||||
u, err := url.Parse(*params.Endpoint)
|
||||
if err != nil {
|
||||
log.Warn("resolver v2: parse url = %s, err = %s", params.Endpoint, err.Error())
|
||||
return smithyendpoints.Endpoint{}, err
|
||||
}
|
||||
return smithyendpoints.Endpoint{
|
||||
URI: *u,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
client *s3.Client
|
||||
}
|
||||
|
||||
func New(ctx context.Context, endpoint string, access string, key string) (*Client, error) {
|
||||
var (
|
||||
err error
|
||||
sdkConfig aws.Config
|
||||
output *s3.ListBucketsOutput
|
||||
)
|
||||
|
||||
customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
|
||||
return aws.Endpoint{
|
||||
URL: endpoint,
|
||||
}, nil
|
||||
})
|
||||
|
||||
if sdkConfig, err = config.LoadDefaultConfig(
|
||||
ctx,
|
||||
config.WithEndpointResolverWithOptions(customResolver),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s3Client := s3.NewFromConfig(sdkConfig, func(o *s3.Options) {
|
||||
//o.BaseEndpoint = aws.String(endpoint)
|
||||
//o.EndpointResolverV2 = &resolverV2{}
|
||||
o.Credentials = aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider(access, key, ""))
|
||||
o.UsePathStyle = true
|
||||
o.Region = "auto"
|
||||
})
|
||||
|
||||
if output, err = s3Client.ListBuckets(tool.Timeout(5), &s3.ListBucketsInput{
|
||||
MaxBuckets: aws.Int32(2),
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, item := range output.Buckets {
|
||||
log.Debug("s3.New: list bucket name = %s", *item.Name)
|
||||
}
|
||||
|
||||
return &Client{client: s3Client}, nil
|
||||
}
|
37
internal/s3/s3_test.go
Normal file
37
internal/s3/s3_test.go
Normal file
@ -0,0 +1,37 @@
|
||||
package s3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/loveuer/nf-disk/internal/tool"
|
||||
"github.com/loveuer/nf/nft/log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewClient(t *testing.T) {
|
||||
log.SetLogLevel(log.LogLevelDebug)
|
||||
_, err := New(context.TODO(), "http://10.220.10.15:9000/", "8ALV3DUZI31YG4BDRJ0Z", "CRqwS1MsiUj27TbRK+3T2n+LpKWd07VvaDKuzU0H")
|
||||
if err != nil {
|
||||
t.Fatalf("call s3.New err = %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestListFile(t *testing.T) {
|
||||
//log.SetLogLevel(log.LogLevelDebug)
|
||||
|
||||
//cli, err := New(context.TODO(), "http://10.220.10.14:19000", "5VCR05L4BSGNCTCD8DXP", "FPTMYBEiHhWLJ05C3aGXW8bjFXXNmghc8Za3Fo2u")
|
||||
cli, err := New(context.TODO(), "http://10.220.10.15:9000/", "8ALV3DUZI31YG4BDRJ0Z", "CRqwS1MsiUj27TbRK+3T2n+LpKWd07VvaDKuzU0H")
|
||||
if err != nil {
|
||||
t.Fatalf("call s3.New err = %s", err.Error())
|
||||
}
|
||||
|
||||
files, err := cli.ListFile(tool.Timeout(30), "topic-audit", "")
|
||||
if err != nil {
|
||||
t.Fatalf("call s3.ListFile err = %s", err.Error())
|
||||
}
|
||||
|
||||
t.Logf("[x] file length = %d", len(files))
|
||||
|
||||
for _, item := range files {
|
||||
t.Logf("[x: %d] file = %s, size = %d", item.Type, item.Name, item.Size)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user