diff --git a/rest/alien_controller.go b/rest/alien_controller.go index ad76124..9e3e565 100644 --- a/rest/alien_controller.go +++ b/rest/alien_controller.go @@ -279,7 +279,7 @@ func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Re panic("文件大小不正确") } - dirMatter := this.matterDao.CheckDirByUuid(uploadToken.FolderUuid, user) + dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, user) matter := this.matterService.Upload(file, user, dirMatter, uploadToken.Filename, uploadToken.Privacy) @@ -343,6 +343,12 @@ func (this *AlienController) CrawlDirect(writer http.ResponseWriter, request *ht //文件名。 filename := request.FormValue("filename") + //文件公有或私有 + privacyStr := request.FormValue("privacy") + //文件夹路径,以 / 开头。 + dir := request.FormValue("dir") + + if filename == "" { panic("文件名必填") } else if m, _ := regexp.MatchString(`[<>|*?/\\]`, filename); m { @@ -354,8 +360,6 @@ func (this *AlienController) CrawlDirect(writer http.ResponseWriter, request *ht panic("资源url必填,并且应该以http://或者https://开头") } - //文件公有或私有 - privacyStr := request.FormValue("privacy") var privacy bool if privacyStr == "" { panic(`文件公有性必填`) @@ -369,8 +373,6 @@ func (this *AlienController) CrawlDirect(writer http.ResponseWriter, request *ht } } - //文件夹路径,以 / 开头。 - dir := request.FormValue("dir") user := this.CheckRequestUser(writer, request) dirUuid, dirRelativePath := this.matterService.GetDirUuid(user, dir) diff --git a/rest/dav_service.go b/rest/dav_service.go index b6aec2f..0b49fc1 100644 --- a/rest/dav_service.go +++ b/rest/dav_service.go @@ -161,13 +161,8 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http this.PanicError(err) //寻找符合条件的matter. - var matter *Matter //如果是空或者/就是请求根目录 - if subPath == "" || subPath == "/" { - matter = NewRootMatter(user) - } else { - matter = this.matterDao.checkByUserUuidAndPath(user.Uuid, subPath) - } + matter := this.matterDao.CheckWithRootByPath(subPath, user) var matters []*Matter if depth == 0 { @@ -208,14 +203,7 @@ func (this *DavService) HandleGetHeadPost(writer http.ResponseWriter, request *h fmt.Printf("GET %s\n", subPath) - //寻找符合条件的matter. - var matter *Matter - //如果是空或者/就是请求根目录 - if subPath == "" || subPath == "/" { - matter = NewRootMatter(user) - } else { - matter = this.matterDao.checkByUserUuidAndPath(user.Uuid, subPath) - } + matter := this.matterDao.CheckWithRootByPath(subPath, user) //如果是文件夹,相当于是 Propfind if matter.Dir { @@ -237,14 +225,7 @@ func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Requ dirPath := GetDirOfPath(subPath) //寻找符合条件的matter. - var matter *Matter - //如果是空或者/就是请求根目录 - if dirPath == "" || dirPath == "/" { - matter = NewRootMatter(user) - } else { - matter = this.matterDao.checkByUserUuidAndPath(user.Uuid, dirPath) - } - + dirMatter := this.matterDao.CheckWithRootByPath(dirPath, user) //如果存在,那么先删除再说。 srcMatter := this.matterDao.findByUserUuidAndPath(user.Uuid, subPath) @@ -252,8 +233,7 @@ func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Requ this.matterService.Delete(srcMatter) } - - this.matterService.Upload(request.Body, user, matter, filename, true) + this.matterService.Upload(request.Body, user, dirMatter, filename, true) } @@ -263,13 +243,7 @@ func (this *DavService) HandleDelete(writer http.ResponseWriter, request *http.R fmt.Printf("DELETE %s\n", subPath) //寻找符合条件的matter. - var matter *Matter - //如果是空或者/就是请求根目录 - if subPath == "" || subPath == "/" { - matter = NewRootMatter(user) - } else { - matter = this.matterDao.checkByUserUuidAndPath(user.Uuid, subPath) - } + matter := this.matterDao.CheckWithRootByPath(subPath, user) this.matterService.Delete(matter) } @@ -283,13 +257,7 @@ func (this *DavService) HandleMkcol(writer http.ResponseWriter, request *http.Re dirPath := GetDirOfPath(subPath) //寻找符合条件的matter. - var dirMatter *Matter - //如果是空或者/就是请求根目录 - if dirPath == "" || dirPath == "/" { - dirMatter = NewRootMatter(user) - } else { - dirMatter = this.matterDao.checkByUserUuidAndPath(user.Uuid, dirPath) - } + dirMatter := this.matterDao.CheckWithRootByPath(dirPath, user) this.matterService.CreateDirectory(dirMatter, thisDirName, user) @@ -301,13 +269,7 @@ func (this *DavService) HandleOptions(w http.ResponseWriter, r *http.Request, us fmt.Printf("OPTIONS %s\n", subPath) //寻找符合条件的matter. - var matter *Matter - //如果是空或者/就是请求根目录 - if subPath == "" || subPath == "/" { - matter = NewRootMatter(user) - } else { - matter = this.matterDao.checkByUserUuidAndPath(user.Uuid, subPath) - } + matter := this.matterDao.CheckWithRootByPath(subPath, user) allow := "OPTIONS, LOCK, PUT, MKCOL" if matter.Dir { @@ -333,7 +295,8 @@ func (this *DavService) prepareMoveCopy( destDirMatter *Matter, srcDirPath string, destinationDirPath string, - destinationName string) { + destinationName string, + overwrite bool) { //解析出目标路径。 destinationStr := request.Header.Get("Destination") @@ -376,7 +339,7 @@ func (this *DavService) prepareMoveCopy( destinationDirPath = GetDirOfPath(destinationPath) srcDirPath = GetDirOfPath(subPath) - overwrite := false + overwrite = false if overwriteStr == "T" { overwrite = true } @@ -387,36 +350,15 @@ func (this *DavService) prepareMoveCopy( } //源matter. + //寻找符合条件的matter. + srcMatter = this.matterDao.CheckWithRootByPath(subPath, user) + //如果是空或者/就是请求根目录 - if subPath == "" || subPath == "/" { + if srcMatter.Uuid == MATTER_ROOT { this.PanicBadRequest("你不能移动根目录!") - } else { - srcMatter = this.matterDao.checkByUserUuidAndPath(user.Uuid, subPath) - } - - //目标matter - destMatter := this.matterDao.findByUserUuidAndPath(user.Uuid, destinationPath) - - //目标文件夹matter - if destinationDirPath == "" || destinationDirPath == "/" { - destDirMatter = NewRootMatter(user) - } else { - destDirMatter = this.matterDao.checkByUserUuidAndPath(user.Uuid, destinationDirPath) - } - - //如果目标matter存在了。 - if destMatter != nil { - - //如果目标matter还存在了。 - if overwrite { - //要求覆盖。那么删除。 - this.matterService.Delete(destMatter) - } else { - this.PanicBadRequest("%s已经存在,操作失败!", destinationName) - } } - return srcMatter, destDirMatter, srcDirPath, destinationDirPath, destinationName + return srcMatter, destDirMatter, srcDirPath, destinationDirPath, destinationName, overwrite } @@ -425,16 +367,16 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req fmt.Printf("MOVE %s\n", subPath) - srcMatter, destDirMatter, srcDirPath, destinationDirPath, destinationName := this.prepareMoveCopy(writer, request, user, subPath) + srcMatter, destDirMatter, srcDirPath, destinationDirPath, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, subPath) //移动到新目录中去。 if destinationDirPath == srcDirPath { //文件夹没变化,相当于重命名。 this.matterService.Rename(srcMatter, destinationName, user) } else { - this.matterService.Move(srcMatter, destDirMatter) + this.matterService.Move(srcMatter, destDirMatter, overwrite) } - this.logger.Info("完成移动 %s => %s", subPath, destinationDirPath) + this.logger.Info("完成移动 %s => %s", subPath, destDirMatter.Path) } //复制文件/文件夹 @@ -442,12 +384,12 @@ func (this *DavService) HandleCopy(writer http.ResponseWriter, request *http.Req fmt.Printf("COPY %s\n", subPath) - srcMatter, destDirMatter, _, destinationDirPath, destinationName := this.prepareMoveCopy(writer, request, user, subPath) + srcMatter, destDirMatter, _, _, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, subPath) //复制到新目录中去。 - this.matterService.Copy(srcMatter, destDirMatter, destinationName) + this.matterService.Copy(srcMatter, destDirMatter, destinationName,overwrite) - this.logger.Info("完成复制 %s => %s", subPath, destinationDirPath) + this.logger.Info("完成复制 %s => %s", subPath, destDirMatter.Path) } diff --git a/rest/download/download.go b/rest/download/download.go index 3ac46aa..1feab50 100644 --- a/rest/download/download.go +++ b/rest/download/download.go @@ -362,3 +362,37 @@ func DownloadFile( } } + + + +// 从指定的url下载一个文件。参考:https://golangcode.com/download-a-file-from-a-url/ +func HttpDownloadFile(filepath string, url string) (int64, error) { + + // Create the file + out, err := os.Create(filepath) + if err != nil { + return 0, err + } + defer func() { + e := out.Close() + PanicError(e) + }() + + // Get the data + resp, err := http.Get(url) + if err != nil { + return 0, err + } + defer func() { + e := resp.Body.Close() + PanicError(e) + }() + + // Write the body to file + size, err := io.Copy(out, resp.Body) + if err != nil { + return 0, err + } + + return size, nil +} diff --git a/rest/matter_controller.go b/rest/matter_controller.go index 261cece..26f2751 100644 --- a/rest/matter_controller.go +++ b/rest/matter_controller.go @@ -232,7 +232,7 @@ func (this *MatterController) Upload(writer http.ResponseWriter, request *http.R fileName = fileName[pos+1:] } - dirMatter := this.matterDao.CheckDirByUuid(puuid, user) + dirMatter := this.matterDao.CheckWithRootByUuid(puuid, user) matter := this.matterService.Upload(file, user, dirMatter, fileName, privacy) @@ -406,31 +406,20 @@ func (this *MatterController) Move(writer http.ResponseWriter, request *http.Req } user := this.checkUser(writer, request) - if user.Role != USER_ROLE_ADMINISTRATOR { - userUuid = user.Uuid - } - if userUuid == "" { + if user.Role != USER_ROLE_ADMINISTRATOR || userUuid == "" { userUuid = user.Uuid } user = this.userDao.CheckByUuid(userUuid) //验证dest是否有问题 - var destMatter *Matter - if destUuid == "" { - this.PanicBadRequest("destUuid参数必填") - } else { - if destUuid == MATTER_ROOT { - destMatter = NewRootMatter(user) - } else { - destMatter = this.matterService.Detail(destUuid) - if !destMatter.Dir { - this.PanicBadRequest("目标不是文件夹") - } - if user.Role != USER_ROLE_ADMINISTRATOR && destMatter.UserUuid != user.Uuid { - this.PanicUnauthorized("没有权限") - } - } + var destMatter = this.matterDao.CheckWithRootByUuid(destUuid, user) + if !destMatter.Dir { + this.PanicBadRequest("目标不是文件夹") + } + + if user.Role != USER_ROLE_ADMINISTRATOR && destMatter.UserUuid != user.Uuid { + this.PanicUnauthorized("没有权限") } var srcMatters []*Matter @@ -439,10 +428,6 @@ func (this *MatterController) Move(writer http.ResponseWriter, request *http.Req //找出该文件或者文件夹 srcMatter := this.matterDao.CheckByUuid(uuid) - if user.Role != USER_ROLE_ADMINISTRATOR && srcMatter.UserUuid != user.Uuid { - this.PanicUnauthorized("没有权限") - } - if srcMatter.Puuid == destMatter.Uuid { this.PanicBadRequest("没有进行移动,操作无效!") } @@ -459,24 +444,10 @@ func (this *MatterController) Move(writer http.ResponseWriter, request *http.Req panic("文件和目标文件夹的拥有者不是同一人") } - //文件夹不能把自己移入到自己中,也不可以移入到自己的子文件夹下。 - tmpMatter := destMatter - for tmpMatter != nil { - if uuid == tmpMatter.Uuid { - panic("文件夹不能把自己移入到自己中,也不可以移入到自己的子文件夹下。") - } - tmpMatter = tmpMatter.Parent - } - srcMatters = append(srcMatters, srcMatter) } - for _, srcMatter := range srcMatters { - - //TODO:移动物理目录并且加锁。 - this.matterService.Move(srcMatter, destMatter) - - } + this.matterService.MoveBatch(srcMatters, destMatter) return this.Success(nil) } diff --git a/rest/matter_dao.go b/rest/matter_dao.go index b46fba7..23d89c7 100644 --- a/rest/matter_dao.go +++ b/rest/matter_dao.go @@ -49,9 +49,12 @@ func (this *MatterDao) CheckByUuid(uuid string) *Matter { return matter } - //按照uuid查找一个文件夹,可能返回root对应的matter. -func (this *MatterDao) CheckDirByUuid(uuid string, user *User) *Matter { +func (this *MatterDao) CheckWithRootByUuid(uuid string, user *User) *Matter { + + if uuid == "" { + this.PanicBadRequest("uuid cannot be nil.") + } var matter *Matter if uuid == MATTER_ROOT { @@ -66,6 +69,25 @@ func (this *MatterDao) CheckDirByUuid(uuid string, user *User) *Matter { return matter } +//按照path查找一个matter,可能返回root对应的matter. +func (this *MatterDao) CheckWithRootByPath(path string, user *User) *Matter { + + var matter *Matter + + if user == nil { + this.PanicBadRequest("user cannot be nil.") + } + + //目标文件夹matter + if path == "" || path == "/" { + matter = NewRootMatter(user) + } else { + matter = this.checkByUserUuidAndPath(user.Uuid, path) + } + + return matter +} + //按照名字查询文件夹 func (this *MatterDao) FindByUserUuidAndPuuidAndNameAndDirTrue(userUuid string, puuid string, name string) *Matter { diff --git a/rest/matter_service.go b/rest/matter_service.go index 83035a8..ce49bfa 100644 --- a/rest/matter_service.go +++ b/rest/matter_service.go @@ -90,7 +90,6 @@ func (this *MatterService) Upload(file io.Reader, user *User, dirMatter *Matter, this.userService.MatterLock(user.Uuid) defer this.userService.MatterUnlock(user.Uuid) - //验证dirMatter if dirMatter == nil { panic(result.BadRequest("dirMatter cannot be nil.")) @@ -245,14 +244,153 @@ func (this *MatterService) CreateDirectory(dirMatter *Matter, name string, user return matter } +//处理 移动和复制时可能存在的覆盖问题。 +func (this *MatterService) handleOverwrite(userUuid string, destinationPath string, overwrite bool) { + + //目标matter。因为有可能已经存在了 + destMatter := this.matterDao.findByUserUuidAndPath(userUuid, destinationPath) + //如果目标matter存在了。 + if destMatter != nil { + //如果目标matter还存在了。 + if overwrite { + //要求覆盖。那么删除。 + this.matterDao.Delete(destMatter) + } else { + this.PanicBadRequest("%s已经存在,操作失败!", destMatter.Path) + } + } -//将一个srcMatter复制到另一个destMatter(必须为文件夹)下,名字叫做name -func (this *MatterService) Copy(srcMatter *Matter, destDirMatter *Matter, name string) { +} + +//将一个srcMatter放置到另一个destMatter(必须为文件夹)下 不关注 overwrite 和 lock. +func (this *MatterService) innerMove(srcMatter *Matter, destDirMatter *Matter) { + + if srcMatter == nil { + panic(result.BadRequest("srcMatter cannot be nil.")) + } if !destDirMatter.Dir { this.PanicBadRequest("目标必须为文件夹") } + if srcMatter.Dir { + //如果源是文件夹 + destAbsolutePath := destDirMatter.AbsolutePath() + "/" + srcMatter.Name + srcAbsolutePath := srcMatter.AbsolutePath() + + //物理文件一口气移动 + err := os.Rename(srcAbsolutePath, destAbsolutePath) + this.PanicError(err) + + //修改数据库中信息 + srcMatter.Puuid = destDirMatter.Uuid + srcMatter.Path = destDirMatter.Path + "/" + srcMatter.Name + srcMatter = this.matterDao.Save(srcMatter) + + //调整该文件夹下文件的Path. + matters := this.matterDao.List(srcMatter.Uuid, srcMatter.UserUuid, nil) + for _, m := range matters { + this.adjustPath(m, srcMatter) + } + + } else { + //如果源是普通文件 + + destAbsolutePath := destDirMatter.AbsolutePath() + "/" + srcMatter.Name + srcAbsolutePath := srcMatter.AbsolutePath() + + //物理文件进行移动 + err := os.Rename(srcAbsolutePath, destAbsolutePath) + this.PanicError(err) + + //删除对应的缓存。 + this.imageCacheDao.DeleteByMatterUuid(srcMatter.Uuid) + + //修改数据库中信息 + srcMatter.Puuid = destDirMatter.Uuid + srcMatter.Path = destDirMatter.Path + "/" + srcMatter.Name + srcMatter = this.matterDao.Save(srcMatter) + + } + + return +} + +//将一个srcMatter放置到另一个destMatter(必须为文件夹)下 +func (this *MatterService) Move(srcMatter *Matter, destDirMatter *Matter, overwrite bool) { + + if srcMatter == nil { + panic(result.BadRequest("srcMatter cannot be nil.")) + } + + //操作锁 + this.userService.MatterLock(srcMatter.UserUuid) + defer this.userService.MatterUnlock(srcMatter.UserUuid) + + if !destDirMatter.Dir { + this.PanicBadRequest("目标必须为文件夹") + } + + + //文件夹不能把自己移入到自己中,也不可以移入到自己的子文件夹下。 + destDirMatter = this.WrapDetail(destDirMatter) + tmpMatter := destDirMatter + for tmpMatter != nil { + if srcMatter.Uuid == tmpMatter.Uuid { + panic("文件夹不能把自己移入到自己中,也不可以移入到自己的子文件夹下。") + } + tmpMatter = tmpMatter.Parent + } + + //处理覆盖的问题 + destinationPath := destDirMatter.Path + "/" + srcMatter.Name + this.handleOverwrite(srcMatter.UserUuid, destinationPath, overwrite) + + //做move操作。 + this.innerMove(srcMatter, destDirMatter) +} + +//将一个srcMatter放置到另一个destMatter(必须为文件夹)下 +func (this *MatterService) MoveBatch(srcMatters []*Matter, destDirMatter *Matter) { + + if destDirMatter == nil { + panic(result.BadRequest("destDirMatter cannot be nil.")) + } + + //操作锁 + this.userService.MatterLock(destDirMatter.UserUuid) + defer this.userService.MatterUnlock(destDirMatter.UserUuid) + + if srcMatters == nil { + panic(result.BadRequest("srcMatters cannot be nil.")) + } + + if !destDirMatter.Dir { + this.PanicBadRequest("目标必须为文件夹") + } + + //文件夹不能把自己移入到自己中,也不可以移入到自己的子文件夹下。 + destDirMatter = this.WrapDetail(destDirMatter) + for _, srcMatter := range srcMatters { + + tmpMatter := destDirMatter + for tmpMatter != nil { + if srcMatter.Uuid == tmpMatter.Uuid { + panic("文件夹不能把自己移入到自己中,也不可以移入到自己的子文件夹下。") + } + tmpMatter = tmpMatter.Parent + } + } + + for _, srcMatter := range srcMatters { + this.innerMove(srcMatter, destDirMatter) + } + +} + +//内部移动一个文件(提供给Copy调用),无需关心overwrite问题。 +func (this *MatterService) innerCopy(srcMatter *Matter, destDirMatter *Matter, name string) { + if srcMatter.Dir { //如果源是文件夹 @@ -275,10 +413,11 @@ func (this *MatterService) Copy(srcMatter *Matter, destDirMatter *Matter, name s //复制子文件或文件夹 matters := this.matterDao.List(srcMatter.Uuid, srcMatter.UserUuid, nil) for _, m := range matters { - this.Copy(m, newMatter, m.Name) + this.innerCopy(m, newMatter, m.Name) } } else { + //如果源是普通文件 destAbsolutePath := destDirMatter.AbsolutePath() + "/" + name srcAbsolutePath := srcMatter.AbsolutePath() @@ -298,13 +437,113 @@ func (this *MatterService) Copy(srcMatter *Matter, destDirMatter *Matter, name s Privacy: srcMatter.Privacy, Path: destDirMatter.Path + "/" + name, } - newMatter = this.matterDao.Create(newMatter) } +} + +//将一个srcMatter复制到另一个destMatter(必须为文件夹)下,名字叫做name +func (this *MatterService) Copy(srcMatter *Matter, destDirMatter *Matter, name string, overwrite bool) { + + if srcMatter == nil { + panic(result.BadRequest("srcMatter cannot be nil.")) + } + + //操作锁 + this.userService.MatterLock(srcMatter.UserUuid) + defer this.userService.MatterUnlock(srcMatter.UserUuid) + + if !destDirMatter.Dir { + this.PanicBadRequest("目标必须为文件夹") + } + destinationPath := destDirMatter.Path + "/" + name + this.handleOverwrite(srcMatter.UserUuid, destinationPath, overwrite) + + this.innerCopy(srcMatter, destDirMatter, name) } +//将一个matter 重命名为 name +func (this *MatterService) Rename(matter *Matter, name string, user *User) { + + if user == nil { + this.PanicBadRequest("user cannot be nil") + } + + //操作锁 + this.userService.MatterLock(user.Uuid) + defer this.userService.MatterUnlock(user.Uuid) + + //验证参数。 + if name == "" { + this.PanicBadRequest("name参数必填") + } + if m, _ := regexp.MatchString(`[<>|*?/\\]`, name); m { + this.PanicBadRequest(`名称中不能包含以下特殊符号:< > | * ? / \`) + } + + if len(name) > 200 { + panic("name长度不能超过200") + } + + if name == matter.Name { + this.PanicBadRequest("新名称和旧名称一样,操作失败!") + } + + //判断同级文件夹中是否有同名的文件 + count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, matter.Puuid, matter.Dir, name) + + if count > 0 { + this.PanicBadRequest("【" + name + "】已经存在了,请使用其他名称。") + } + + if matter.Dir { + //如果源是文件夹 + + oldAbsolutePath := matter.AbsolutePath() + absoluteDirPath := GetDirOfPath(oldAbsolutePath) + relativeDirPath := GetDirOfPath(matter.Path) + newAbsolutePath := absoluteDirPath + "/" + name + + //物理文件一口气移动 + err := os.Rename(oldAbsolutePath, newAbsolutePath) + this.PanicError(err) + + //修改数据库中信息 + matter.Name = name + matter.Path = relativeDirPath + "/" + name + matter = this.matterDao.Save(matter) + + //调整该文件夹下文件的Path. + matters := this.matterDao.List(matter.Uuid, matter.UserUuid, nil) + for _, m := range matters { + this.adjustPath(m, matter) + } + + } else { + //如果源是普通文件 + + oldAbsolutePath := matter.AbsolutePath() + absoluteDirPath := GetDirOfPath(oldAbsolutePath) + relativeDirPath := GetDirOfPath(matter.Path) + newAbsolutePath := absoluteDirPath + "/" + name + + //物理文件进行移动 + err := os.Rename(oldAbsolutePath, newAbsolutePath) + this.PanicError(err) + + //删除对应的缓存。 + this.imageCacheDao.DeleteByMatterUuid(matter.Uuid) + + //修改数据库中信息 + matter.Name = name + matter.Path = relativeDirPath + "/" + name + matter = this.matterDao.Save(matter) + + } + + return +} //根据一个文件夹路径,找到最后一个文件夹的uuid,如果中途出错,返回err. func (this *MatterService) GetDirUuid(user *User, dir string) (puuid string, dirRelativePath string) { @@ -367,11 +606,12 @@ func (this *MatterService) GetDirUuid(user *User, dir string) (puuid string, dir return puuid, parentRelativePath } +//包装某个matter的详情。会把父级依次倒着装进去。如果中途出错,直接抛出异常。 +func (this *MatterService) WrapDetail(matter *Matter) *Matter { -//获取某个文件的详情,会把父级依次倒着装进去。如果中途出错,直接抛出异常。 -func (this *MatterService) Detail(uuid string) *Matter { - - matter := this.matterDao.CheckByUuid(uuid) + if matter == nil { + this.PanicBadRequest("matter cannot be nil.") + } //组装file的内容,展示其父组件。 puuid := matter.Puuid @@ -386,36 +626,10 @@ func (this *MatterService) Detail(uuid string) *Matter { return matter } -// 从指定的url下载一个文件。参考:https://golangcode.com/download-a-file-from-a-url/ -func (this *MatterService) httpDownloadFile(filepath string, url string) (int64, error) { - - // Create the file - out, err := os.Create(filepath) - if err != nil { - return 0, err - } - defer func() { - e := out.Close() - this.PanicError(e) - }() - - // Get the data - resp, err := http.Get(url) - if err != nil { - return 0, err - } - defer func() { - e := resp.Body.Close() - this.PanicError(e) - }() - - // Write the body to file - size, err := io.Copy(out, resp.Body) - if err != nil { - return 0, err - } - - return size, nil +//获取某个文件的详情,会把父级依次倒着装进去。如果中途出错,直接抛出异常。 +func (this *MatterService) Detail(uuid string) *Matter { + matter := this.matterDao.CheckByUuid(uuid) + return this.WrapDetail(matter) } //去指定的url中爬文件 @@ -432,7 +646,7 @@ func (this *MatterService) Crawl(url string, filename string, user *User, puuid //使用临时文件存放 fmt.Printf("存放于%s", absolutePath) - size, err := this.httpDownloadFile(absolutePath, url) + size, err := download.HttpDownloadFile(absolutePath, url) this.PanicError(err) //判断用户自身上传大小的限制。 @@ -495,128 +709,3 @@ func (this *MatterService) adjustPath(matter *Matter, parentMatter *Matter) { } } - -//将一个srcMatter放置到另一个destMatter(必须为文件夹)下 -func (this *MatterService) Move(srcMatter *Matter, destMatter *Matter) { - - if !destMatter.Dir { - this.PanicBadRequest("目标必须为文件夹") - } - - if srcMatter.Dir { - //如果源是文件夹 - destAbsolutePath := destMatter.AbsolutePath() + "/" + srcMatter.Name - srcAbsolutePath := srcMatter.AbsolutePath() - - //物理文件一口气移动 - err := os.Rename(srcAbsolutePath, destAbsolutePath) - this.PanicError(err) - - //修改数据库中信息 - srcMatter.Puuid = destMatter.Uuid - srcMatter.Path = destMatter.Path + "/" + srcMatter.Name - srcMatter = this.matterDao.Save(srcMatter) - - //调整该文件夹下文件的Path. - matters := this.matterDao.List(srcMatter.Uuid, srcMatter.UserUuid, nil) - for _, m := range matters { - this.adjustPath(m, srcMatter) - } - - } else { - //如果源是普通文件 - - destAbsolutePath := destMatter.AbsolutePath() + "/" + srcMatter.Name - srcAbsolutePath := srcMatter.AbsolutePath() - - //物理文件进行移动 - err := os.Rename(srcAbsolutePath, destAbsolutePath) - this.PanicError(err) - - //删除对应的缓存。 - this.imageCacheDao.DeleteByMatterUuid(srcMatter.Uuid) - - //修改数据库中信息 - srcMatter.Puuid = destMatter.Uuid - srcMatter.Path = destMatter.Path + "/" + srcMatter.Name - srcMatter = this.matterDao.Save(srcMatter) - - } - - return -} - - -//将一个matter 重命名为 name -func (this *MatterService) Rename(matter *Matter, name string, user *User) { - - //验证参数。 - if name == "" { - this.PanicBadRequest("name参数必填") - } - if m, _ := regexp.MatchString(`[<>|*?/\\]`, name); m { - this.PanicBadRequest(`名称中不能包含以下特殊符号:< > | * ? / \`) - } - - if len(name) > 200 { - panic("name长度不能超过200") - } - - if name == matter.Name { - this.PanicBadRequest("新名称和旧名称一样,操作失败!") - } - - //判断同级文件夹中是否有同名的文件 - count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, matter.Puuid, matter.Dir, name) - - if count > 0 { - this.PanicBadRequest("【" + name + "】已经存在了,请使用其他名称。") - } - - if matter.Dir { - //如果源是文件夹 - - oldAbsolutePath := matter.AbsolutePath() - absoluteDirPath := GetDirOfPath(oldAbsolutePath) - relativeDirPath := GetDirOfPath(matter.Path) - newAbsolutePath := absoluteDirPath + "/" + name - - //物理文件一口气移动 - err := os.Rename(oldAbsolutePath, newAbsolutePath) - this.PanicError(err) - - //修改数据库中信息 - matter.Name = name - matter.Path = relativeDirPath + "/" + name - matter = this.matterDao.Save(matter) - - //调整该文件夹下文件的Path. - matters := this.matterDao.List(matter.Uuid, matter.UserUuid, nil) - for _, m := range matters { - this.adjustPath(m, matter) - } - - } else { - //如果源是普通文件 - - oldAbsolutePath := matter.AbsolutePath() - absoluteDirPath := GetDirOfPath(oldAbsolutePath) - relativeDirPath := GetDirOfPath(matter.Path) - newAbsolutePath := absoluteDirPath + "/" + name - - //物理文件进行移动 - err := os.Rename(oldAbsolutePath, newAbsolutePath) - this.PanicError(err) - - //删除对应的缓存。 - this.imageCacheDao.DeleteByMatterUuid(matter.Uuid) - - //修改数据库中信息 - matter.Name = name - matter.Path = relativeDirPath + "/" + name - matter = this.matterDao.Save(matter) - - } - - return -}