Pack 3.0.0.Beta2

This commit is contained in:
zicla 2019-05-07 02:21:39 +08:00
parent 5b95c1a2f4
commit 4780ff8698
26 changed files with 220 additions and 187 deletions

View File

@ -1 +1 @@
<!DOCTYPE html><html><head><title>蓝眼云盘</title><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="user-scalable=no,width=device-width,initial-scale=1,maximum-scale=1"><meta name=msapplication-tap-highlight content=no><meta name=apple-mobile-web-app-capable content=yes><link rel="shortcut icon" href=/favicon.ico><link href=/static/css/app.eea5b41ecb8720462beaae0a0f288d22.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.2ae2e69a05c33dfc65f8.js></script><script type=text/javascript src=/static/js/vendor.b638bbef135b3146e23e.js></script><script type=text/javascript src=/static/js/app.8dcd6f81815de3293ad7.js></script></body></html>
<!DOCTYPE html><html><head><title>蓝眼云盘</title><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="user-scalable=no,width=device-width,initial-scale=1,maximum-scale=1"><meta name=msapplication-tap-highlight content=no><meta name=apple-mobile-web-app-capable content=yes><link rel="shortcut icon" href=/favicon.ico><link href=/static/css/app.8434ac4892014823a9f4b7dfb500b1ff.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=/static/js/manifest.2ae2e69a05c33dfc65f8.js></script><script type=text/javascript src=/static/js/vendor.28b2a104c5c31556c9b7.js></script><script type=text/javascript src=/static/js/app.8360edfd476e2af78ca7.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -11,7 +11,7 @@
@REM prepare the variables.
@REM version name
SET VERSION_NAME=tank-3.0.0.beta1
SET VERSION_NAME=tank-3.0.0.beta2
@REM assign variable like Linux GOARCH=$(go env GOARCH) eg. amd64
FOR /f %%i IN ('go env GOARCH') DO SET GOARCH=%%i
ECHO GOARCH: %GOARCH%
@ -33,16 +33,16 @@ FOR %%F IN (%BUILD_DIR%) DO SET PROJECT_DIR_SLASH=%%~dpF
SET PROJECT_DIR=%PROJECT_DIR_SLASH:~0,-1%
ECHO PROJECT_DIR: %PROJECT_DIR%
@REM final zip file name. eg. tank-3.0.0.beta1.windows-amd64.zip
@REM final zip file name. eg. tank-x.x.x.windows-amd64.zip
SET FILE_NAME=%VERSION_NAME%.%GOOS%-%GOARCH%.zip
ECHO FILE_NAME: %FILE_NAME%
@REM zip dist dir eg. D:\Group\eyeblue\tank\tmp\dist
SET DIST_DIR=%PROJECT_DIR%\tmp\dist
ECHO DIST_DIR: %DIST_DIR%
@REM component dir eg. D:\Group\eyeblue\tank\tmp\dist\tank-3.0.0.beta1
@REM component dir eg. D:\Group\eyeblue\tank\tmp\dist\tank-x.x.x
SET COMPONENT_DIR=%DIST_DIR%\%VERSION_NAME%
ECHO COMPONENT_DIR: %COMPONENT_DIR%
@REM final dist path eg. D:\Group\eyeblue\tank\tmp\dist\tank-3.0.0.beta1.windows-amd64.zip
@REM final dist path eg. D:\Group\eyeblue\tank\tmp\dist\tank-x.x.x.windows-amd64.zip
SET DIST_PATH=%DIST_DIR%\%FILE_NAME%
ECHO DIST_PATH: %DIST_PATH%

View File

