diff --git a/Makefile b/Makefile index eb76ff9..fba9242 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,12 @@ BINARY_MAC := $(BINARY_NAME)-darwin BINARY_LINUX := $(BINARY_NAME)-linux .PHONY: all -all: build +all: proto build + +.PHONY: proto +proto: + @echo "Generating protobuf files..." + protoc --go_out=. --go_opt=paths=source_relative pb/*.proto .PHONY: build build: @@ -30,10 +35,12 @@ endif .PHONY: clean clean: rm -f $(BINARY_NAME) $(BINARY_MAC) $(BINARY_LINUX) + rm -f pb/*.pb.go .PHONY: help help: @echo "Available targets:" - @echo " all - Build for current platform (default)" + @echo " all - Generate protobuf files and build for current platform (default)" + @echo " proto - Generate protobuf files" @echo " build - Build for current platform" - @echo " clean - Remove built binaries" \ No newline at end of file + @echo " clean - Remove built binaries and generated protobuf files" \ No newline at end of file diff --git a/api_file.go b/api_file.go index 62b5965..2d073b7 100644 --- a/api_file.go +++ b/api_file.go @@ -112,6 +112,17 @@ func (s *Service) HandleRenameFile( req *httpserver.Request, resp *httpserver.Response, ) *httpserver.Response { + params := req.Binded.(*RenameParams) + isDir := params.IsDir + srcPath := utils.FullPath(utils.NormalizePath(params.SrcPath)) + dstPath := utils.FullPath(utils.NormalizePath(params.DstPath)) + + err := s.FileSystemManager.RenameFile(req.Context(), srcPath, dstPath, isDir) + if err != nil { + logger.Error("rename %s to %s: %v", srcPath, dstPath, err) + return resp.InternalServerError("rename file failed, " + err.Error()) + } + return resp.NoContent() } diff --git a/config.yml b/config.yml index a42d024..b7dc05f 100644 --- a/config.yml +++ b/config.yml @@ -13,7 +13,7 @@ s3: region: "default" endpoint: "http://120.48.66.228:6202" access_key_id: "admin" - secret_access_key: "admin" + secret_access_key: "12345678" bucket_name: "myjfs" use_path_style: true diff --git a/engine/filesystem_manager.go b/engine/filesystem_manager.go index b24de87..ce07cce 100644 --- a/engine/filesystem_manager.go +++ b/engine/filesystem_manager.go @@ -140,6 +140,16 @@ func (f *FileSystemManager) CreateFile(ctx context.Context, path utils.FullPath, return fmt.Errorf("upload s3 failed: %v", err) } + if output.ETag == nil { + empty := "" + output.ETag = &empty + } + + if output.VersionID == nil { + empty := "" + output.VersionID = &empty + } + entry := utils.NewFileEntry(path, path.ToS3Key(), uint64(fileSize), contentType, *output.ETag, *output.VersionID) if err := f.meta.InsertEntry(ctx, entry); err != nil { return fmt.Errorf("create file entry failed: %v", err) @@ -195,6 +205,52 @@ func (f *FileSystemManager) DeleteFile(ctx context.Context, path utils.FullPath, return nil } +func (f *FileSystemManager) RenameFile(ctx context.Context, srcPath, dstPath utils.FullPath, isDir bool) error { + f.Lock() + defer f.Unlock() + + if string(srcPath) == "/" || string(dstPath) == "/" { + return fmt.Errorf("cannot rename root") + } + + srcEntry, err := f.FindEntry(ctx, srcPath) + if err != nil { + return fmt.Errorf("find src file failed: %v", err) + } + + if dstEntry, _ := f.FindEntry(ctx, dstPath); dstEntry != nil { + return fmt.Errorf("dst file %s already exists", dstPath) + } + + parentDir, _ := dstPath.DirAndName() + if parentDir != "/" { + if parentEntry, _ := f.FindEntry(ctx, utils.FullPath(parentDir)); parentEntry == nil { + return fmt.Errorf("parent directory %s does not exist", parentDir) + } + } + + newS3Key := dstPath.ToS3Key() + if err := f.storage.CopyObject(srcEntry.S3Key, newS3Key); err != nil { + return fmt.Errorf("rename file failed: %v", err) + } + + newEntry := utils.NewFileEntry(dstPath, newS3Key, srcEntry.Size, srcEntry.ContentType, srcEntry.Etag, srcEntry.VersionID) + + if err := f.meta.InsertEntry(ctx, newEntry); err != nil { + return fmt.Errorf("insert new entry failed: %v", err) + } + + if err := f.meta.DeleteEntry(ctx, srcPath); err != nil { + return fmt.Errorf("delete source entry failed: %v", err) + } + + if err := f.storage.DeleteObject(srcEntry.S3Key); err != nil { + return fmt.Errorf("delete old file failed: %v", err) + } + + return nil +} + func (f *FileSystemManager) Shutdown() { if f.meta != nil { f.meta.Shutdown() diff --git a/router.go b/router.go index 71d6692..934eddf 100644 --- a/router.go +++ b/router.go @@ -34,9 +34,8 @@ func (s *Service) RegisterRouteRules() { Required: true, }, { - Key: "startFileName", - Type: httpserver.QueryTypeString, - Required: true, + Key: "startFileName", + Type: httpserver.QueryTypeString, }, { Key: "inclusive",