mirror of
				https://github.com/cloudreve/cloudreve.git
				synced 2025-10-31 08:39:10 +08:00 
			
		
		
		
	Feat: add List method to Handler interface / implement local.List
This commit is contained in:
		| @ -46,6 +46,10 @@ type Driver struct { | |||||||
| 	HTTPClient request.Client | 	HTTPClient request.Client | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (handler Driver) List(ctx context.Context, path string) ([]response.Object, error) { | ||||||
|  | 	panic("implement me") | ||||||
|  | } | ||||||
|  |  | ||||||
| // CORS 创建跨域策略 | // CORS 创建跨域策略 | ||||||
| func (handler Driver) CORS() error { | func (handler Driver) CORS() error { | ||||||
| 	_, err := handler.Client.Bucket.PutCORS(context.Background(), &cossdk.BucketPutCORSOptions{ | 	_, err := handler.Client.Bucket.PutCORS(context.Background(), &cossdk.BucketPutCORSOptions{ | ||||||
|  | |||||||
| @ -23,6 +23,47 @@ type Driver struct { | |||||||
| 	Policy *model.Policy | 	Policy *model.Policy | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // List 递归列取给定物理路径下所有文件 | ||||||
|  | func (handler Driver) List(ctx context.Context, path string) ([]response.Object, error) { | ||||||
|  | 	var res []response.Object | ||||||
|  |  | ||||||
|  | 	// 取得起始路径 | ||||||
|  | 	root := util.RelativePath(filepath.FromSlash(path)) | ||||||
|  |  | ||||||
|  | 	// 开始遍历路径下的文件、目录 | ||||||
|  | 	err := filepath.Walk(root, | ||||||
|  | 		func(path string, info os.FileInfo, err error) error { | ||||||
|  | 			// 跳过根目录 | ||||||
|  | 			if path == root { | ||||||
|  | 				return nil | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if err != nil { | ||||||
|  | 				util.Log().Warning("无法遍历目录 %s, %s", path, err) | ||||||
|  | 				return filepath.SkipDir | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// 将遍历对象的绝对路径转换为相对路径 | ||||||
|  | 			rel, err := filepath.Rel(root, path) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			res = append(res, response.Object{ | ||||||
|  | 				Name:         info.Name(), | ||||||
|  | 				RelativePath: filepath.ToSlash(rel), | ||||||
|  | 				Source:       path, | ||||||
|  | 				Size:         uint64(info.Size()), | ||||||
|  | 				IsDir:        info.IsDir(), | ||||||
|  | 				LastModify:   info.ModTime(), | ||||||
|  | 			}) | ||||||
|  |  | ||||||
|  | 			return nil | ||||||
|  | 		}) | ||||||
|  |  | ||||||
|  | 	return res, err | ||||||
|  | } | ||||||
|  |  | ||||||
| // Get 获取文件内容 | // Get 获取文件内容 | ||||||
| func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) { | func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) { | ||||||
| 	// 打开文件 | 	// 打开文件 | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package local | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"fmt" | ||||||
| 	model "github.com/HFO4/cloudreve/models" | 	model "github.com/HFO4/cloudreve/models" | ||||||
| 	"github.com/HFO4/cloudreve/pkg/auth" | 	"github.com/HFO4/cloudreve/pkg/auth" | ||||||
| 	"github.com/HFO4/cloudreve/pkg/conf" | 	"github.com/HFO4/cloudreve/pkg/conf" | ||||||
| @ -230,3 +231,12 @@ func TestHandler_Token(t *testing.T) { | |||||||
| 	_, err := handler.Token(ctx, 10, "123") | 	_, err := handler.Token(ctx, 10, "123") | ||||||
| 	asserts.NoError(err) | 	asserts.NoError(err) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestDriver_List(t *testing.T) { | ||||||
|  | 	//asserts := assert.New(t) | ||||||
|  | 	handler := Driver{} | ||||||
|  | 	ctx := context.Background() | ||||||
|  |  | ||||||
|  | 	res, err := handler.List(ctx, "KKV") | ||||||
|  | 	fmt.Println(res, err) | ||||||
|  | } | ||||||
|  | |||||||
| @ -22,6 +22,10 @@ type Driver struct { | |||||||
| 	HTTPClient request.Client | 	HTTPClient request.Client | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (handler Driver) List(ctx context.Context, path string) ([]response.Object, error) { | ||||||
|  | 	panic("implement me") | ||||||
|  | } | ||||||
|  |  | ||||||
| // Get 获取文件 | // Get 获取文件 | ||||||
| func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) { | func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) { | ||||||
| 	// 获取文件源地址 | 	// 获取文件源地址 | ||||||
|  | |||||||
| @ -42,6 +42,10 @@ type Driver struct { | |||||||
| 	HTTPClient request.Client | 	HTTPClient request.Client | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (handler *Driver) List(ctx context.Context, path string) ([]response.Object, error) { | ||||||
|  | 	panic("implement me") | ||||||
|  | } | ||||||
|  |  | ||||||
| type key int | type key int | ||||||
|  |  | ||||||
| const ( | const ( | ||||||
|  | |||||||
| @ -22,6 +22,10 @@ type Driver struct { | |||||||
| 	Policy *model.Policy | 	Policy *model.Policy | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (handler Driver) List(ctx context.Context, path string) ([]response.Object, error) { | ||||||
|  | 	panic("implement me") | ||||||
|  | } | ||||||
|  |  | ||||||
| // Get 获取文件 | // Get 获取文件 | ||||||
| func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) { | func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) { | ||||||
| 	// 给文件名加上随机参数以强制拉取 | 	// 给文件名加上随机参数以强制拉取 | ||||||
|  | |||||||
| @ -27,6 +27,10 @@ type Driver struct { | |||||||
| 	AuthInstance auth.Auth | 	AuthInstance auth.Auth | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (handler Driver) List(ctx context.Context, path string) ([]response.Object, error) { | ||||||
|  | 	panic("implement me") | ||||||
|  | } | ||||||
|  |  | ||||||
| // getAPIUrl 获取接口请求地址 | // getAPIUrl 获取接口请求地址 | ||||||
| func (handler Driver) getAPIUrl(scope string, routes ...string) string { | func (handler Driver) getAPIUrl(scope string, routes ...string) string { | ||||||
| 	serverURL, err := url.Parse(handler.Policy.Server) | 	serverURL, err := url.Parse(handler.Policy.Server) | ||||||
|  | |||||||
| @ -40,6 +40,10 @@ type Driver struct { | |||||||
| 	Policy *model.Policy | 	Policy *model.Policy | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (handler Driver) List(ctx context.Context, path string) ([]response.Object, error) { | ||||||
|  | 	panic("implement me") | ||||||
|  | } | ||||||
|  |  | ||||||
| // Get 获取文件 | // Get 获取文件 | ||||||
| func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) { | func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) { | ||||||
| 	// 给文件名加上随机参数以强制拉取 | 	// 给文件名加上随机参数以强制拉取 | ||||||
|  | |||||||
| @ -41,7 +41,7 @@ type FileHeader interface { | |||||||
| 	GetVirtualPath() string | 	GetVirtualPath() string | ||||||
| } | } | ||||||
|  |  | ||||||
| // Driver 存储策略适配器 | // Handler 存储策略适配器 | ||||||
| type Handler interface { | type Handler interface { | ||||||
| 	// 上传文件, dst为文件存储路径,size 为文件大小。上下文关闭 | 	// 上传文件, dst为文件存储路径,size 为文件大小。上下文关闭 | ||||||
| 	// 时,应取消上传并清理临时文件 | 	// 时,应取消上传并清理临时文件 | ||||||
| @ -64,6 +64,9 @@ type Handler interface { | |||||||
|  |  | ||||||
| 	// Token 获取有效期为ttl的上传凭证和签名,同时回调会话有效期为sessionTTL | 	// Token 获取有效期为ttl的上传凭证和签名,同时回调会话有效期为sessionTTL | ||||||
| 	Token(ctx context.Context, ttl int64, callbackKey string) (serializer.UploadCredential, error) | 	Token(ctx context.Context, ttl int64, callbackKey string) (serializer.UploadCredential, error) | ||||||
|  |  | ||||||
|  | 	// List 递归列取远程端path路径下文件、目录,不包含path本身,返回的对象路径以path作为起始根目录 | ||||||
|  | 	List(ctx context.Context, path string) ([]response.Object, error) | ||||||
| } | } | ||||||
|  |  | ||||||
| // FileSystem 管理文件的文件系统 | // FileSystem 管理文件的文件系统 | ||||||
|  | |||||||
| @ -1,6 +1,9 @@ | |||||||
| package response | package response | ||||||
|  |  | ||||||
| import "io" | import ( | ||||||
|  | 	"io" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
|  |  | ||||||
| // ContentResponse 获取文件内容类方法的通用返回值。 | // ContentResponse 获取文件内容类方法的通用返回值。 | ||||||
| // 有些上传策略需要重定向, | // 有些上传策略需要重定向, | ||||||
| @ -17,3 +20,13 @@ type RSCloser interface { | |||||||
| 	io.ReadSeeker | 	io.ReadSeeker | ||||||
| 	io.Closer | 	io.Closer | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Object 列出文件、目录时返回的对象 | ||||||
|  | type Object struct { | ||||||
|  | 	Name         string | ||||||
|  | 	RelativePath string | ||||||
|  | 	Source       string | ||||||
|  | 	Size         uint64 | ||||||
|  | 	IsDir        bool | ||||||
|  | 	LastModify   time.Time | ||||||
|  | } | ||||||
|  | |||||||
| @ -26,6 +26,10 @@ type FileHeaderMock struct { | |||||||
| 	testMock.Mock | 	testMock.Mock | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (m FileHeaderMock) List(ctx context.Context, path string) ([]response.Object, error) { | ||||||
|  | 	panic("implement me") | ||||||
|  | } | ||||||
|  |  | ||||||
| func (m FileHeaderMock) Get(ctx context.Context, path string) (response.RSCloser, error) { | func (m FileHeaderMock) Get(ctx context.Context, path string) (response.RSCloser, error) { | ||||||
| 	args := m.Called(ctx, path) | 	args := m.Called(ctx, path) | ||||||
| 	return args.Get(0).(response.RSCloser), args.Error(1) | 	return args.Get(0).(response.RSCloser), args.Error(1) | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 HFO4
					HFO4