@ -9,7 +9,7 @@
#prepare the variables.
# version name
VERSION_NAME=tank-3.0.0.beta1
VERSION_NAME=tank-3.0.0.beta2
echo "VERSION_NAME: ${VERSION_NAME}"
# eg. amd64
GOARCH=$(go env GOARCH)
@ -35,10 +35,10 @@ echo "FILE_NAME: ${FILE_NAME}"
# zip dist dir eg. /data/tank/tmp/dist
DIST_DIR=${PROJECT_DIR}/tmp/dist
echo "DIST_DIR: ${DIST_DIR}"
# component dir eg. /data/tank/tmp/dist/tank-3.0.0.beta1
# component dir eg. /data/tank/tmp/dist/tank-x.x.x
COMPONENT_DIR=${DIST_DIR}/${VERSION_NAME}
echo "COMPONENT_DIR: ${COMPONENT_DIR}"
# final dist path eg. /data/tank/tmp/dist/tank-3.0.0.beta1.darwin-amd64.tar.gz
# final dist path eg. /data/tank/tmp/dist/tank-x.x.x.darwin-amd64.tar.gz
DIST_PATH=${DIST_DIR}/${FILE_NAME}
echo "DIST_PATH: ${DIST_PATH}"

View File

@ -12,7 +12,7 @@ const (
//db table's prefix. tank30_ means current version is tank:3.0.x
TABLE_PREFIX = "tank30_"
VERSION = "3.0.0.beta1"
VERSION = "3.0.0.beta2"
)
type Config interface {

View File

@ -3,6 +3,7 @@ package rest
import (
"fmt"
"github.com/eyebluecn/tank/code/core"
"github.com/eyebluecn/tank/code/tool/i18n"
"github.com/eyebluecn/tank/code/tool/result"
"github.com/eyebluecn/tank/code/tool/util"
"github.com/json-iterator/go"
@ -55,7 +56,7 @@ func (this *BaseController) Wrap(f func(writer http.ResponseWriter, request *htt
if user.Status == USER_STATUS_DISABLED {
//check user's status
webResult = result.ConstWebResult(result.USER_DISABLED)
webResult = result.CustomWebResultI18n(request, result.USER_DISABLED, i18n.UserDisabled)
} else {
if qualifiedRole == USER_ROLE_ADMINISTRATOR && user.Role != USER_ROLE_ADMINISTRATOR {
webResult = result.ConstWebResult(result.UNAUTHORIZED)

View File

@ -103,10 +103,14 @@ var LivePropMap = map[xml.Name]LiveProp{
{Space: "DAV:", Local: "quota-available-bytes"}: {
findFn: func(user *User, matter *Matter) string {
var size int64 = 0
if user.SizeLimit >= 0 {
size = user.SizeLimit
if user.TotalSizeLimit >= 0 {
if user.TotalSizeLimit-user.TotalSize > 0 {
size = user.TotalSizeLimit - user.TotalSize
} else {
size = 0
}
} else {
//TODO: no limit, default 100G.
// no limit, default 100G.
size = 100 * 1024 * 1024 * 1024
}
return fmt.Sprintf(`%d`, size)
@ -115,8 +119,7 @@ var LivePropMap = map[xml.Name]LiveProp{
},
{Space: "DAV:", Local: "quota-used-bytes"}: {
findFn: func(user *User, matter *Matter) string {
//TODO: default 0
return fmt.Sprintf(`%d`, 0)
return fmt.Sprintf(`%d`, user.TotalSize)
},
dir: true,
},

View File

@ -225,7 +225,7 @@ func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Requ
//if exist delete it.
srcMatter := this.matterDao.findByUserUuidAndPath(user.Uuid, subPath)
if srcMatter != nil {
this.matterService.AtomicDelete(request, srcMatter)
this.matterService.AtomicDelete(request, srcMatter, user)
}
this.matterService.Upload(request, request.Body, user, dirMatter, filename, true)
@ -239,7 +239,7 @@ func (this *DavService) HandleDelete(writer http.ResponseWriter, request *http.R
matter := this.matterDao.CheckWithRootByPath(subPath, user)
this.matterService.AtomicDelete(request, matter)
this.matterService.AtomicDelete(request, matter, user)
}
//crate a directory
@ -369,7 +369,7 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req
//if destination path not change. it means rename.
this.matterService.AtomicRename(request, srcMatter, destinationName, user)
} else {
this.matterService.AtomicMove(request, srcMatter, destDirMatter, overwrite)
this.matterService.AtomicMove(request, srcMatter, destDirMatter, overwrite, user)
}
this.logger.Info("finish moving %s => %s", subPath, destDirMatter.Path)
@ -383,7 +383,7 @@ func (this *DavService) HandleCopy(writer http.ResponseWriter, request *http.Req
srcMatter, destDirMatter, _, _, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, subPath)
//copy to the new directory
this.matterService.AtomicCopy(request, srcMatter, destDirMatter, destinationName, overwrite)
this.matterService.AtomicCopy(request, srcMatter, destDirMatter, destinationName, overwrite, user)
this.logger.Info("finish copying %s => %s", subPath, destDirMatter.Path)

View File

@ -294,7 +294,7 @@ func (this *MatterController) Delete(writer http.ResponseWriter, request *http.R
panic(result.UNAUTHORIZED)
}
this.matterService.AtomicDelete(request, matter)
this.matterService.AtomicDelete(request, matter, user)
return this.Success("OK")
}
@ -322,7 +322,7 @@ func (this *MatterController) DeleteBatch(writer http.ResponseWriter, request *h
panic(result.UNAUTHORIZED)
}
this.matterService.AtomicDelete(request, matter)
this.matterService.AtomicDelete(request, matter, user)
}
@ -417,7 +417,7 @@ func (this *MatterController) Move(writer http.ResponseWriter, request *http.Req
srcMatters = append(srcMatters, srcMatter)
}
this.matterService.AtomicMoveBatch(request, srcMatters, destMatter)
this.matterService.AtomicMoveBatch(request, srcMatters, destMatter, user)
return this.Success(nil)
}

View File

@ -332,39 +332,6 @@ func (this *MatterDao) SizeByPuuidAndUserUuid(matterUuid string, userUuid string
return sumSize
}
// compute route size. It will compute upward until root directory
func (this *MatterDao) ComputeRouteSize(matterUuid string, userUuid string) {
//if to root directory, then update to user's info.
if matterUuid == MATTER_ROOT {
size := this.SizeByPuuidAndUserUuid(MATTER_ROOT, userUuid)
db := core.CONTEXT.GetDB().Model(&User{}).Where("uuid = ?", userUuid).Update("total_size", size)
this.PanicError(db.Error)
return
}
matter := this.CheckByUuid(matterUuid)
//only compute dir
if matter.Dir {
//compute the total size.
size := this.SizeByPuuidAndUserUuid(matterUuid, userUuid)
//when changed, we update
if matter.Size != size {
db := core.CONTEXT.GetDB().Model(&Matter{}).Where("uuid = ?", matterUuid).Update("size", size)
this.PanicError(db.Error)
}
}
//update parent recursively.
this.ComputeRouteSize(matter.Puuid, userUuid)
}
//delete a file from db and disk.
func (this *MatterDao) Delete(matter *Matter) {

View File

@ -25,7 +25,7 @@ const (
)
/**
* file
* file is too common. so we use matter as file.
*/
type Matter struct {
Base

View File

@ -242,7 +242,7 @@ func (this *MatterService) zipMatters(request *http.Request, matters []*Matter,
}
//delete files.
func (this *MatterService) Delete(request *http.Request, matter *Matter) {
func (this *MatterService) Delete(request *http.Request, matter *Matter, user *User) {
if matter == nil {
panic(result.BadRequest("matter cannot be nil"))
@ -251,11 +251,11 @@ func (this *MatterService) Delete(request *http.Request, matter *Matter) {
this.matterDao.Delete(matter)
//re compute the size of Route.
this.matterDao.ComputeRouteSize(matter.Puuid, matter.UserUuid)
this.ComputeRouteSize(matter.Puuid, user)
}
//atomic delete files
func (this *MatterService) AtomicDelete(request *http.Request, matter *Matter) {
func (this *MatterService) AtomicDelete(request *http.Request, matter *Matter, user *User) {
if matter == nil {
panic(result.BadRequest("matter cannot be nil"))
@ -265,7 +265,7 @@ func (this *MatterService) AtomicDelete(request *http.Request, matter *Matter) {
this.userService.MatterLock(matter.UserUuid)
defer this.userService.MatterUnlock(matter.UserUuid)
this.Delete(request, matter)
this.Delete(request, matter, user)
}
//upload files.
@ -283,12 +283,19 @@ func (this *MatterService) Upload(request *http.Request, file io.Reader, user *U
panic(result.BadRequestI18n(request, i18n.MatterNameLengthExceedLimit, len(filename), MATTER_NAME_MAX_LENGTH))
}
//check the total size limit.
if user.TotalSizeLimit >= 0 {
if user.TotalSize > user.TotalSizeLimit {
panic(result.BadRequestI18n(request, i18n.MatterSizeExceedTotalLimit, util.HumanFileSize(user.TotalSize), util.HumanFileSize(user.TotalSizeLimit)))
}
}
dirAbsolutePath := dirMatter.AbsolutePath()
dirRelativePath := dirMatter.Path
count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, false, filename)
if count > 0 {
panic(result.BadRequest("%s already exists", filename))
panic(result.BadRequestI18n(request, i18n.MatterExist, filename))
}
fileAbsolutePath := dirAbsolutePath + "/" + filename
@ -344,12 +351,48 @@ func (this *MatterService) Upload(request *http.Request, file io.Reader, user *U
//compute the size of directory
go core.RunWithRecovery(func() {
this.matterDao.ComputeRouteSize(dirMatter.Uuid, user.Uuid)
this.ComputeRouteSize(dirMatter.Uuid, user)
})
return matter
}
// compute route size. It will compute upward until root directory
func (this *MatterService) ComputeRouteSize(matterUuid string, user *User) {
//if to root directory, then update to user's info.
if matterUuid == MATTER_ROOT {
size := this.matterDao.SizeByPuuidAndUserUuid(MATTER_ROOT, user.Uuid)
db := core.CONTEXT.GetDB().Model(&User{}).Where("uuid = ?", user.Uuid).Update("total_size", size)
this.PanicError(db.Error)
//update user total size info in cache.
user.TotalSize = size
return
}
matter := this.matterDao.CheckByUuid(matterUuid)
//only compute dir
if matter.Dir {
//compute the total size.
size := this.matterDao.SizeByPuuidAndUserUuid(matterUuid, user.Uuid)
//when changed, we update
if matter.Size != size {
db := core.CONTEXT.GetDB().Model(&Matter{}).Where("uuid = ?", matterUuid).Update("size", size)
this.PanicError(db.Error)
}
}
//update parent recursively.
this.ComputeRouteSize(matter.Puuid, user)
}
//inner create directory.
func (this *MatterService) createDirectory(request *http.Request, dirMatter *Matter, name string, user *User) *Matter {
@ -427,14 +470,14 @@ func (this *MatterService) AtomicCreateDirectory(request *http.Request, dirMatte
}
//copy or move may overwrite.
func (this *MatterService) handleOverwrite(request *http.Request, userUuid string, destinationPath string, overwrite bool) {
func (this *MatterService) handleOverwrite(request *http.Request, user *User, destinationPath string, overwrite bool) {
destMatter := this.matterDao.findByUserUuidAndPath(userUuid, destinationPath)
destMatter := this.matterDao.findByUserUuidAndPath(user.Uuid, destinationPath)
if destMatter != nil {
//if exist
if overwrite {
//delete.
this.Delete(request, destMatter)
this.Delete(request, destMatter, user)
} else {
panic(result.BadRequestI18n(request, i18n.MatterExist, destMatter.Path))
}
@ -443,7 +486,7 @@ func (this *MatterService) handleOverwrite(request *http.Request, userUuid strin
}
//move srcMatter to destMatter. invoker must handled the overwrite and lock.
func (this *MatterService) move(request *http.Request, srcMatter *Matter, destDirMatter *Matter) {
func (this *MatterService) move(request *http.Request, srcMatter *Matter, destDirMatter *Matter, user *User) {
if srcMatter == nil {
panic(result.BadRequest("srcMatter cannot be nil."))
@ -453,7 +496,6 @@ func (this *MatterService) move(request *http.Request, srcMatter *Matter, destDi
panic(result.BadRequestI18n(request, i18n.MatterDestinationMustDirectory))
}
userUuid := srcMatter.UserUuid
srcPuuid := srcMatter.Puuid
destDirUuid := destDirMatter.Uuid
@ -499,13 +541,13 @@ func (this *MatterService) move(request *http.Request, srcMatter *Matter, destDi
}
//reCompute the size of src and dest.
this.matterDao.ComputeRouteSize(srcPuuid, userUuid)
this.matterDao.ComputeRouteSize(destDirUuid, userUuid)
this.ComputeRouteSize(srcPuuid, user)
this.ComputeRouteSize(destDirUuid, user)
}
//move srcMatter to destMatter(must be dir)
func (this *MatterService) AtomicMove(request *http.Request, srcMatter *Matter, destDirMatter *Matter, overwrite bool) {
func (this *MatterService) AtomicMove(request *http.Request, srcMatter *Matter, destDirMatter *Matter, overwrite bool, user *User) {
if srcMatter == nil {
panic(result.BadRequest("srcMatter cannot be nil."))
@ -533,14 +575,14 @@ func (this *MatterService) AtomicMove(request *http.Request, srcMatter *Matter,
//handle the overwrite
destinationPath := destDirMatter.Path + "/" + srcMatter.Name
this.handleOverwrite(request, srcMatter.UserUuid, destinationPath, overwrite)
this.handleOverwrite(request, user, destinationPath, overwrite)
//do the move operation.
this.move(request, srcMatter, destDirMatter)
this.move(request, srcMatter, destDirMatter, user)
}
//move srcMatters to destMatter(must be dir)
func (this *MatterService) AtomicMoveBatch(request *http.Request, srcMatters []*Matter, destDirMatter *Matter) {
func (this *MatterService) AtomicMoveBatch(request *http.Request, srcMatters []*Matter, destDirMatter *Matter, user *User) {
if destDirMatter == nil {
panic(result.BadRequest("destDirMatter cannot be nil."))
@ -571,7 +613,7 @@ func (this *MatterService) AtomicMoveBatch(request *http.Request, srcMatters []*
}
for _, srcMatter := range srcMatters {
this.move(request, srcMatter, destDirMatter)
this.move(request, srcMatter, destDirMatter, user)
}
}
@ -626,7 +668,7 @@ func (this *MatterService) copy(request *http.Request, srcMatter *Matter, destDi
}
//copy srcMatter to destMatter.
func (this *MatterService) AtomicCopy(request *http.Request, srcMatter *Matter, destDirMatter *Matter, name string, overwrite bool) {
func (this *MatterService) AtomicCopy(request *http.Request, srcMatter *Matter, destDirMatter *Matter, name string, overwrite bool, user *User) {
if srcMatter == nil {
panic(result.BadRequest("srcMatter cannot be nil."))
@ -640,7 +682,7 @@ func (this *MatterService) AtomicCopy(request *http.Request, srcMatter *Matter,
}
destinationPath := destDirMatter.Path + "/" + name
this.handleOverwrite(request, srcMatter.UserUuid, destinationPath, overwrite)
this.handleOverwrite(request, user, destinationPath, overwrite)
this.copy(request, srcMatter, destDirMatter, name)
}
@ -785,7 +827,7 @@ func (this *MatterService) mirror(request *http.Request, srcPath string, destDir
if matter != nil {
//如果是覆盖,那么删除之前的文件
if overwrite {
this.Delete(request, matter)
this.Delete(request, matter, user)
} else {
//直接完成。
return

View File

@ -47,6 +47,10 @@ func (this *UserController) RegisterRoutes() map[string]func(writer http.Respons
func (this *UserController) innerLogin(writer http.ResponseWriter, request *http.Request, user *User) {
if user.Status == USER_STATUS_DISABLED {
panic(result.BadRequestI18n(request, i18n.UserDisabled))
}
//set cookie. expire after 30 days.
expiration := time.Now()
expiration = expiration.AddDate(0, 0, 30)
@ -160,13 +164,16 @@ func (this *UserController) Register(writer http.ResponseWriter, request *http.R
func (this *UserController) Edit(writer http.ResponseWriter, request *http.Request) *result.WebResult {
avatarUrl := request.FormValue("avatarUrl")
uuid := request.FormValue("uuid")
avatarUrl := request.FormValue("avatarUrl")
sizeLimitStr := request.FormValue("sizeLimit")
totalSizeLimitStr := request.FormValue("totalSizeLimit")
user := this.checkUser(request)
currentUser := this.userDao.CheckByUuid(uuid)
currentUser.AvatarUrl = avatarUrl
if user.Role == USER_ROLE_ADMINISTRATOR {
//only admin can edit user's sizeLimit
var sizeLimit int64 = 0
@ -180,12 +187,23 @@ func (this *UserController) Edit(writer http.ResponseWriter, request *http.Reque
sizeLimit = int64(intSizeLimit)
}
currentUser.SizeLimit = sizeLimit
var totalSizeLimit int64 = 0
if totalSizeLimitStr == "" {
panic("user's total limit size is required")
} else {
intTotalSizeLimit, err := strconv.Atoi(totalSizeLimitStr)
if err != nil {
this.PanicError(err)
}
totalSizeLimit = int64(intTotalSizeLimit)
}
currentUser.TotalSizeLimit = totalSizeLimit
} else if user.Uuid != uuid {
panic(result.UNAUTHORIZED)
}
currentUser.AvatarUrl = avatarUrl
currentUser = this.userDao.Save(currentUser)
return this.Success(currentUser)

View File

@ -30,6 +30,7 @@ var (
UserRegisterNotAllowd = &Item{English: `admin has banned register`, Chinese: `管理员已禁用自主注册`}
UserPasswordLengthError = &Item{English: `password at least 6 chars`, Chinese: `密码长度至少为6位`}
UserOldPasswordError = &Item{English: `old password error`, Chinese: `旧密码不正确`}
UserDisabled = &Item{English: `user has been disabled`, Chinese: `用户已经被禁用了`}
MatterDestinationMustDirectory = &Item{English: `destination must be directory'`, Chinese: `目标对象只能是文件夹。`}
MatterExist = &Item{English: `"%s" already exists, invalid operation`, Chinese: `"%s" 已经存在了,操作无效`}
MatterDepthExceedLimit = &Item{English: `directory's depth exceed the limit %d > %d`, Chinese: `文件加层数超过限制 %d > %d `}
@ -37,6 +38,7 @@ var (
MatterSelectNumExceedLimit = &Item{English: `selected files' num exceed the limit %d > %d`, Chinese: `选择的文件数量超出限制了 %d > %d `}
MatterSelectSizeExceedLimit = &Item{English: `selected files' size exceed the limit %s > %s`, Chinese: `选择的文件大小超出限制了 %s > %s `}
MatterSizeExceedLimit = &Item{English: `uploaded file's size exceed the size limit %s > %s `, Chinese: `上传的文件超过了限制 %s > %s `}
MatterSizeExceedTotalLimit = &Item{English: `file's size exceed the total size limit %s > %s `, Chinese: `上传的文件超过了总大小限制 %s > %s `}
MatterNameContainSpecialChars = &Item{English: `file name cannot contain special chars \ / : * ? " < > |"`, Chinese: `名称中不能包含以下特殊符号:\ / : * ? " < > |`}
MatterMoveRecursive = &Item{English: `directory cannot be moved to itself or its children`, Chinese: `文件夹不能把自己移入到自己中,也不可以移入到自己的子文件夹下。`}
MatterNameNoChange = &Item{English: `filename not change, invalid operation`, Chinese: `文件名没有改变,操作无效!`}