|
|
@ -71,53 +71,43 @@ func (this *MatterService) Delete(matter *Matter) { |
|
|
panic(result.BadRequest("matter不能为nil")) |
|
|
panic(result.BadRequest("matter不能为nil")) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//操作锁
|
|
|
//操作锁
|
|
|
this.userService.MatterLock(matter.UserUuid) |
|
|
this.userService.MatterLock(matter.UserUuid) |
|
|
defer this.userService.MatterUnlock(matter.UserUuid) |
|
|
defer this.userService.MatterUnlock(matter.UserUuid) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.matterDao.Delete(matter) |
|
|
this.matterDao.Delete(matter) |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//开始上传文件
|
|
|
//开始上传文件
|
|
|
//上传文件. alien表明文件是否是应用使用的文件。
|
|
|
//上传文件. alien表明文件是否是应用使用的文件。
|
|
|
func (this *MatterService) Upload(file io.Reader, user *User, puuid string, filename string, privacy bool, alien bool) *Matter { |
|
|
func (this *MatterService) Upload(file io.Reader, user *User, dirMatter *Matter, filename string, privacy bool) *Matter { |
|
|
|
|
|
|
|
|
//文件名不能太长。
|
|
|
if user == nil { |
|
|
if len(filename) > 200 { |
|
|
panic(result.BadRequest("user cannot be nil.")) |
|
|
panic("文件名不能超过200") |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//文件夹路径
|
|
|
//操作锁
|
|
|
var dirAbsolutePath string |
|
|
this.userService.MatterLock(user.Uuid) |
|
|
var dirRelativePath string |
|
|
defer this.userService.MatterUnlock(user.Uuid) |
|
|
if puuid == "" { |
|
|
|
|
|
this.PanicBadRequest("puuid必填") |
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
|
|
|
if puuid == MATTER_ROOT { |
|
|
|
|
|
dirAbsolutePath = GetUserFileRootDir(user.Username) |
|
|
|
|
|
dirRelativePath = "" |
|
|
|
|
|
} else { |
|
|
|
|
|
//验证puuid是否存在
|
|
|
|
|
|
dirMatter := this.matterDao.CheckByUuidAndUserUuid(puuid, user.Uuid) |
|
|
|
|
|
|
|
|
|
|
|
dirAbsolutePath = GetUserFileRootDir(user.Username) + dirMatter.Path |
|
|
//验证dirMatter
|
|
|
dirRelativePath = dirMatter.Path |
|
|
if dirMatter == nil { |
|
|
|
|
|
panic(result.BadRequest("dirMatter cannot be nil.")) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
//文件名不能太长。
|
|
|
|
|
|
if len(filename) > MATTER_NAME_MAX_LENGTH { |
|
|
|
|
|
panic(result.BadRequest("文件名不能超过%s", MATTER_NAME_MAX_LENGTH)) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//查找文件夹下面是否有同名文件。
|
|
|
//文件夹路径
|
|
|
matters := this.matterDao.ListByUserUuidAndPuuidAndDirAndName(user.Uuid, puuid, false, filename) |
|
|
dirAbsolutePath := dirMatter.AbsolutePath() |
|
|
//如果有同名的文件,那么我们直接覆盖同名文件。
|
|
|
dirRelativePath := dirMatter.Path |
|
|
for _, dbFile := range matters { |
|
|
|
|
|
this.PanicBadRequest("该目录下%s已经存在了", dbFile.Name) |
|
|
count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, false, filename) |
|
|
|
|
|
if count > 0 { |
|
|
|
|
|
panic(result.BadRequest("该目录下%s已经存在了", filename)) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//获取文件应该存放在的物理路径的绝对路径和相对路径。
|
|
|
//获取文件应该存放在的物理路径的绝对路径和相对路径。
|
|
|
@ -136,112 +126,51 @@ func (this *MatterService) Upload(file io.Reader, user *User, puuid string, file |
|
|
this.PanicError(removeError) |
|
|
this.PanicError(removeError) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
distFile, err := os.OpenFile(fileAbsolutePath, os.O_WRONLY|os.O_CREATE, 0777) |
|
|
destFile, err := os.OpenFile(fileAbsolutePath, os.O_WRONLY|os.O_CREATE, 0777) |
|
|
this.PanicError(err) |
|
|
this.PanicError(err) |
|
|
|
|
|
|
|
|
defer func() { |
|
|
defer func() { |
|
|
err := distFile.Close() |
|
|
err := destFile.Close() |
|
|
this.PanicError(err) |
|
|
this.PanicError(err) |
|
|
}() |
|
|
}() |
|
|
|
|
|
|
|
|
written, err := io.Copy(distFile, file) |
|
|
fileSize, err := io.Copy(destFile, file) |
|
|
this.PanicError(err) |
|
|
this.PanicError(err) |
|
|
|
|
|
|
|
|
this.logger.Info("上传文件%s大小为%v", filename, HumanFileSize(written)) |
|
|
this.logger.Info("上传文件 %s 大小为 %v ", filename, HumanFileSize(fileSize)) |
|
|
|
|
|
|
|
|
//判断用户自身上传大小的限制。
|
|
|
//判断用户自身上传大小的限制。
|
|
|
if user.SizeLimit >= 0 { |
|
|
if user.SizeLimit >= 0 { |
|
|
if written > user.SizeLimit { |
|
|
if fileSize > user.SizeLimit { |
|
|
this.PanicBadRequest("文件大小超出限制 " + HumanFileSize(user.SizeLimit) + ">" + HumanFileSize(written)) |
|
|
//删除上传过来的内容
|
|
|
|
|
|
err = os.Remove(fileAbsolutePath) |
|
|
|
|
|
this.PanicError(err) |
|
|
|
|
|
|
|
|
|
|
|
panic(result.BadRequest("文件大小超出限制 %s > %s ", HumanFileSize(user.SizeLimit), HumanFileSize(fileSize))) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
//将文件信息存入数据库中。
|
|
|
//将文件信息存入数据库中。
|
|
|
matter := &Matter{ |
|
|
matter := &Matter{ |
|
|
Puuid: puuid, |
|
|
Puuid: dirMatter.Uuid, |
|
|
UserUuid: user.Uuid, |
|
|
UserUuid: user.Uuid, |
|
|
Username: user.Username, |
|
|
Username: user.Username, |
|
|
Dir: false, |
|
|
Dir: false, |
|
|
Alien: alien, |
|
|
|
|
|
Name: filename, |
|
|
Name: filename, |
|
|
Md5: "", |
|
|
Md5: "", |
|
|
Size: written, |
|
|
Size: fileSize, |
|
|
Privacy: privacy, |
|
|
Privacy: privacy, |
|
|
Path: fileRelativePath, |
|
|
Path: fileRelativePath, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
matter = this.matterDao.Create(matter) |
|
|
matter = this.matterDao.Create(matter) |
|
|
|
|
|
|
|
|
return matter |
|
|
return matter |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//根据一个文件夹路径,找到最后一个文件夹的uuid,如果中途出错,返回err.
|
|
|
|
|
|
func (this *MatterService) GetDirUuid(user *User, dir string) (puuid string, dirRelativePath string) { |
|
|
|
|
|
|
|
|
|
|
|
if dir == "" { |
|
|
|
|
|
panic(`文件夹不能为空`) |
|
|
|
|
|
} else if dir[0:1] != "/" { |
|
|
|
|
|
panic(`文件夹必须以/开头`) |
|
|
|
|
|
} else if strings.Index(dir, "//") != -1 { |
|
|
|
|
|
panic(`文件夹不能出现连续的//`) |
|
|
|
|
|
} else if m, _ := regexp.MatchString(`[<>|*?\\]`, dir); m { |
|
|
|
|
|
panic(`文件夹中不能包含以下特殊符号:< > | * ? \`) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if dir == "/" { |
|
|
|
|
|
return MATTER_ROOT, "" |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if dir[len(dir)-1] == '/' { |
|
|
|
|
|
dir = dir[:len(dir)-1] |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//递归找寻文件的上级目录uuid.
|
|
|
|
|
|
folders := strings.Split(dir, "/") |
|
|
|
|
|
|
|
|
|
|
|
if len(folders) > 32 { |
|
|
|
|
|
panic("文件夹最多32层。") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
puuid = MATTER_ROOT |
|
|
|
|
|
parentRelativePath := "/" |
|
|
|
|
|
for k, name := range folders { |
|
|
|
|
|
|
|
|
|
|
|
if len(name) > 200 { |
|
|
|
|
|
panic("每级文件夹的最大长度为200") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if k == 0 { |
|
|
|
|
|
continue |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
matter := this.matterDao.FindByUserUuidAndPuuidAndNameAndDirTrue(user.Uuid, puuid, name) |
|
|
|
|
|
if matter == nil { |
|
|
|
|
|
//创建一个文件夹。这里一般都是通过alien接口来创建的文件夹。
|
|
|
|
|
|
matter = &Matter{ |
|
|
|
|
|
Puuid: puuid, |
|
|
|
|
|
UserUuid: user.Uuid, |
|
|
|
|
|
Username: user.Username, |
|
|
|
|
|
Dir: true, |
|
|
|
|
|
Alien: true, |
|
|
|
|
|
Name: name, |
|
|
|
|
|
Path: parentRelativePath + "/" + name, |
|
|
|
|
|
} |
|
|
|
|
|
matter = this.matterDao.Create(matter) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
puuid = matter.Uuid |
|
|
|
|
|
parentRelativePath = matter.Path |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return puuid, parentRelativePath |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//在dirMatter中创建文件夹 返回刚刚创建的这个文件夹
|
|
|
//在dirMatter中创建文件夹 返回刚刚创建的这个文件夹
|
|
|
func (this *MatterService) CreateDirectory(dirMatter *Matter, name string, user *User) *Matter { |
|
|
func (this *MatterService) CreateDirectory(dirMatter *Matter, name string, user *User) *Matter { |
|
|
|
|
|
|
|
|
|
|
|
//操作锁
|
|
|
this.userService.MatterLock(user.Uuid) |
|
|
this.userService.MatterLock(user.Uuid) |
|
|
defer this.userService.MatterUnlock(user.Uuid) |
|
|
defer this.userService.MatterUnlock(user.Uuid) |
|
|
|
|
|
|
|
|
@ -273,7 +202,6 @@ func (this *MatterService) CreateDirectory(dirMatter *Matter, name string, user |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if m, _ := regexp.MatchString(`[<>|*?/\\]`, name); m { |
|
|
if m, _ := regexp.MatchString(`[<>|*?/\\]`, name); m { |
|
|
|
|
|
|
|
|
panic(result.BadRequest(`名称中不能包含以下特殊符号:< > | * ? / \`)) |
|
|
panic(result.BadRequest(`名称中不能包含以下特殊符号:< > | * ? / \`)) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -317,6 +245,129 @@ func (this *MatterService) CreateDirectory(dirMatter *Matter, name string, user |
|
|
return matter |
|
|
return matter |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//将一个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, |
|
|
|
|
|
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, |
|
|
|
|
|
Name: name, |
|
|
|
|
|
Md5: "", |
|
|
|
|
|
Size: srcMatter.Size, |
|
|
|
|
|
Privacy: srcMatter.Privacy, |
|
|
|
|
|
Path: destDirMatter.Path + "/" + name, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
newMatter = this.matterDao.Create(newMatter) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//根据一个文件夹路径,找到最后一个文件夹的uuid,如果中途出错,返回err.
|
|
|
|
|
|
func (this *MatterService) GetDirUuid(user *User, dir string) (puuid string, dirRelativePath string) { |
|
|
|
|
|
|
|
|
|
|
|
if dir == "" { |
|
|
|
|
|
panic(`文件夹不能为空`) |
|
|
|
|
|
} else if dir[0:1] != "/" { |
|
|
|
|
|
panic(`文件夹必须以/开头`) |
|
|
|
|
|
} else if strings.Index(dir, "//") != -1 { |
|
|
|
|
|
panic(`文件夹不能出现连续的//`) |
|
|
|
|
|
} else if m, _ := regexp.MatchString(`[<>|*?\\]`, dir); m { |
|
|
|
|
|
panic(`文件夹中不能包含以下特殊符号:< > | * ? \`) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if dir == "/" { |
|
|
|
|
|
return MATTER_ROOT, "" |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if dir[len(dir)-1] == '/' { |
|
|
|
|
|
dir = dir[:len(dir)-1] |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//递归找寻文件的上级目录uuid.
|
|
|
|
|
|
folders := strings.Split(dir, "/") |
|
|
|
|
|
|
|
|
|
|
|
if len(folders) > 32 { |
|
|
|
|
|
panic("文件夹最多32层。") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
puuid = MATTER_ROOT |
|
|
|
|
|
parentRelativePath := "/" |
|
|
|
|
|
for k, name := range folders { |
|
|
|
|
|
|
|
|
|
|
|
if len(name) > 200 { |
|
|
|
|
|
panic("每级文件夹的最大长度为200") |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if k == 0 { |
|
|
|
|
|
continue |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
matter := this.matterDao.FindByUserUuidAndPuuidAndNameAndDirTrue(user.Uuid, puuid, name) |
|
|
|
|
|
if matter == nil { |
|
|
|
|
|
//创建一个文件夹。这里一般都是通过alien接口来创建的文件夹。
|
|
|
|
|
|
matter = &Matter{ |
|
|
|
|
|
Puuid: puuid, |
|
|
|
|
|
UserUuid: user.Uuid, |
|
|
|
|
|
Username: user.Username, |
|
|
|
|
|
Dir: true, |
|
|
|
|
|
Name: name, |
|
|
|
|
|
Path: parentRelativePath + "/" + name, |
|
|
|
|
|
} |
|
|
|
|
|
matter = this.matterDao.Create(matter) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
puuid = matter.Uuid |
|
|
|
|
|
parentRelativePath = matter.Path |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return puuid, parentRelativePath |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//获取某个文件的详情,会把父级依次倒着装进去。如果中途出错,直接抛出异常。
|
|
|
//获取某个文件的详情,会把父级依次倒着装进去。如果中途出错,直接抛出异常。
|
|
|
func (this *MatterService) Detail(uuid string) *Matter { |
|
|
func (this *MatterService) Detail(uuid string) *Matter { |
|
|
|
|
|
|
|
|
@ -404,7 +455,6 @@ func (this *MatterService) Crawl(url string, filename string, user *User, puuid |
|
|
UserUuid: user.Uuid, |
|
|
UserUuid: user.Uuid, |
|
|
Username: user.Username, |
|
|
Username: user.Username, |
|
|
Dir: false, |
|
|
Dir: false, |
|
|
Alien: false, |
|
|
|
|
|
Name: filename, |
|
|
Name: filename, |
|
|
Md5: "", |
|
|
Md5: "", |
|
|
Size: size, |
|
|
Size: size, |
|
|
@ -496,66 +546,6 @@ func (this *MatterService) Move(srcMatter *Matter, destMatter *Matter) { |
|
|
return |
|
|
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
|
|
|
//将一个matter 重命名为 name
|
|
|
func (this *MatterService) Rename(matter *Matter, name string, user *User) { |
|
|
func (this *MatterService) Rename(matter *Matter, name string, user *User) { |
|
|
|