From 8ff928d9d6ebd53ade7675ff63e6853be8746be3 Mon Sep 17 00:00:00 2001 From: zicla Date: Wed, 24 Apr 2019 02:02:25 +0800 Subject: [PATCH] Finish the method of COPY for webdav. --- rest/dav_service.go | 45 ++++++++++++++++++++++------- rest/matter_service.go | 65 ++++++++++++++++++++++++++++++++++++++++-- rest/util_path.go | 40 ++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 13 deletions(-) diff --git a/rest/dav_service.go b/rest/dav_service.go index a666c16..19f56de 100644 --- a/rest/dav_service.go +++ b/rest/dav_service.go @@ -316,10 +316,17 @@ func (this *DavService) HandleOptions(w http.ResponseWriter, r *http.Request, us } -//移动或者重命名 -func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { - fmt.Printf("MOVE %s\n", subPath) +//移动或者复制的准备工作 +func (this *DavService) prepareMoveCopy( + writer http.ResponseWriter, + request *http.Request, + user *User, subPath string) ( + srcMatter *Matter, + destDirMatter *Matter, + srcDirPath string, + destinationDirPath string, + destinationName string) { //解析出目标路径。 destinationStr := request.Header.Get("Destination") @@ -358,9 +365,9 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req this.PanicBadRequest("目标前缀必须为:%s", WEBDAV_PREFFIX) } - destinationName := GetFilenameOfPath(destinationPath) - destinationDirPath := GetDirOfPath(destinationPath) - srcDirPath := GetDirOfPath(subPath) + destinationName = GetFilenameOfPath(destinationPath) + destinationDirPath = GetDirOfPath(destinationPath) + srcDirPath = GetDirOfPath(subPath) overwrite := false if overwriteStr == "T" { @@ -373,7 +380,6 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req } //源matter. - var srcMatter *Matter //如果是空或者/就是请求根目录 if subPath == "" || subPath == "/" { this.PanicBadRequest("你不能移动根目录!") @@ -385,13 +391,13 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req destMatter := this.matterDao.findByUserUuidAndPath(user.Uuid, destinationPath) //目标文件夹matter - var destDirMatter *Matter if destinationDirPath == "" || destinationDirPath == "/" { destDirMatter = NewRootMatter(user) } else { destDirMatter = this.matterDao.checkByUserUuidAndPath(user.Uuid, destinationDirPath) } + //如果目标matter存在了。 if destMatter != nil { @@ -404,6 +410,16 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req } } + return srcMatter, destDirMatter, srcDirPath, destinationDirPath, destinationName + +} + +//移动或者重命名 +func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { + + fmt.Printf("MOVE %s\n", subPath) + + srcMatter, destDirMatter, srcDirPath, destinationDirPath, destinationName := this.prepareMoveCopy(writer, request, user, subPath) //移动到新目录中去。 if destinationDirPath == srcDirPath { //文件夹没变化,相当于重命名。 @@ -416,8 +432,17 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req } //复制文件/文件夹 -func (this *DavService) HandleCopy(w http.ResponseWriter, r *http.Request, user *User, subPath string) { - this.PanicBadRequest("暂不支持COPY方法") +func (this *DavService) HandleCopy(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { + + fmt.Printf("COPY %s\n", subPath) + + srcMatter, destDirMatter, _, destinationDirPath, destinationName := this.prepareMoveCopy(writer, request, user, subPath) + + //复制到新目录中去。 + this.matterService.Copy(srcMatter, destDirMatter, destinationName) + + this.logger.Info("完成复制 %s => %s", subPath, destinationDirPath) + } //处理所有的请求 diff --git a/rest/matter_service.go b/rest/matter_service.go index 0442c5b..6f73cc2 100644 --- a/rest/matter_service.go +++ b/rest/matter_service.go @@ -131,9 +131,8 @@ func (this *MatterService) Detail(uuid string) *Matter { return matter } - //创建文件夹 返回刚刚创建的这个文件夹 -func (this *MatterService) CreateDirectory(puuid string, name string,user *User) *Matter { +func (this *MatterService) CreateDirectory(puuid string, name string, user *User) *Matter { name = strings.TrimSpace(name) //验证参数。 @@ -788,9 +787,69 @@ func (this *MatterService) Move(srcMatter *Matter, destMatter *Matter) { return } +//将一个srcMatter复制到另一个destMatter(必须为文件夹)下,名字叫做name +func (this *MatterService) Copy(srcMatter *Matter, destDirMatter *Matter, name string) { + + if !destDirMatter.Dir { + this.PanicBadRequest("目标必须为文件夹") + } + + if srcMatter.Dir { + + //如果源是文件夹 + + //在目标地址创建新文件夹。 + newMatter := &Matter{ + Puuid: destDirMatter.Uuid, + UserUuid: srcMatter.UserUuid, + Username: srcMatter.Username, + Dir: srcMatter.Dir, + Alien: srcMatter.Alien, + Name: name, + Md5: "", + Size: srcMatter.Size, + Privacy: srcMatter.Privacy, + Path: destDirMatter.Path + "/" + name, + } + + newMatter = this.matterDao.Create(newMatter) + + //复制子文件或文件夹 + matters := this.matterDao.List(srcMatter.Uuid, srcMatter.UserUuid, nil) + for _, m := range matters { + this.Copy(m, newMatter, m.Name) + } + + } else { + //如果源是普通文件 + destAbsolutePath := destDirMatter.AbsolutePath() + "/" + name + srcAbsolutePath := srcMatter.AbsolutePath() + + //物理文件进行复制 + CopyFile(srcAbsolutePath, destAbsolutePath) + + //创建新文件的数据库信息。 + newMatter := &Matter{ + Puuid: destDirMatter.Uuid, + UserUuid: srcMatter.UserUuid, + Username: srcMatter.Username, + Dir: srcMatter.Dir, + Alien: srcMatter.Alien, + Name: name, + Md5: "", + Size: srcMatter.Size, + Privacy: srcMatter.Privacy, + Path: destDirMatter.Path + "/" + name, + } + + newMatter = this.matterDao.Create(newMatter) + + } + +} //将一个matter 重命名为 name -func (this *MatterService) Rename(matter *Matter, name string,user *User) { +func (this *MatterService) Rename(matter *Matter, name string, user *User) { //验证参数。 if name == "" { diff --git a/rest/util_path.go b/rest/util_path.go index b635cc2..0e7f6dc 100644 --- a/rest/util_path.go +++ b/rest/util_path.go @@ -3,6 +3,7 @@ package rest import ( "fmt" "go/build" + "io" "io/ioutil" "os" "os/user" @@ -229,3 +230,42 @@ func GetUserCacheRootDir(username string) (rootDirPath string) { return rootDirPath } + + +//复制文件 +func CopyFile(srcPath string, destPath string) (nBytes int64) { + + srcFileStat, err := os.Stat(srcPath) + if err != nil { + panic(err) + } + + if !srcFileStat.Mode().IsRegular() { + panic(fmt.Errorf("%s is not a regular file", srcPath)) + } + + srcFile, err := os.Open(srcPath) + if err != nil { + panic(err) + } + defer func() { + err = srcFile.Close() + if err != nil { + panic(err) + } + }() + + destFile, err := os.Create(destPath) + if err != nil { + panic(err) + } + defer func() { + err = destFile.Close() + if err != nil { + panic(err) + } + }() + + nBytes, err = io.Copy(destFile, srcFile) + return nBytes +}