From 9e6d2c1043694aeff4239810dc5b2175eb66c460 Mon Sep 17 00:00:00 2001 From: lishuang Date: Sat, 27 May 2023 14:12:35 +0800 Subject: [PATCH] feat: remove the space props in the user model. --- code/rest/alien_controller.go | 42 +++--- code/rest/alien_service.go | 4 +- code/rest/base_controller.go | 9 +- code/rest/dav_controller.go | 13 +- code/rest/dav_model.go | 34 ++--- code/rest/dav_service.go | 112 ++++++++-------- code/rest/image_cache_dao.go | 12 +- code/rest/image_cache_model.go | 2 +- code/rest/image_cache_service.go | 8 +- code/rest/install_controller.go | 25 +++- code/rest/matter_controller.go | 45 ++++--- code/rest/matter_dao.go | 42 +++++- code/rest/matter_model.go | 21 +-- code/rest/matter_service.go | 222 ++++++++++++++++--------------- code/rest/space_model.go | 2 +- code/rest/task_service.go | 28 ++-- code/rest/user_controller.go | 78 +++-------- code/rest/user_dao.go | 22 ++- code/rest/user_model.go | 28 ++-- code/rest/user_service.go | 28 +++- code/tool/i18n/i18n.go | 1 - 21 files changed, 422 insertions(+), 356 deletions(-) diff --git a/code/rest/alien_controller.go b/code/rest/alien_controller.go index fdc3ac4..81671ee 100644 --- a/code/rest/alien_controller.go +++ b/code/rest/alien_controller.go @@ -15,6 +15,7 @@ type AlienController struct { uploadTokenDao *UploadTokenDao downloadTokenDao *DownloadTokenDao matterDao *MatterDao + spaceDao *SpaceDao matterService *MatterService imageCacheDao *ImageCacheDao imageCacheService *ImageCacheService @@ -40,6 +41,11 @@ func (this *AlienController) Init() { this.matterDao = c } + b = core.CONTEXT.GetBean(this.spaceDao) + if c, ok := b.(*SpaceDao); ok { + this.spaceDao = c + } + b = core.CONTEXT.GetBean(this.matterService) if c, ok := b.(*MatterService); ok { this.matterService = c @@ -80,7 +86,7 @@ func (this *AlienController) RegisterRoutes() map[string]func(writer http.Respon return routeMap } -//handle some special routes, eg. params in the url. +// handle some special routes, eg. params in the url. func (this *AlienController) HandleRoutes(writer http.ResponseWriter, request *http.Request) (func(writer http.ResponseWriter, request *http.Request), bool) { path := request.URL.Path @@ -108,7 +114,7 @@ func (this *AlienController) HandleRoutes(writer http.ResponseWriter, request *h return nil, false } -//fetch a upload token for guest. Guest can upload file with this token. +// fetch a upload token for guest. Guest can upload file with this token. func (this *AlienController) FetchUploadToken(writer http.ResponseWriter, request *http.Request) *result.WebResult { filename := request.FormValue("filename") @@ -151,7 +157,8 @@ func (this *AlienController) FetchUploadToken(writer http.ResponseWriter, reques } user := this.checkUser(request) - dirMatter := this.matterService.CreateDirectories(request, user, dirPath) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) + dirMatter := this.matterService.CreateDirectories(request, user, space, dirPath) uploadToken := &UploadToken{ UserUuid: user.Uuid, @@ -170,7 +177,7 @@ func (this *AlienController) FetchUploadToken(writer http.ResponseWriter, reques } -//user confirm a file whether uploaded successfully. +// user confirm a file whether uploaded successfully. func (this *AlienController) Confirm(writer http.ResponseWriter, request *http.Request) *result.WebResult { matterUuid := request.FormValue("matterUuid") @@ -188,7 +195,7 @@ func (this *AlienController) Confirm(writer http.ResponseWriter, request *http.R return this.Success(matter) } -//a guest upload a file with a upload token. +// a guest upload a file with a upload token. func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Request) *result.WebResult { //allow cors. this.allowCORS(writer) @@ -216,6 +223,7 @@ func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Re } user := this.userDao.CheckByUuid(uploadToken.UserUuid) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) err = request.ParseMultipartForm(32 << 20) this.PanicError(err) @@ -228,9 +236,9 @@ func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Re panic(result.BadRequest("file size doesn't the one in uploadToken")) } - dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, user) + dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, user, space) - matter := this.matterService.Upload(request, file, user, dirMatter, uploadToken.Filename, uploadToken.Privacy) + matter := this.matterService.Upload(request, file, user, space, dirMatter, uploadToken.Filename, uploadToken.Privacy) //expire the upload token. uploadToken.ExpireTime = time.Now() @@ -239,7 +247,7 @@ func (this *AlienController) Upload(writer http.ResponseWriter, request *http.Re return this.Success(matter) } -//crawl a url with uploadToken. guest can visit this method. +// crawl a url with uploadToken. guest can visit this method. func (this *AlienController) CrawlToken(writer http.ResponseWriter, request *http.Request) *result.WebResult { //allow cors. @@ -263,10 +271,11 @@ func (this *AlienController) CrawlToken(writer http.ResponseWriter, request *htt } user := this.userDao.CheckByUuid(uploadToken.UserUuid) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) - dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, user) + dirMatter := this.matterDao.CheckWithRootByUuid(uploadToken.FolderUuid, user, space) - matter := this.matterService.AtomicCrawl(request, url, uploadToken.Filename, user, dirMatter, uploadToken.Privacy) + matter := this.matterService.AtomicCrawl(request, url, uploadToken.Filename, user, space, dirMatter, uploadToken.Privacy) //expire the upload token. uploadToken.ExpireTime = time.Now() @@ -275,7 +284,7 @@ func (this *AlienController) CrawlToken(writer http.ResponseWriter, request *htt return this.Success(matter) } -//crawl a url directly. only user can visit this method. +// crawl a url directly. only user can visit this method. func (this *AlienController) CrawlDirect(writer http.ResponseWriter, request *http.Request) *result.WebResult { filename := request.FormValue("filename") @@ -291,14 +300,15 @@ func (this *AlienController) CrawlDirect(writer http.ResponseWriter, request *ht } user := this.checkUser(request) - dirMatter := this.matterService.CreateDirectories(request, user, dirPath) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) + dirMatter := this.matterService.CreateDirectories(request, user, space, dirPath) - matter := this.matterService.AtomicCrawl(request, url, filename, user, dirMatter, privacy) + matter := this.matterService.AtomicCrawl(request, url, filename, user, space, dirMatter, privacy) return this.Success(matter) } -//fetch a download token for guest. Guest can download file with this token. +// fetch a download token for guest. Guest can download file with this token. func (this *AlienController) FetchDownloadToken(writer http.ResponseWriter, request *http.Request) *result.WebResult { matterUuid := request.FormValue("matterUuid") @@ -338,13 +348,13 @@ func (this *AlienController) FetchDownloadToken(writer http.ResponseWriter, requ } -//preview a file. +// preview a file. func (this *AlienController) Preview(writer http.ResponseWriter, request *http.Request, uuid string, filename string) { this.alienService.PreviewOrDownload(writer, request, uuid, filename, false) } -//download a file. +// download a file. func (this *AlienController) Download(writer http.ResponseWriter, request *http.Request, uuid string, filename string) { this.alienService.PreviewOrDownload(writer, request, uuid, filename, true) diff --git a/code/rest/alien_service.go b/code/rest/alien_service.go index 06f817f..63983e1 100644 --- a/code/rest/alien_service.go +++ b/code/rest/alien_service.go @@ -8,7 +8,7 @@ import ( "time" ) -//@Service +// @Service type AlienService struct { BaseBean matterDao *MatterDao @@ -135,7 +135,7 @@ func (this *AlienService) PreviewOrDownload( } //download the cache image file. - this.matterService.DownloadFile(writer, request, GetUserCacheRootDir(imageCache.Username)+imageCache.Path, imageCache.Name, withContentDisposition) + this.matterService.DownloadFile(writer, request, GetSpaceCacheRootDir(imageCache.Username)+imageCache.Path, imageCache.Name, withContentDisposition) } else { this.matterService.DownloadFile(writer, request, matter.AbsolutePath(), matter.Name, withContentDisposition) diff --git a/code/rest/base_controller.go b/code/rest/base_controller.go index e2d5ad9..fcbd54d 100644 --- a/code/rest/base_controller.go +++ b/code/rest/base_controller.go @@ -14,6 +14,7 @@ import ( type BaseController struct { BaseBean userDao *UserDao + spaceDao *SpaceDao sessionDao *SessionDao } @@ -38,12 +39,12 @@ func (this *BaseController) RegisterRoutes() map[string]func(writer http.Respons return make(map[string]func(writer http.ResponseWriter, request *http.Request)) } -//handle some special routes, eg. params in the url. +// handle some special routes, eg. params in the url. func (this *BaseController) HandleRoutes(writer http.ResponseWriter, request *http.Request) (func(writer http.ResponseWriter, request *http.Request), bool) { return nil, false } -//wrap the handle method. +// wrap the handle method. func (this *BaseController) Wrap(f func(writer http.ResponseWriter, request *http.Request) *result.WebResult, qualifiedRole string) func(w http.ResponseWriter, r *http.Request) { return func(writer http.ResponseWriter, request *http.Request) { @@ -87,7 +88,7 @@ func (this *BaseController) Wrap(f func(writer http.ResponseWriter, request *htt } } -//response a success result. 1.string 2. WebResult 3.nil pointer 4.any type +// response a success result. 1.string 2. WebResult 3.nil pointer 4.any type func (this *BaseController) Success(data interface{}) *result.WebResult { var webResult *result.WebResult = nil if value, ok := data.(string); ok { @@ -106,7 +107,7 @@ func (this *BaseController) Success(data interface{}) *result.WebResult { return webResult } -//allow cors. +// allow cors. func (this *BaseController) allowCORS(writer http.ResponseWriter) { util.AllowCORS(writer) } diff --git a/code/rest/dav_controller.go b/code/rest/dav_controller.go index 5f2781e..3bfbef9 100644 --- a/code/rest/dav_controller.go +++ b/code/rest/dav_controller.go @@ -25,6 +25,7 @@ type DavController struct { BaseController uploadTokenDao *UploadTokenDao downloadTokenDao *DownloadTokenDao + spaceDao *SpaceDao matterDao *MatterDao matterService *MatterService imageCacheDao *ImageCacheDao @@ -50,6 +51,11 @@ func (this *DavController) Init() { this.matterDao = c } + b = core.CONTEXT.GetBean(this.spaceDao) + if c, ok := b.(*SpaceDao); ok { + this.spaceDao = c + } + b = core.CONTEXT.GetBean(this.matterService) if c, ok := b.(*MatterService); ok { this.matterService = c @@ -71,7 +77,7 @@ func (this *DavController) Init() { } } -//Auth user by BasicAuth +// Auth user by BasicAuth func (this *DavController) CheckCurrentUser(writer http.ResponseWriter, request *http.Request) *User { username, password, ok := request.BasicAuth() @@ -100,7 +106,7 @@ func (this *DavController) RegisterRoutes() map[string]func(writer http.Response return routeMap } -//handle some special routes, eg. params in the url. +// handle some special routes, eg. params in the url. func (this *DavController) HandleRoutes(writer http.ResponseWriter, request *http.Request) (func(writer http.ResponseWriter, request *http.Request), bool) { path := request.URL.Path @@ -166,7 +172,8 @@ func (this *DavController) Index(writer http.ResponseWriter, request *http.Reque //this.debug(writer, request, subPath) user := this.CheckCurrentUser(writer, request) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) - this.davService.HandleDav(writer, request, user, subPath) + this.davService.HandleDav(writer, request, user, space, subPath) } diff --git a/code/rest/dav_model.go b/code/rest/dav_model.go index 07adfda..09a338d 100644 --- a/code/rest/dav_model.go +++ b/code/rest/dav_model.go @@ -9,19 +9,19 @@ import ( "strconv" ) -//webdav url prefix. +// webdav url prefix. var WEBDAV_PREFIX = "/api/dav" -//live prop. +// live prop. type LiveProp struct { - findFn func(user *User, matter *Matter) string + findFn func(space *Space, matter *Matter) string dir bool } -//all live prop map. +// all live prop map. var LivePropMap = map[xml.Name]LiveProp{ {Space: "DAV:", Local: "resourcetype"}: { - findFn: func(user *User, matter *Matter) string { + findFn: func(space *Space, matter *Matter) string { if matter.Dir { return `` } else { @@ -31,7 +31,7 @@ var LivePropMap = map[xml.Name]LiveProp{ dir: true, }, {Space: "DAV:", Local: "displayname"}: { - findFn: func(user *User, matter *Matter) string { + findFn: func(space *Space, matter *Matter) string { if path.Clean("/"+matter.Name) == "/" { return "" } else { @@ -41,13 +41,13 @@ var LivePropMap = map[xml.Name]LiveProp{ dir: true, }, {Space: "DAV:", Local: "getcontentlength"}: { - findFn: func(user *User, matter *Matter) string { + findFn: func(space *Space, matter *Matter) string { return strconv.FormatInt(matter.Size, 10) }, dir: false, }, {Space: "DAV:", Local: "getlastmodified"}: { - findFn: func(user *User, matter *Matter) string { + findFn: func(space *Space, matter *Matter) string { return matter.UpdateTime.UTC().Format(http.TimeFormat) }, // http://webdav.org/specs/rfc4918.html#PROPERTY_getlastmodified @@ -68,7 +68,7 @@ var LivePropMap = map[xml.Name]LiveProp{ dir: false, }, {Space: "DAV:", Local: "getcontenttype"}: { - findFn: func(user *User, matter *Matter) string { + findFn: func(space *Space, matter *Matter) string { if matter.Dir { return "" } else { @@ -78,7 +78,7 @@ var LivePropMap = map[xml.Name]LiveProp{ dir: false, }, {Space: "DAV:", Local: "getetag"}: { - findFn: func(user *User, matter *Matter) string { + findFn: func(space *Space, matter *Matter) string { return fmt.Sprintf(`"%x%x"`, matter.UpdateTime.UnixNano(), matter.Size) }, // findETag implements ETag as the concatenated hex values of a file's @@ -91,7 +91,7 @@ var LivePropMap = map[xml.Name]LiveProp{ // active locks on a resource. {Space: "DAV:", Local: "lockdiscovery"}: {}, {Space: "DAV:", Local: "supportedlock"}: { - findFn: func(user *User, matter *Matter) string { + findFn: func(space *Space, matter *Matter) string { return `` + `` + `` + @@ -101,11 +101,11 @@ var LivePropMap = map[xml.Name]LiveProp{ dir: true, }, {Space: "DAV:", Local: "quota-available-bytes"}: { - findFn: func(user *User, matter *Matter) string { + findFn: func(space *Space, matter *Matter) string { var size int64 = 0 - if user.TotalSizeLimit >= 0 { - if user.TotalSizeLimit-user.TotalSize > 0 { - size = user.TotalSizeLimit - user.TotalSize + if space.TotalSizeLimit >= 0 { + if space.TotalSizeLimit-space.TotalSize > 0 { + size = space.TotalSizeLimit - space.TotalSize } else { size = 0 } @@ -118,8 +118,8 @@ var LivePropMap = map[xml.Name]LiveProp{ dir: true, }, {Space: "DAV:", Local: "quota-used-bytes"}: { - findFn: func(user *User, matter *Matter) string { - return fmt.Sprintf(`%d`, user.TotalSize) + findFn: func(space *Space, matter *Matter) string { + return fmt.Sprintf(`%d`, space.TotalSize) }, dir: true, }, diff --git a/code/rest/dav_service.go b/code/rest/dav_service.go index 3abf8be..5ed6936 100644 --- a/code/rest/dav_service.go +++ b/code/rest/dav_service.go @@ -49,7 +49,7 @@ func (this *DavService) Init() { this.lockSystem = webdav.NewMemLS() } -//get the depth in header. Not support infinity yet. +// get the depth in header. Not support infinity yet. func (this *DavService) ParseDepth(request *http.Request) int { depth := 1 @@ -88,8 +88,8 @@ func (this *DavService) makePropstatResponse(href string, pstats []dav.Propstat) return &resp } -//fetch a matter's []dav.Propstat -func (this *DavService) PropstatsFromXmlNames(user *User, matter *Matter, xmlNames []xml.Name) []dav.Propstat { +// fetch a matter's []dav.Propstat +func (this *DavService) PropstatsFromXmlNames(user *User, space *Space, matter *Matter, xmlNames []xml.Name) []dav.Propstat { propstats := make([]dav.Propstat, 0) @@ -101,7 +101,7 @@ func (this *DavService) PropstatsFromXmlNames(user *User, matter *Matter, xmlNam // Otherwise, it must either be a live property or we don't know it. if liveProp := LivePropMap[xmlName]; liveProp.findFn != nil && (liveProp.dir || !matter.Dir) { - innerXML := liveProp.findFn(user, matter) + innerXML := liveProp.findFn(space, matter) okProperties = append(okProperties, dav.Property{ XMLName: xmlName, @@ -162,7 +162,7 @@ func (this *DavService) AllPropXmlNames(matter *Matter) []xml.Name { return pnames } -func (this *DavService) Propstats(user *User, matter *Matter, propfind *dav.Propfind) []dav.Propstat { +func (this *DavService) Propstats(user *User, space *Space, matter *Matter, propfind *dav.Propfind) []dav.Propstat { propstats := make([]dav.Propstat, 0) if propfind.Propname != nil { @@ -172,18 +172,18 @@ func (this *DavService) Propstats(user *User, matter *Matter, propfind *dav.Prop //TODO: if include other things. add to it. xmlNames := this.AllPropXmlNames(matter) - propstats = this.PropstatsFromXmlNames(user, matter, xmlNames) + propstats = this.PropstatsFromXmlNames(user, space, matter, xmlNames) } else { - propstats = this.PropstatsFromXmlNames(user, matter, propfind.Prop) + propstats = this.PropstatsFromXmlNames(user, space, matter, propfind.Prop) } return propstats } -//list the directory. -func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { +// list the directory. +func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) { fmt.Printf("PROPFIND %s\n", subPath) @@ -193,7 +193,7 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http propfind := dav.ReadPropfind(request.Body) //find the matter, if subPath is null, means the root directory. - matter := this.matterDao.CheckWithRootByPath(subPath, user) + matter := this.matterDao.CheckWithRootByPath(subPath, user, space) var matters []*Matter if depth == 0 { @@ -213,7 +213,7 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http fmt.Printf("handle Matter %s\n", matter.Path) - propstats := this.Propstats(user, matter, propfind) + propstats := this.Propstats(user, space, matter, propfind) visitPath := fmt.Sprintf("%s%s", WEBDAV_PREFIX, matter.Path) response := this.makePropstatResponse(visitPath, propstats) @@ -228,7 +228,7 @@ func (this *DavService) HandlePropfind(writer http.ResponseWriter, request *http } -//change the file's property +// change the file's property func (this *DavService) HandleProppatch(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { fmt.Printf("PROPPATCH %s\n", subPath) @@ -296,16 +296,16 @@ func (this *DavService) HandleProppatch(writer http.ResponseWriter, request *htt } -//handle download -func (this *DavService) HandleGetHeadPost(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { +// handle download +func (this *DavService) HandleGetHeadPost(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) { fmt.Printf("GET %s\n", subPath) - matter := this.matterDao.CheckWithRootByPath(subPath, user) + matter := this.matterDao.CheckWithRootByPath(subPath, user, space) //if this is a Directory, it means Propfind if matter.Dir { - this.HandlePropfind(writer, request, user, subPath) + this.HandlePropfind(writer, request, user, space, subPath) return } @@ -314,8 +314,8 @@ func (this *DavService) HandleGetHeadPost(writer http.ResponseWriter, request *h } -//upload a file -func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { +// upload a file +func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) { fmt.Printf("PUT %s\n", subPath) @@ -339,23 +339,23 @@ func (this *DavService) HandlePut(writer http.ResponseWriter, request *http.Requ filename := util.GetFilenameOfPath(subPath) dirPath := util.GetDirOfPath(subPath) - dirMatter := this.matterDao.CheckWithRootByPath(dirPath, user) + dirMatter := this.matterDao.CheckWithRootByPath(dirPath, user, space) //if exist delete it. srcMatter := this.matterDao.findByUserUuidAndPath(user.Uuid, subPath) if srcMatter != nil { - this.matterService.AtomicDelete(request, srcMatter, user) + this.matterService.AtomicDelete(request, srcMatter, user, space) } - this.matterService.Upload(request, request.Body, user, dirMatter, filename, true) + this.matterService.Upload(request, request.Body, user, space, dirMatter, filename, true) //set the status code 201 writer.WriteHeader(http.StatusCreated) } -//delete file -func (this *DavService) HandleDelete(w http.ResponseWriter, r *http.Request, user *User, subPath string) { +// delete file +func (this *DavService) HandleDelete(w http.ResponseWriter, r *http.Request, user *User, space *Space, subPath string) { fmt.Printf("DELETE %s\n", subPath) @@ -371,13 +371,13 @@ func (this *DavService) HandleDelete(w http.ResponseWriter, r *http.Request, use defer release() } - matter := this.matterDao.CheckWithRootByPath(subPath, user) + matter := this.matterDao.CheckWithRootByPath(subPath, user, space) - this.matterService.AtomicDelete(r, matter, user) + this.matterService.AtomicDelete(r, matter, user, space) } -//crate a directory -func (this *DavService) HandleMkcol(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { +// crate a directory +func (this *DavService) HandleMkcol(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) { fmt.Printf("MKCOL %s\n", subPath) @@ -395,7 +395,7 @@ func (this *DavService) HandleMkcol(writer http.ResponseWriter, request *http.Re thisDirName := util.GetFilenameOfPath(subPath) dirPath := util.GetDirOfPath(subPath) - dirMatter := this.matterDao.FindWithRootByPath(dirPath, user) + dirMatter := this.matterDao.FindWithRootByPath(dirPath, user, space) if dirMatter == nil { //throw conflict error panic(result.CustomWebResult(result.CONFLICT, fmt.Sprintf("%s not exist", dirPath))) @@ -417,12 +417,12 @@ func (this *DavService) HandleMkcol(writer http.ResponseWriter, request *http.Re } -//cors options -func (this *DavService) HandleOptions(w http.ResponseWriter, r *http.Request, user *User, subPath string) { +// cors options +func (this *DavService) HandleOptions(w http.ResponseWriter, r *http.Request, user *User, space *Space, subPath string) { fmt.Printf("OPTIONS %s\n", subPath) - matter := this.matterDao.CheckWithRootByPath(subPath, user) + matter := this.matterDao.CheckWithRootByPath(subPath, user, space) allow := "OPTIONS, LOCK, PUT, MKCOL" if matter.Dir { @@ -439,11 +439,11 @@ func (this *DavService) HandleOptions(w http.ResponseWriter, r *http.Request, us } -//prepare for moving or copying +// prepare for moving or copying func (this *DavService) prepareMoveCopy( writer http.ResponseWriter, request *http.Request, - user *User, subPath string) ( + user *User, space *Space, subPath string) ( srcMatter *Matter, destDirMatter *Matter, srcDirPath string, @@ -506,14 +506,14 @@ func (this *DavService) prepareMoveCopy( } //source matter - srcMatter = this.matterDao.CheckWithRootByPath(subPath, user) + srcMatter = this.matterDao.CheckWithRootByPath(subPath, user, space) //if source matter is root. if srcMatter.Uuid == MATTER_ROOT { panic(result.BadRequest("you cannot move the root directory")) } - destDirMatter = this.matterDao.FindWithRootByPath(destinationDirPath, user) + destDirMatter = this.matterDao.FindWithRootByPath(destinationDirPath, user, space) if destDirMatter == nil { //throw conflict error panic(result.CustomWebResult(result.CONFLICT, fmt.Sprintf("%s not exist", destinationDirPath))) @@ -523,8 +523,8 @@ func (this *DavService) prepareMoveCopy( } -//move or rename. -func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { +// move or rename. +func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) { fmt.Printf("MOVE %s\n", subPath) @@ -541,14 +541,14 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req defer release() } - srcMatter, destDirMatter, srcDirPath, destinationDirPath, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, subPath) + srcMatter, destDirMatter, srcDirPath, destinationDirPath, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, space, subPath) //move to the new directory if destinationDirPath == srcDirPath { //if destination path not change. it means rename. - this.matterService.AtomicRename(request, srcMatter, destinationName, overwrite, user) + this.matterService.AtomicRename(request, srcMatter, destinationName, overwrite, user, space) } else { - this.matterService.AtomicMove(request, srcMatter, destDirMatter, overwrite, user) + this.matterService.AtomicMove(request, srcMatter, destDirMatter, overwrite, user, space) } this.logger.Info("finish moving %s => %s", subPath, destDirMatter.Path) @@ -562,12 +562,12 @@ func (this *DavService) HandleMove(writer http.ResponseWriter, request *http.Req } } -//copy file/directory -func (this *DavService) HandleCopy(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { +// copy file/directory +func (this *DavService) HandleCopy(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) { fmt.Printf("COPY %s\n", subPath) - srcMatter, destDirMatter, _, _, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, subPath) + srcMatter, destDirMatter, _, _, destinationName, overwrite := this.prepareMoveCopy(writer, request, user, space, subPath) // handle the lock feature. release, status, err := this.confirmLocks(request, destDirMatter.Path+"/"+destinationName, "") @@ -579,7 +579,7 @@ func (this *DavService) HandleCopy(writer http.ResponseWriter, request *http.Req } //copy to the new directory - this.matterService.AtomicCopy(request, srcMatter, destDirMatter, destinationName, overwrite, user) + this.matterService.AtomicCopy(request, srcMatter, destDirMatter, destinationName, overwrite, user, space) this.logger.Info("finish copying %s => %s", subPath, destDirMatter.Path) @@ -688,7 +688,7 @@ func (h *DavService) confirmLocks(r *http.Request, src, dst string) (release fun return nil, http.StatusLocked, webdav.ErrLocked } -//lock. +// lock. func (this *DavService) HandleLock(w http.ResponseWriter, r *http.Request, user *User, subPath string) { duration, err := webdav.ParseTimeout(r.Header.Get("Timeout")) @@ -785,7 +785,7 @@ func (this *DavService) HandleLock(w http.ResponseWriter, r *http.Request, user } -//unlock +// unlock func (this *DavService) HandleUnlock(w http.ResponseWriter, r *http.Request, user *User, subPath string) { // http://www.webdav.org/specs/rfc4918.html#HEADER_Lock-Token says that the @@ -810,44 +810,44 @@ func (this *DavService) HandleUnlock(w http.ResponseWriter, r *http.Request, use } } -//hanle all the request. -func (this *DavService) HandleDav(writer http.ResponseWriter, request *http.Request, user *User, subPath string) { +// hanle all the request. +func (this *DavService) HandleDav(writer http.ResponseWriter, request *http.Request, user *User, space *Space, subPath string) { method := request.Method if method == "OPTIONS" { //cors option - this.HandleOptions(writer, request, user, subPath) + this.HandleOptions(writer, request, user, space, subPath) } else if method == "GET" || method == "HEAD" || method == "POST" { //get the detail of file. download - this.HandleGetHeadPost(writer, request, user, subPath) + this.HandleGetHeadPost(writer, request, user, space, subPath) } else if method == "DELETE" { //delete file - this.HandleDelete(writer, request, user, subPath) + this.HandleDelete(writer, request, user, space, subPath) } else if method == "PUT" { //upload file - this.HandlePut(writer, request, user, subPath) + this.HandlePut(writer, request, user, space, subPath) } else if method == "MKCOL" { //crate directory - this.HandleMkcol(writer, request, user, subPath) + this.HandleMkcol(writer, request, user, space, subPath) } else if method == "COPY" { //copy file/directory - this.HandleCopy(writer, request, user, subPath) + this.HandleCopy(writer, request, user, space, subPath) } else if method == "MOVE" { //move/rename a file or directory - this.HandleMove(writer, request, user, subPath) + this.HandleMove(writer, request, user, space, subPath) } else if method == "LOCK" { @@ -862,7 +862,7 @@ func (this *DavService) HandleDav(writer http.ResponseWriter, request *http.Requ } else if method == "PROPFIND" { //list a directory - this.HandlePropfind(writer, request, user, subPath) + this.HandlePropfind(writer, request, user, space, subPath) } else if method == "PROPPATCH" { diff --git a/code/rest/image_cache_dao.go b/code/rest/image_cache_dao.go index fddd768..8d2ec47 100644 --- a/code/rest/image_cache_dao.go +++ b/code/rest/image_cache_dao.go @@ -17,7 +17,7 @@ type ImageCacheDao struct { BaseDao } -//find by uuid. if not found return nil. +// find by uuid. if not found return nil. func (this *ImageCacheDao) FindByUuid(uuid string) *ImageCache { var entity = &ImageCache{} db := core.CONTEXT.GetDB().Where("uuid = ?", uuid).First(entity) @@ -31,7 +31,7 @@ func (this *ImageCacheDao) FindByUuid(uuid string) *ImageCache { return entity } -//find by uuid. if not found panic NotFound error +// find by uuid. if not found panic NotFound error func (this *ImageCacheDao) CheckByUuid(uuid string) *ImageCache { entity := this.FindByUuid(uuid) if entity == nil { @@ -137,7 +137,7 @@ func (this *ImageCacheDao) Save(imageCache *ImageCache) *ImageCache { func (this *ImageCacheDao) deleteFileAndDir(imageCache *ImageCache) { - filePath := GetUserCacheRootDir(imageCache.Username) + imageCache.Path + filePath := GetSpaceCacheRootDir(imageCache.Username) + imageCache.Path dirPath := filepath.Dir(filePath) @@ -152,7 +152,7 @@ func (this *ImageCacheDao) deleteFileAndDir(imageCache *ImageCache) { } -//delete a file from db and disk. +// delete a file from db and disk. func (this *ImageCacheDao) Delete(imageCache *ImageCache) { db := core.CONTEXT.GetDB().Delete(&imageCache) @@ -162,7 +162,7 @@ func (this *ImageCacheDao) Delete(imageCache *ImageCache) { } -//delete all the cache of a matter. +// delete all the cache of a matter. func (this *ImageCacheDao) DeleteByMatterUuid(matterUuid string) { var wp = &builder.WherePair{} @@ -208,7 +208,7 @@ func (this *ImageCacheDao) SizeBetweenTime(startTime time.Time, endTime time.Tim return size } -//System cleanup. +// System cleanup. func (this *ImageCacheDao) Cleanup() { this.logger.Info("[ImageCacheDao]clean up. Delete all ImageCache ") db := core.CONTEXT.GetDB().Where("uuid is not null").Delete(ImageCache{}) diff --git a/code/rest/image_cache_model.go b/code/rest/image_cache_model.go index 7cd8455..1c43884 100644 --- a/code/rest/image_cache_model.go +++ b/code/rest/image_cache_model.go @@ -24,5 +24,5 @@ type ImageCache struct { // get the absolute path. path in db means relative path. func (this *ImageCache) AbsolutePath() string { - return GetUserCacheRootDir(this.Username) + this.Path + return GetSpaceCacheRootDir(this.Username) + this.Path } diff --git a/code/rest/image_cache_service.go b/code/rest/image_cache_service.go index e232b33..25349fe 100644 --- a/code/rest/image_cache_service.go +++ b/code/rest/image_cache_service.go @@ -14,7 +14,7 @@ import ( "strings" ) -//@Service +// @Service type ImageCacheService struct { BaseBean imageCacheDao *ImageCacheDao @@ -92,7 +92,7 @@ func (this *ImageCacheService) ResizeParams(request *http.Request) (needProcess } -//resize image. +// resize image. func (this *ImageCacheService) ResizeImage(request *http.Request, filePath string) *image.NRGBA { diskFile, err := os.Open(filePath) @@ -148,7 +148,7 @@ func (this *ImageCacheService) ResizeImage(request *http.Request, filePath strin } } -//cache an image +// cache an image func (this *ImageCacheService) cacheImage(writer http.ResponseWriter, request *http.Request, matter *Matter) *ImageCache { //only these image can do. @@ -177,7 +177,7 @@ func (this *ImageCacheService) cacheImage(writer http.ResponseWriter, request *h cacheImageName := util.GetSimpleFileName(matter.Name) + "_" + mode + extension cacheImageRelativePath := util.GetSimpleFileName(matter.Path) + "_" + mode + extension - cacheImageAbsolutePath := GetUserCacheRootDir(user.Username) + util.GetSimpleFileName(matter.Path) + "_" + mode + extension + cacheImageAbsolutePath := GetSpaceCacheRootDir(user.Username) + util.GetSimpleFileName(matter.Path) + "_" + mode + extension //create directory dir := filepath.Dir(cacheImageAbsolutePath) diff --git a/code/rest/install_controller.go b/code/rest/install_controller.go index 6b85b7e..1763d43 100644 --- a/code/rest/install_controller.go +++ b/code/rest/install_controller.go @@ -370,9 +370,20 @@ func (this *InstallController) CreateAdmin(writer http.ResponseWriter, request * panic(result.BadRequestI18n(request, i18n.UsernameExist, adminUsername)) } - user := &User{} + space := &Space{} timeUUID, _ := uuid.NewV4() - user.Uuid = string(timeUUID.String()) + space.Uuid = timeUUID.String() + space.CreateTime = time.Now() + space.UpdateTime = time.Now() + space.UserUuid = "" + space.SizeLimit = -1 + space.Type = SPACE_TYPE_PRIVATE + db3 := db.Create(space) + this.PanicError(db3.Error) + + user := &User{} + timeUUID, _ = uuid.NewV4() + user.Uuid = timeUUID.String() user.CreateTime = time.Now() user.UpdateTime = time.Now() user.LastTime = time.Now() @@ -380,11 +391,15 @@ func (this *InstallController) CreateAdmin(writer http.ResponseWriter, request * user.Role = USER_ROLE_ADMINISTRATOR user.Username = adminUsername user.Password = util.GetBcrypt(adminPassword) - user.SizeLimit = -1 + user.SpaceUuid = space.Uuid user.Status = USER_STATUS_OK - db3 := db.Create(user) - this.PanicError(db3.Error) + db4 := db.Create(user) + this.PanicError(db4.Error) + + space.UserUuid = user.Uuid + db5 := db.Save(space) + this.PanicError(db5.Error) return this.Success("OK") diff --git a/code/rest/matter_controller.go b/code/rest/matter_controller.go index 09fad2b..97bc172 100644 --- a/code/rest/matter_controller.go +++ b/code/rest/matter_controller.go @@ -18,6 +18,7 @@ type MatterController struct { downloadTokenDao *DownloadTokenDao imageCacheDao *ImageCacheDao shareDao *ShareDao + spaceDao *SpaceDao shareService *ShareService bridgeDao *BridgeDao imageCacheService *ImageCacheService @@ -51,6 +52,11 @@ func (this *MatterController) Init() { this.shareDao = b } + b = core.CONTEXT.GetBean(this.spaceDao) + if b, ok := b.(*SpaceDao); ok { + this.spaceDao = b + } + b = core.CONTEXT.GetBean(this.shareService) if b, ok := b.(*ShareService); ok { this.shareService = b @@ -224,8 +230,9 @@ func (this *MatterController) CreateDirectory(writer http.ResponseWriter, reques name := request.FormValue("name") user := this.checkUser(request) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) - var dirMatter = this.matterDao.CheckWithRootByUuid(puuid, user) + var dirMatter = this.matterDao.CheckWithRootByUuid(puuid, user, space) matter := this.matterService.AtomicCreateDirectory(request, dirMatter, name, user) return this.Success(matter) @@ -243,6 +250,7 @@ func (this *MatterController) Upload(writer http.ResponseWriter, request *http.R }() user := this.checkUser(request) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) privacy := privacyStr == TRUE @@ -260,10 +268,10 @@ func (this *MatterController) Upload(writer http.ResponseWriter, request *http.R fileName = fileName[pos+1:] } - dirMatter := this.matterDao.CheckWithRootByUuid(puuid, user) + dirMatter := this.matterDao.CheckWithRootByUuid(puuid, user, space) //support upload simultaneously - matter := this.matterService.Upload(request, file, user, dirMatter, fileName, privacy) + matter := this.matterService.Upload(request, file, user, space, dirMatter, fileName, privacy) return this.Success(matter) } @@ -276,8 +284,8 @@ func (this *MatterController) Crawl(writer http.ResponseWriter, request *http.Re filename := request.FormValue("filename") user := this.checkUser(request) - - dirMatter := this.matterService.CreateDirectories(request, user, destPath) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) + dirMatter := this.matterService.CreateDirectories(request, user, space, destPath) if url == "" || (!strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://")) { panic(" url must start with http:// or https://") @@ -287,7 +295,7 @@ func (this *MatterController) Crawl(writer http.ResponseWriter, request *http.Re panic("filename cannot be null") } - matter := this.matterService.AtomicCrawl(request, url, filename, user, dirMatter, true) + matter := this.matterService.AtomicCrawl(request, url, filename, user, space, dirMatter, true) return this.Success(matter) } @@ -303,11 +311,12 @@ func (this *MatterController) SoftDelete(writer http.ResponseWriter, request *ht matter := this.matterDao.CheckByUuid(uuid) user := this.checkUser(request) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) if matter.UserUuid != user.Uuid { panic(result.UNAUTHORIZED) } - this.matterService.AtomicSoftDelete(request, matter, user) + this.matterService.AtomicSoftDelete(request, matter, user, space) return this.Success("OK") } @@ -319,6 +328,7 @@ func (this *MatterController) SoftDeleteBatch(writer http.ResponseWriter, reques panic(result.BadRequest("uuids cannot be null")) } user := this.checkUser(request) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) uuidArray := strings.Split(uuids, ",") @@ -340,7 +350,7 @@ func (this *MatterController) SoftDeleteBatch(writer http.ResponseWriter, reques } for _, matter := range matters { - this.matterService.AtomicSoftDelete(request, matter, user) + this.matterService.AtomicSoftDelete(request, matter, user, space) } return this.Success("OK") @@ -408,11 +418,12 @@ func (this *MatterController) Delete(writer http.ResponseWriter, request *http.R matter := this.matterDao.CheckByUuid(uuid) user := this.checkUser(request) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) if matter.UserUuid != user.Uuid { panic(result.UNAUTHORIZED) } - this.matterService.AtomicDelete(request, matter, user) + this.matterService.AtomicDelete(request, matter, user, space) return this.Success("OK") } @@ -426,6 +437,7 @@ func (this *MatterController) DeleteBatch(writer http.ResponseWriter, request *h uuidArray := strings.Split(uuids, ",") user := this.checkUser(request) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) matters := make([]*Matter, 0) for _, uuid := range uuidArray { @@ -445,7 +457,7 @@ func (this *MatterController) DeleteBatch(writer http.ResponseWriter, request *h for _, matter := range matters { - this.matterService.AtomicDelete(request, matter, user) + this.matterService.AtomicDelete(request, matter, user, space) } return this.Success("OK") @@ -465,14 +477,14 @@ func (this *MatterController) Rename(writer http.ResponseWriter, request *http.R name := request.FormValue("name") user := this.checkUser(request) - + space := this.spaceDao.CheckByUuid(user.SpaceUuid) matter := this.matterDao.CheckByUuid(uuid) if matter.UserUuid != user.Uuid { panic(result.UNAUTHORIZED) } - this.matterService.AtomicRename(request, matter, name, false, user) + this.matterService.AtomicRename(request, matter, name, false, user, space) return this.Success(matter) } @@ -519,8 +531,8 @@ func (this *MatterController) Move(writer http.ResponseWriter, request *http.Req } user := this.checkUser(request) - - var destMatter = this.matterDao.CheckWithRootByUuid(destUuid, user) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) + var destMatter = this.matterDao.CheckWithRootByUuid(destUuid, user, space) if !destMatter.Dir { panic(result.BadRequest("destination is not a directory")) } @@ -559,7 +571,7 @@ func (this *MatterController) Move(writer http.ResponseWriter, request *http.Req srcMatters = append(srcMatters, srcMatter) } - this.matterService.AtomicMoveBatch(request, srcMatters, destMatter, user) + this.matterService.AtomicMoveBatch(request, srcMatters, destMatter, user, space) return this.Success(nil) } @@ -581,8 +593,9 @@ func (this *MatterController) Mirror(writer http.ResponseWriter, request *http.R } user := this.userDao.checkUser(request) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) - this.matterService.AtomicMirror(request, srcPath, destPath, overwrite, user) + this.matterService.AtomicMirror(request, srcPath, destPath, overwrite, user, space) return this.Success(nil) diff --git a/code/rest/matter_dao.go b/code/rest/matter_dao.go index b297a45..221063a 100644 --- a/code/rest/matter_dao.go +++ b/code/rest/matter_dao.go @@ -56,7 +56,7 @@ func (this *MatterDao) CheckByUuid(uuid string) *Matter { } // find by uuid. if uuid=root, then return the Root Matter -func (this *MatterDao) CheckWithRootByUuid(uuid string, user *User) *Matter { +func (this *MatterDao) CheckWithRootByUuid(uuid string, user *User, space *Space) *Matter { if uuid == "" { panic(result.BadRequest("uuid cannot be null.")) @@ -67,7 +67,7 @@ func (this *MatterDao) CheckWithRootByUuid(uuid string, user *User) *Matter { if user == nil { panic(result.BadRequest("user cannot be null.")) } - matter = NewRootMatter(user) + matter = NewRootMatter(user, space) } else { matter = this.CheckByUuid(uuid) } @@ -76,7 +76,7 @@ func (this *MatterDao) CheckWithRootByUuid(uuid string, user *User) *Matter { } // find by path. if path=/, then return the Root Matter -func (this *MatterDao) CheckWithRootByPath(path string, user *User) *Matter { +func (this *MatterDao) CheckWithRootByPath(path string, user *User, space *Space) *Matter { var matter *Matter @@ -85,7 +85,7 @@ func (this *MatterDao) CheckWithRootByPath(path string, user *User) *Matter { } if path == "" || path == "/" { - matter = NewRootMatter(user) + matter = NewRootMatter(user, space) } else { matter = this.checkByUserUuidAndPath(user.Uuid, path) } @@ -94,7 +94,7 @@ func (this *MatterDao) CheckWithRootByPath(path string, user *User) *Matter { } // find by path. if path=/, then return the Root Matter -func (this *MatterDao) FindWithRootByPath(path string, user *User) *Matter { +func (this *MatterDao) FindWithRootByPath(path string, user *User, space *Space) *Matter { var matter *Matter @@ -103,7 +103,7 @@ func (this *MatterDao) FindWithRootByPath(path string, user *User) *Matter { } if path == "" || path == "/" { - matter = NewRootMatter(user) + matter = NewRootMatter(user, space) } else { matter = this.findByUserUuidAndPath(user.Uuid, path) } @@ -175,6 +175,36 @@ func (this *MatterDao) CountByUserUuidAndPuuidAndDirAndName(userUuid string, puu return int(count) } +func (this *MatterDao) CountBySpaceUuidAndPuuidAndDirAndName(spaceUuid string, puuid string, dir bool, name string) int { + + var matter Matter + var count int64 + + var wp = &builder.WherePair{} + + if puuid != "" { + wp = wp.And(&builder.WherePair{Query: "puuid = ?", Args: []interface{}{puuid}}) + } + + if spaceUuid != "" { + wp = wp.And(&builder.WherePair{Query: "space_uuid = ?", Args: []interface{}{spaceUuid}}) + } + + if name != "" { + wp = wp.And(&builder.WherePair{Query: "name = ?", Args: []interface{}{name}}) + } + + wp = wp.And(&builder.WherePair{Query: "dir = ?", Args: []interface{}{dir}}) + + db := core.CONTEXT.GetDB(). + Model(&matter). + Where(wp.Query, wp.Args...). + Count(&count) + this.PanicError(db.Error) + + return int(count) +} + func (this *MatterDao) FindByUserUuidAndPuuidAndDirAndName(userUuid string, puuid string, dir string, name string) *Matter { var matter = &Matter{} diff --git a/code/rest/matter_model.go b/code/rest/matter_model.go index 9318aaf..f67cbf9 100644 --- a/code/rest/matter_model.go +++ b/code/rest/matter_model.go @@ -36,7 +36,8 @@ type Matter struct { CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"` Puuid string `json:"puuid" gorm:"type:char(36);index:idx_matter_puuid"` //index should unique globally. UserUuid string `json:"userUuid" gorm:"type:char(36);index:idx_matter_uu"` - Username string `json:"username" gorm:"type:varchar(45) not null"` + //TODO: check field usage. + SpaceName string `json:"space_name" gorm:"type:varchar(45) not null"` Dir bool `json:"dir" gorm:"type:tinyint(1) not null;default:0"` Name string `json:"name" gorm:"type:varchar(255) not null"` Md5 string `json:"md5" gorm:"type:varchar(45)"` @@ -55,7 +56,7 @@ type Matter struct { // get matter's absolute path. the Path property is relative path in db. func (this *Matter) AbsolutePath() string { - return GetUserMatterRootDir(this.Username) + this.Path + return GetSpaceMatterRootDir(this.SpaceName) + this.Path } func (this *Matter) MimeType() string { @@ -63,11 +64,11 @@ func (this *Matter) MimeType() string { } // Create a root matter. It's convenient for copy and move -func NewRootMatter(user *User) *Matter { +func NewRootMatter(user *User, space *Space) *Matter { matter := &Matter{} matter.Uuid = MATTER_ROOT matter.UserUuid = user.Uuid - matter.Username = user.Username + matter.SpaceName = space.Name matter.Dir = true matter.Path = "" matter.CreateTime = user.CreateTime @@ -86,25 +87,25 @@ func GetUserSpaceRootDir(username string) (rootDirPath string) { } // get user's root absolute path -func GetUserMatterRootDir(username string) (rootDirPath string) { +func GetSpaceMatterRootDir(spaceName string) (rootDirPath string) { - rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), username, MATTER_ROOT) + rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), spaceName, MATTER_ROOT) return rootDirPath } // get user's cache absolute path -func GetUserCacheRootDir(username string) (rootDirPath string) { +func GetSpaceCacheRootDir(spaceName string) (rootDirPath string) { - rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), username, MATTER_CACHE) + rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), spaceName, MATTER_CACHE) return rootDirPath } // get user's zip absolute path -func GetUserZipRootDir(username string) (rootDirPath string) { +func GetSpaceZipRootDir(spaceName string) (rootDirPath string) { - rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), username, MATTER_ZIP) + rootDirPath = fmt.Sprintf("%s/%s/%s", core.CONFIG.MatterPath(), spaceName, MATTER_ZIP) return rootDirPath } diff --git a/code/rest/matter_service.go b/code/rest/matter_service.go index 8908dfd..591e4d6 100644 --- a/code/rest/matter_service.go +++ b/code/rest/matter_service.go @@ -27,6 +27,7 @@ import ( type MatterService struct { BaseBean matterDao *MatterDao + spaceDao *SpaceDao userDao *UserDao userService *UserService imageCacheDao *ImageCacheDao @@ -47,6 +48,11 @@ func (this *MatterService) Init() { this.userDao = b } + b = core.CONTEXT.GetBean(this.spaceDao) + if b, ok := b.(*SpaceDao); ok { + this.spaceDao = b + } + b = core.CONTEXT.GetBean(this.userService) if b, ok := b.(*UserService); ok { this.userService = b @@ -69,7 +75,7 @@ func (this *MatterService) Init() { } -//Download. Support chunk download. +// Download. Support chunk download. func (this *MatterService) DownloadFile( writer http.ResponseWriter, request *http.Request, @@ -80,7 +86,7 @@ func (this *MatterService) DownloadFile( download.DownloadFile(writer, request, filePath, filename, withContentDisposition) } -//Download specified matters. matters must have the same puuid. +// Download specified matters. matters must have the same puuid. func (this *MatterService) DownloadZip( writer http.ResponseWriter, request *http.Request, @@ -127,7 +133,7 @@ func (this *MatterService) DownloadZip( } //prepare the temp zip dir - destZipDirPath := fmt.Sprintf("%s/%d", GetUserZipRootDir(matters[0].Username), time.Now().UnixNano()/1e6) + destZipDirPath := fmt.Sprintf("%s/%d", GetSpaceZipRootDir(matters[0].SpaceName), time.Now().UnixNano()/1e6) util.MakeDirAll(destZipDirPath) destZipName := fmt.Sprintf("%s.zip", matters[0].Name) @@ -150,7 +156,7 @@ func (this *MatterService) DownloadZip( } -//zip matters. +// zip matters. func (this *MatterService) zipMatters(request *http.Request, matters []*Matter, destPath string) { if util.PathExists(destPath) { @@ -243,8 +249,8 @@ func (this *MatterService) zipMatters(request *http.Request, matters []*Matter, } } -//delete files. -func (this *MatterService) Delete(request *http.Request, matter *Matter, user *User) { +// delete files. +func (this *MatterService) Delete(request *http.Request, matter *Matter, user *User, space *Space) { if matter == nil { panic(result.BadRequest("matter cannot be nil")) @@ -253,10 +259,10 @@ func (this *MatterService) Delete(request *http.Request, matter *Matter, user *U this.matterDao.Delete(matter) //re compute the size of Route. - this.ComputeRouteSize(matter.Puuid, user) + this.ComputeRouteSize(matter.Puuid, user, space) } -//soft delete files. +// soft delete files. func (this *MatterService) SoftDelete(request *http.Request, matter *Matter, user *User) { if matter == nil { @@ -271,7 +277,7 @@ func (this *MatterService) SoftDelete(request *http.Request, matter *Matter, use //no need to recompute size. } -//recovery delete files. +// recovery delete files. func (this *MatterService) Recovery(request *http.Request, matter *Matter, user *User) { if matter == nil { @@ -286,8 +292,8 @@ func (this *MatterService) Recovery(request *http.Request, matter *Matter, user //no need to recompute size. } -//atomic delete files -func (this *MatterService) AtomicDelete(request *http.Request, matter *Matter, user *User) { +// atomic delete files +func (this *MatterService) AtomicDelete(request *http.Request, matter *Matter, user *User, space *Space) { if matter == nil { panic(result.BadRequest("matter cannot be nil")) @@ -297,11 +303,11 @@ func (this *MatterService) AtomicDelete(request *http.Request, matter *Matter, u this.userService.MatterLock(matter.UserUuid) defer this.userService.MatterUnlock(matter.UserUuid) - this.Delete(request, matter, user) + this.Delete(request, matter, user, space) } -//atomic soft delete files -func (this *MatterService) AtomicSoftDelete(request *http.Request, matter *Matter, user *User) { +// atomic soft delete files +func (this *MatterService) AtomicSoftDelete(request *http.Request, matter *Matter, user *User, space *Space) { if matter == nil { panic(result.BadRequest("matter cannot be nil")) @@ -318,14 +324,14 @@ func (this *MatterService) AtomicSoftDelete(request *http.Request, matter *Matte //if disabled the recycle feature. then we hard delete. preference := this.preferenceService.Fetch() if preference.DeletedKeepDays == 0 { - this.Delete(request, matter, user) + this.Delete(request, matter, user, space) } else { this.SoftDelete(request, matter, user) } } -//atomic recovery delete files +// atomic recovery delete files func (this *MatterService) AtomicRecovery(request *http.Request, matter *Matter, user *User) { if matter == nil { @@ -343,8 +349,8 @@ func (this *MatterService) AtomicRecovery(request *http.Request, matter *Matter, this.Recovery(request, matter, user) } -//upload files. -func (this *MatterService) Upload(request *http.Request, file io.Reader, user *User, dirMatter *Matter, filename string, privacy bool) *Matter { +// upload files. +func (this *MatterService) Upload(request *http.Request, file io.Reader, user *User, space *Space, dirMatter *Matter, filename string, privacy bool) *Matter { if user == nil { panic(result.BadRequest("user cannot be nil.")) @@ -364,7 +370,7 @@ func (this *MatterService) Upload(request *http.Request, file io.Reader, user *U dirAbsolutePath := dirMatter.AbsolutePath() - count := this.matterDao.CountByUserUuidAndPuuidAndDirAndName(user.Uuid, dirMatter.Uuid, false, filename) + count := this.matterDao.CountBySpaceUuidAndPuuidAndDirAndName(space.Uuid, dirMatter.Uuid, false, filename) if count > 0 { panic(result.BadRequestI18n(request, i18n.MatterExist, filename)) } @@ -395,35 +401,35 @@ func (this *MatterService) Upload(request *http.Request, file io.Reader, user *U this.logger.Info("upload %s %v ", filename, util.HumanFileSize(fileSize)) //check the size limit. - if user.SizeLimit >= 0 { - if fileSize > user.SizeLimit { + if space.SizeLimit >= 0 { + if fileSize > space.SizeLimit { //delete the file on disk. err = os.Remove(fileAbsolutePath) this.PanicError(err) - panic(result.BadRequestI18n(request, i18n.MatterSizeExceedLimit, util.HumanFileSize(fileSize), util.HumanFileSize(user.SizeLimit))) + panic(result.BadRequestI18n(request, i18n.MatterSizeExceedLimit, util.HumanFileSize(fileSize), util.HumanFileSize(space.SizeLimit))) } } //check total size. - if user.TotalSizeLimit >= 0 { - if user.TotalSize+fileSize > user.TotalSizeLimit { + if space.TotalSizeLimit >= 0 { + if space.TotalSize+fileSize > space.TotalSizeLimit { //delete the file on disk. err = os.Remove(fileAbsolutePath) this.PanicError(err) - panic(result.BadRequestI18n(request, i18n.MatterSizeExceedTotalLimit, util.HumanFileSize(user.TotalSize), util.HumanFileSize(user.TotalSizeLimit))) + panic(result.BadRequestI18n(request, i18n.MatterSizeExceedTotalLimit, util.HumanFileSize(space.TotalSize), util.HumanFileSize(space.TotalSizeLimit))) } } - matter := this.createNonDirMatter(dirMatter, filename, fileSize, privacy, user) + matter := this.createNonDirMatter(dirMatter, filename, fileSize, privacy, user, space) return matter } // create a non dir matter. -func (this *MatterService) createNonDirMatter(dirMatter *Matter, filename string, fileSize int64, privacy bool, user *User) *Matter { +func (this *MatterService) createNonDirMatter(dirMatter *Matter, filename string, fileSize int64, privacy bool, user *User, space *Space) *Matter { dirRelativePath := dirMatter.Path fileRelativePath := dirRelativePath + "/" + filename @@ -431,7 +437,7 @@ func (this *MatterService) createNonDirMatter(dirMatter *Matter, filename string matter := &Matter{ Puuid: dirMatter.Uuid, UserUuid: user.Uuid, - Username: user.Username, + SpaceName: space.Name, Dir: false, Name: filename, Md5: "", @@ -445,14 +451,14 @@ func (this *MatterService) createNonDirMatter(dirMatter *Matter, filename string //compute the size of directory go core.RunWithRecovery(func() { - this.ComputeRouteSize(dirMatter.Uuid, user) + this.ComputeRouteSize(dirMatter.Uuid, user, space) }) return matter } // create a non dir matter. -func (this *MatterService) updateNonDirMatter(matter *Matter, fileSize int64, user *User) *Matter { +func (this *MatterService) updateNonDirMatter(matter *Matter, fileSize int64, user *User, space *Space) *Matter { matter.Size = fileSize @@ -460,25 +466,25 @@ func (this *MatterService) updateNonDirMatter(matter *Matter, fileSize int64, us //compute the size of directory go core.RunWithRecovery(func() { - this.ComputeRouteSize(matter.Puuid, user) + this.ComputeRouteSize(matter.Puuid, user, space) }) return matter } // compute route size. It will compute upward until root directory -func (this *MatterService) ComputeRouteSize(matterUuid string, user *User) { +func (this *MatterService) ComputeRouteSize(matterUuid string, user *User, space *Space) { //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) + db := core.CONTEXT.GetDB().Model(&Space{}).Where("uuid = ?", space.Uuid).Update("total_size", size) this.PanicError(db.Error) //update user total size info in cache. - user.TotalSize = size + space.TotalSize = size return } @@ -499,27 +505,27 @@ func (this *MatterService) ComputeRouteSize(matterUuid string, user *User) { } //update parent recursively. - this.ComputeRouteSize(matter.Puuid, user) + this.ComputeRouteSize(matter.Puuid, user, space) } // compute all dir's size. -func (this *MatterService) ComputeAllDirSize(user *User) { +func (this *MatterService) ComputeAllDirSize(user *User, space *Space) { this.logger.Info("Compute all dir's size for user %s %s", user.Uuid, user.Username) - rootMatter := NewRootMatter(user) - this.ComputeDirSize(rootMatter, user) + rootMatter := NewRootMatter(user, space) + this.ComputeDirSize(rootMatter, user, space) } // compute a dir's size. -func (this *MatterService) ComputeDirSize(dirMatter *Matter, user *User) { +func (this *MatterService) ComputeDirSize(dirMatter *Matter, user *User, space *Space) { this.logger.Info("Compute dir's size %s %s", dirMatter.Uuid, dirMatter.Name) //update sub dir first childrenDirMatters := this.matterDao.FindByUserUuidAndPuuidAndDirTrue(user.Uuid, dirMatter.Uuid) for _, childrenDirMatter := range childrenDirMatters { - this.ComputeDirSize(childrenDirMatter, user) + this.ComputeDirSize(childrenDirMatter, user, space) } //if to root directory, then update to user's info. @@ -531,7 +537,7 @@ func (this *MatterService) ComputeDirSize(dirMatter *Matter, user *User) { this.PanicError(db.Error) //update user total size info in cache. - user.TotalSize = size + space.TotalSize = size } else { //compute self. @@ -546,7 +552,7 @@ func (this *MatterService) ComputeDirSize(dirMatter *Matter, user *User) { } -//inner create directory. +// inner create directory. func (this *MatterService) createDirectory(request *http.Request, dirMatter *Matter, name string, user *User) *Matter { if dirMatter == nil { @@ -593,7 +599,7 @@ func (this *MatterService) createDirectory(request *http.Request, dirMatter *Mat panic(result.BadRequestI18n(request, i18n.MatterDepthExceedLimit, len(parts), MATTER_NAME_MAX_DEPTH)) } - absolutePath := GetUserMatterRootDir(user.Username) + dirMatter.Path + "/" + name + absolutePath := GetSpaceMatterRootDir(user.Username) + dirMatter.Path + "/" + name relativePath := dirMatter.Path + "/" + name @@ -605,7 +611,7 @@ func (this *MatterService) createDirectory(request *http.Request, dirMatter *Mat matter = &Matter{ Puuid: dirMatter.Uuid, UserUuid: user.Uuid, - Username: user.Username, + SpaceName: user.Username, Dir: true, Name: name, Path: relativePath, @@ -631,15 +637,15 @@ func (this *MatterService) AtomicCreateDirectory(request *http.Request, dirMatte return matter } -//copy or move may overwrite. -func (this *MatterService) handleOverwrite(request *http.Request, user *User, destinationPath string, overwrite bool) { +// copy or move may overwrite. +func (this *MatterService) handleOverwrite(request *http.Request, user *User, space *Space, destinationPath string, overwrite bool) { destMatter := this.matterDao.findByUserUuidAndPath(user.Uuid, destinationPath) if destMatter != nil { //if exist if overwrite { //delete. - this.Delete(request, destMatter, user) + this.Delete(request, destMatter, user, space) } else { //throw precondition failed. (RFC4918:10.6) panic(result.CustomWebResult(result.PRECONDITION_FAILED, fmt.Sprintf("%s exists", destMatter.Path))) @@ -648,8 +654,8 @@ func (this *MatterService) handleOverwrite(request *http.Request, user *User, de } -//move srcMatter to destMatter. invoker must handled the overwrite and lock. -func (this *MatterService) move(request *http.Request, srcMatter *Matter, destDirMatter *Matter, user *User) { +// move srcMatter to destMatter. invoker must handled the overwrite and lock. +func (this *MatterService) move(request *http.Request, srcMatter *Matter, destDirMatter *Matter, user *User, space *Space) { if srcMatter == nil { panic(result.BadRequest("srcMatter cannot be nil.")) @@ -704,13 +710,13 @@ func (this *MatterService) move(request *http.Request, srcMatter *Matter, destDi } //reCompute the size of src and dest. - this.ComputeRouteSize(srcPuuid, user) - this.ComputeRouteSize(destDirUuid, user) + this.ComputeRouteSize(srcPuuid, user, space) + this.ComputeRouteSize(destDirUuid, user, space) } -//move srcMatter to destMatter(must be dir) -func (this *MatterService) AtomicMove(request *http.Request, srcMatter *Matter, destDirMatter *Matter, overwrite bool, user *User) { +// move srcMatter to destMatter(must be dir) +func (this *MatterService) AtomicMove(request *http.Request, srcMatter *Matter, destDirMatter *Matter, overwrite bool, user *User, space *Space) { if srcMatter == nil { panic(result.BadRequest("srcMatter cannot be nil.")) @@ -738,14 +744,14 @@ func (this *MatterService) AtomicMove(request *http.Request, srcMatter *Matter, //handle the overwrite destinationPath := destDirMatter.Path + "/" + srcMatter.Name - this.handleOverwrite(request, user, destinationPath, overwrite) + this.handleOverwrite(request, user, space, destinationPath, overwrite) //do the move operation. - this.move(request, srcMatter, destDirMatter, user) + this.move(request, srcMatter, destDirMatter, user, space) } -//move srcMatters to destMatter(must be dir) -func (this *MatterService) AtomicMoveBatch(request *http.Request, srcMatters []*Matter, destDirMatter *Matter, user *User) { +// move srcMatters to destMatter(must be dir) +func (this *MatterService) AtomicMoveBatch(request *http.Request, srcMatters []*Matter, destDirMatter *Matter, user *User, space *Space) { if destDirMatter == nil { panic(result.BadRequest("destDirMatter cannot be nil.")) @@ -776,12 +782,12 @@ func (this *MatterService) AtomicMoveBatch(request *http.Request, srcMatters []* } for _, srcMatter := range srcMatters { - this.move(request, srcMatter, destDirMatter, user) + this.move(request, srcMatter, destDirMatter, user, space) } } -//copy srcMatter to destMatter. invoker must handled the overwrite and lock. +// copy srcMatter to destMatter. invoker must handled the overwrite and lock. func (this *MatterService) copy(request *http.Request, srcMatter *Matter, destDirMatter *Matter, name string) { this.logger.Info("copy srcPath = %s destPath = %s/%s", srcMatter.Path, destDirMatter.Path, name) @@ -791,7 +797,7 @@ func (this *MatterService) copy(request *http.Request, srcMatter *Matter, destDi newMatter := &Matter{ Puuid: destDirMatter.Uuid, UserUuid: srcMatter.UserUuid, - Username: srcMatter.Username, + SpaceName: srcMatter.SpaceName, Dir: srcMatter.Dir, Name: name, Md5: "", @@ -824,7 +830,7 @@ func (this *MatterService) copy(request *http.Request, srcMatter *Matter, destDi newMatter := &Matter{ Puuid: destDirMatter.Uuid, UserUuid: srcMatter.UserUuid, - Username: srcMatter.Username, + SpaceName: srcMatter.SpaceName, Dir: srcMatter.Dir, Name: name, Md5: "", @@ -839,8 +845,8 @@ 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, user *User) { +// copy srcMatter to destMatter. +func (this *MatterService) AtomicCopy(request *http.Request, srcMatter *Matter, destDirMatter *Matter, name string, overwrite bool, user *User, space *Space) { if srcMatter == nil { panic(result.BadRequest("srcMatter cannot be nil.")) @@ -854,13 +860,13 @@ func (this *MatterService) AtomicCopy(request *http.Request, srcMatter *Matter, } destinationPath := destDirMatter.Path + "/" + name - this.handleOverwrite(request, user, destinationPath, overwrite) + this.handleOverwrite(request, user, space, destinationPath, overwrite) this.copy(request, srcMatter, destDirMatter, name) } -//rename matter to name -func (this *MatterService) AtomicRename(request *http.Request, matter *Matter, name string, overwrite bool, user *User) { +// rename matter to name +func (this *MatterService) AtomicRename(request *http.Request, matter *Matter, name string, overwrite bool, user *User, space *Space) { this.logger.Info("Try to rename srcPath = %s to name = %s", matter.Path, name) @@ -886,7 +892,7 @@ func (this *MatterService) AtomicRename(request *http.Request, matter *Matter, n if oldMatter != nil { if overwrite { //delete this one. - this.Delete(request, oldMatter, user) + this.Delete(request, oldMatter, user, space) } else { panic(result.CustomWebResult(result.PRECONDITION_FAILED, fmt.Sprintf("%s already exists", name))) } @@ -941,8 +947,8 @@ func (this *MatterService) AtomicRename(request *http.Request, matter *Matter, n return } -//将本地文件映射到蓝眼云盘中去。 -func (this *MatterService) AtomicMirror(request *http.Request, srcPath string, destPath string, overwrite bool, user *User) { +// 将本地文件映射到蓝眼云盘中去。 +func (this *MatterService) AtomicMirror(request *http.Request, srcPath string, destPath string, overwrite bool, user *User, space *Space) { if user == nil { panic(result.BadRequest("user cannot be nil")) @@ -957,17 +963,17 @@ func (this *MatterService) AtomicMirror(request *http.Request, srcPath string, d panic(result.BadRequest("dest cannot be null")) } - destDirMatter := this.CreateDirectories(request, user, destPath) + destDirMatter := this.CreateDirectories(request, user, space, destPath) if destDirMatter.Deleted { panic(result.BadRequest("dest matter has been deleted. Cannot mirror.")) } - this.mirror(request, srcPath, destDirMatter, overwrite, user) + this.mirror(request, srcPath, destDirMatter, overwrite, user, space) } -//将本地文件/文件夹映射到蓝眼云盘中去。 -func (this *MatterService) mirror(request *http.Request, srcPath string, destDirMatter *Matter, overwrite bool, user *User) { +// 将本地文件/文件夹映射到蓝眼云盘中去。 +func (this *MatterService) mirror(request *http.Request, srcPath string, destDirMatter *Matter, overwrite bool, user *User, space *Space) { if user == nil { panic(result.BadRequest("user cannot be nil")) @@ -1003,7 +1009,7 @@ func (this *MatterService) mirror(request *http.Request, srcPath string, destDir for _, fileInfo := range fileInfos { path := fmt.Sprintf("%s/%s", srcPath, fileInfo.Name()) - this.mirror(request, path, srcDirMatter, overwrite, user) + this.mirror(request, path, srcDirMatter, overwrite, user, space) } } else { @@ -1013,7 +1019,7 @@ func (this *MatterService) mirror(request *http.Request, srcPath string, destDir if matter != nil { //如果是覆盖,那么删除之前的文件 if overwrite { - this.Delete(request, matter, user) + this.Delete(request, matter, user, space) } else { //直接完成。 return @@ -1028,19 +1034,19 @@ func (this *MatterService) mirror(request *http.Request, srcPath string, destDir this.PanicError(err) }() - this.Upload(request, file, user, destDirMatter, fileStat.Name(), true) + this.Upload(request, file, user, space, destDirMatter, fileStat.Name(), true) } } -//根据一个文件夹路径,依次创建,找到最后一个文件夹的matter,如果中途出错,返回err. 如果存在了那就直接返回即可。 -func (this *MatterService) CreateDirectories(request *http.Request, user *User, dirPath string) *Matter { +// 根据一个文件夹路径,依次创建,找到最后一个文件夹的matter,如果中途出错,返回err. 如果存在了那就直接返回即可。 +func (this *MatterService) CreateDirectories(request *http.Request, user *User, space *Space, dirPath string) *Matter { dirPath = path.Clean(dirPath) if dirPath == "/" { - return NewRootMatter(user) + return NewRootMatter(user, space) } //ignore the last slash. @@ -1065,7 +1071,7 @@ func (this *MatterService) CreateDirectories(request *http.Request, user *User, //ignore the first element. if k == 0 { - dirMatter = NewRootMatter(user) + dirMatter = NewRootMatter(user, space) continue } @@ -1075,7 +1081,7 @@ func (this *MatterService) CreateDirectories(request *http.Request, user *User, return dirMatter } -//wrap a matter. put its parent. +// wrap a matter. put its parent. func (this *MatterService) WrapParentDetail(request *http.Request, matter *Matter) *Matter { if matter == nil { @@ -1098,7 +1104,7 @@ func (this *MatterService) WrapParentDetail(request *http.Request, matter *Matte return matter } -//wrap a matter ,put its children +// wrap a matter ,put its children func (this *MatterService) WrapChildrenDetail(request *http.Request, matter *Matter) { if matter == nil { @@ -1117,14 +1123,14 @@ func (this *MatterService) WrapChildrenDetail(request *http.Request, matter *Mat } -//fetch a matter's detail with parent info. +// fetch a matter's detail with parent info. func (this *MatterService) Detail(request *http.Request, uuid string) *Matter { matter := this.matterDao.CheckByUuid(uuid) return this.WrapParentDetail(request, matter) } -//crawl a url to dirMatter -func (this *MatterService) AtomicCrawl(request *http.Request, url string, filename string, user *User, dirMatter *Matter, privacy bool) *Matter { +// crawl a url to dirMatter +func (this *MatterService) AtomicCrawl(request *http.Request, url string, filename string, user *User, space *Space, dirMatter *Matter, privacy bool) *Matter { if user == nil { panic(result.BadRequest("user cannot be nil.")) @@ -1149,10 +1155,10 @@ func (this *MatterService) AtomicCrawl(request *http.Request, url string, filena resp, err := http.Get(url) this.PanicError(err) - return this.Upload(request, resp.Body, user, dirMatter, filename, privacy) + return this.Upload(request, resp.Body, user, space, dirMatter, filename, privacy) } -//adjust a matter's path. +// adjust a matter's path. func (this *MatterService) adjustPath(matter *Matter, parentMatter *Matter) { if matter.Dir { @@ -1176,45 +1182,45 @@ func (this *MatterService) adjustPath(matter *Matter, parentMatter *Matter) { } -//delete someone's EyeblueTank files according to physics files. -func (this *MatterService) DeleteByPhysics(request *http.Request, user *User) { +// delete someone's EyeblueTank files according to physics files. +func (this *MatterService) DeleteByPhysics(request *http.Request, user *User, space *Space) { if user == nil { panic(result.BadRequest("user cannot be nil.")) } //scan user's file. scan level by level. - rootMatter := NewRootMatter(user) - this.deleteFolderByPhysics(request, rootMatter, user) + rootMatter := NewRootMatter(user, space) + this.deleteFolderByPhysics(request, rootMatter, user, space) } -func (this *MatterService) deleteFolderByPhysics(request *http.Request, dirMatter *Matter, user *User) { +func (this *MatterService) deleteFolderByPhysics(request *http.Request, dirMatter *Matter, user *User, space *Space) { //scan user's file. scan level by level. this.matterDao.PageHandle(dirMatter.Uuid, user.Uuid, "", "", "", nil, nil, func(matter *Matter) { if matter.Dir { //delete children first. - this.deleteFolderByPhysics(request, matter, user) + this.deleteFolderByPhysics(request, matter, user, space) } if !util.PathExists(matter.AbsolutePath()) { this.logger.Info("physics file not exist. delete from tank. %s", matter.Name) - this.AtomicDelete(nil, matter, user) + this.AtomicDelete(nil, matter, user, space) } }) } -//scan someone's physics files to EyeblueTank -func (this *MatterService) ScanPhysics(request *http.Request, user *User) { +// scan someone's physics files to EyeblueTank +func (this *MatterService) ScanPhysics(request *http.Request, user *User, space *Space) { if user == nil { panic(result.BadRequest("user cannot be nil.")) } - rootDirPath := GetUserMatterRootDir(user.Username) + rootDirPath := GetSpaceMatterRootDir(user.Username) this.logger.Info("scan %s's root dir %s", user.Username, rootDirPath) rootExists := util.PathExists(rootDirPath) @@ -1226,11 +1232,11 @@ func (this *MatterService) ScanPhysics(request *http.Request, user *User) { panic(result.BadRequest("cannot get root file info.")) } - rootMatter := NewRootMatter(user) - this.scanPhysicsFolder(request, rootFileInfo, rootMatter, user) + rootMatter := NewRootMatter(user, space) + this.scanPhysicsFolder(request, rootFileInfo, rootMatter, user, space) } -func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.FileInfo, dirMatter *Matter, user *User) { +func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.FileInfo, dirMatter *Matter, user *User, space *Space) { if !dirInfo.IsDir() { return } @@ -1266,12 +1272,12 @@ func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.F if !matter.Dir { if matter.Size != fileInfo.Size() { this.logger.Info("update matter: %s size:%d -> %d", name, matter.Size, fileInfo.Size()) - this.updateNonDirMatter(matter, fileInfo.Size(), user) + this.updateNonDirMatter(matter, fileInfo.Size(), user, space) } } else { //recursive scan this folder. - this.scanPhysicsFolder(request, fileInfo, matter, user) + this.scanPhysicsFolder(request, fileInfo, matter, user, space) } @@ -1283,13 +1289,13 @@ func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.F matter = this.createDirectory(request, dirMatter, name, user) //recursive scan this folder. - this.scanPhysicsFolder(request, fileInfo, matter, user) + this.scanPhysicsFolder(request, fileInfo, matter, user, space) } else { //not exist. add basic info. this.logger.Info("Create matter: %s size:%d", name, fileInfo.Size()) - matter = this.createNonDirMatter(dirMatter, name, fileInfo.Size(), true, user) + matter = this.createNonDirMatter(dirMatter, name, fileInfo.Size(), true, user, space) } @@ -1297,14 +1303,14 @@ func (this *MatterService) scanPhysicsFolder(request *http.Request, dirInfo os.F } } -//clean all the expired deleted matters +// clean all the expired deleted matters func (this *MatterService) CleanExpiredDeletedMatters() { //mock a request. request := &http.Request{} preference := this.preferenceService.Fetch() - this.userDao.PageHandle("", "", func(user *User) { + this.userDao.PageHandle("", "", func(user *User, space *Space) { this.logger.Info("Clean %s 's deleted matters", user.Username) @@ -1316,7 +1322,7 @@ func (this *MatterService) CleanExpiredDeletedMatters() { //first remove all the matter(not dir). this.matterDao.PageHandle("", "", "", FALSE, TRUE, &thenDate, nil, func(matter *Matter) { - this.Delete(request, matter, user) + this.Delete(request, matter, user, space) }) sortArray := []builder.OrderPair{ @@ -1328,7 +1334,7 @@ func (this *MatterService) CleanExpiredDeletedMatters() { //remove all the deleted directories. sort by path. this.matterDao.PageHandle("", "", "", TRUE, TRUE, &thenDate, sortArray, func(matter *Matter) { - this.Delete(request, matter, user) + this.Delete(request, matter, user, space) }) }) diff --git a/code/rest/space_model.go b/code/rest/space_model.go index a4867a5..dcb480b 100644 --- a/code/rest/space_model.go +++ b/code/rest/space_model.go @@ -20,7 +20,7 @@ type Space struct { UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"` CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"` Name string `json:"name" gorm:"type:varchar(100) not null;unique"` - UserUuid string `json:"userUuid" gorm:"type:char(36);unique"` + UserUuid string `json:"userUuid" gorm:"type:char(36)"` SizeLimit int64 `json:"sizeLimit" gorm:"type:bigint(20) not null;default:-1"` TotalSizeLimit int64 `json:"totalSizeLimit" gorm:"type:bigint(20) not null;default:-1"` TotalSize int64 `json:"totalSize" gorm:"type:bigint(20) not null;default:0"` diff --git a/code/rest/task_service.go b/code/rest/task_service.go index ffaf9d6..1b839eb 100644 --- a/code/rest/task_service.go +++ b/code/rest/task_service.go @@ -8,7 +8,7 @@ import ( ) // system tasks service -//@Service +// @Service type TaskService struct { BaseBean footprintService *FootprintService @@ -16,6 +16,7 @@ type TaskService struct { preferenceService *PreferenceService matterService *MatterService userDao *UserDao + spaceDao *SpaceDao //whether scan task is running scanTaskRunning bool @@ -48,11 +49,15 @@ func (this *TaskService) Init() { if b, ok := b.(*UserDao); ok { this.userDao = b } + b = core.CONTEXT.GetBean(this.spaceDao) + if b, ok := b.(*SpaceDao); ok { + this.spaceDao = b + } this.scanTaskRunning = false } -//init the clean footprint task. +// init the clean footprint task. func (this *TaskService) InitCleanFootprintTask() { //use standard cron expression. 5 fields. () @@ -65,7 +70,7 @@ func (this *TaskService) InitCleanFootprintTask() { this.logger.Info("[cron job] Every day 00:10 delete Footprint data of 8 days ago.") } -//init the elt task. +// init the elt task. func (this *TaskService) InitEtlTask() { expression := "5 0 * * *" @@ -77,7 +82,7 @@ func (this *TaskService) InitEtlTask() { this.logger.Info("[cron job] Everyday 00:05 ETL dashboard data.") } -//init the clean deleted matters task. +// init the clean deleted matters task. func (this *TaskService) InitCleanDeletedMattersTask() { expression := "0 1 * * *" @@ -89,7 +94,7 @@ func (this *TaskService) InitCleanDeletedMattersTask() { this.logger.Info("[cron job] Everyday 01:00 Clean deleted matters.") } -//scan task. +// scan task. func (this *TaskService) doScanTask() { if this.scanTaskRunning { @@ -121,12 +126,12 @@ func (this *TaskService) doScanTask() { if scanConfig.Scope == SCAN_SCOPE_ALL { //scan all user's root folder. - this.userDao.PageHandle("", "", func(user *User) { + this.userDao.PageHandle("", "", func(user *User, space *Space) { core.RunWithRecovery(func() { - this.matterService.DeleteByPhysics(request, user) - this.matterService.ScanPhysics(request, user) + this.matterService.DeleteByPhysics(request, user, space) + this.matterService.ScanPhysics(request, user, space) }) @@ -142,10 +147,11 @@ func (this *TaskService) doScanTask() { } else { this.logger.Info("scan custom user folder. username = %s", username) + space := this.spaceDao.CheckByUuid(user.SpaceUuid) core.RunWithRecovery(func() { - this.matterService.DeleteByPhysics(request, user) - this.matterService.ScanPhysics(request, user) + this.matterService.DeleteByPhysics(request, user, space) + this.matterService.ScanPhysics(request, user, space) }) @@ -155,7 +161,7 @@ func (this *TaskService) doScanTask() { } -//init the scan task. +// init the scan task. func (this *TaskService) InitScanTask() { if this.scanTaskCron != nil { diff --git a/code/rest/user_controller.go b/code/rest/user_controller.go index 84cfa9b..abab182 100644 --- a/code/rest/user_controller.go +++ b/code/rest/user_controller.go @@ -16,6 +16,8 @@ type UserController struct { BaseController preferenceService *PreferenceService userService *UserService + spaceDao *SpaceDao + spaceService *SpaceService matterService *MatterService } @@ -32,6 +34,14 @@ func (this *UserController) Init() { this.userService = b } + b = core.CONTEXT.GetBean(this.spaceDao) + if b, ok := b.(*SpaceDao); ok { + this.spaceDao = b + } + b = core.CONTEXT.GetBean(this.spaceService) + if b, ok := b.(*SpaceService); ok { + this.spaceService = b + } b = core.CONTEXT.GetBean(this.matterService) if b, ok := b.(*MatterService); ok { this.matterService = b @@ -169,15 +179,7 @@ func (this *UserController) Register(writer http.ResponseWriter, request *http.R panic(result.BadRequestI18n(request, i18n.UsernameExist, username)) } - user := &User{ - Role: USER_ROLE_USER, - Username: username, - Password: util.GetBcrypt(password), - TotalSizeLimit: preference.DefaultTotalSizeLimit, - Status: USER_STATUS_OK, - } - - user = this.userDao.Create(user) + user := this.userService.CreateUser(request, username, -1, preference.DefaultTotalSizeLimit, password, USER_ROLE_USER) //auto login this.innerLogin(writer, request, user) @@ -190,31 +192,9 @@ func (this *UserController) Create(writer http.ResponseWriter, request *http.Req username := request.FormValue("username") password := request.FormValue("password") role := request.FormValue("role") - sizeLimitStr := request.FormValue("sizeLimit") - totalSizeLimitStr := request.FormValue("totalSizeLimit") - //only admin can edit user's sizeLimit - var sizeLimit int64 = 0 - if sizeLimitStr == "" { - panic("user's limit size is required") - } else { - intSizeLimit, err := strconv.Atoi(sizeLimitStr) - if err != nil { - this.PanicError(err) - } - sizeLimit = int64(intSizeLimit) - } - - 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) - } + sizeLimit := util.ExtractRequestInt64(request, "sizeLimit", "space's limit size is required") + totalSizeLimit := util.ExtractRequestInt64(request, "totalSizeLimit", "space's total limit size is required") //validation work. if m, _ := regexp.MatchString(USERNAME_PATTERN, username); !m { @@ -234,7 +214,7 @@ func (this *UserController) Create(writer http.ResponseWriter, request *http.Req panic(result.BadRequestI18n(request, i18n.UserRoleError)) } - user := this.userService.CreateUser(request, username, password, role, sizeLimit, totalSizeLimit) + user := this.userService.CreateUser(request, username, sizeLimit, totalSizeLimit, password, role) return this.Success(user) } @@ -243,8 +223,6 @@ func (this *UserController) Edit(writer http.ResponseWriter, request *http.Reque uuid := request.FormValue("uuid") avatarUrl := request.FormValue("avatarUrl") - sizeLimitStr := request.FormValue("sizeLimit") - totalSizeLimitStr := request.FormValue("totalSizeLimit") role := request.FormValue("role") user := this.checkUser(request) @@ -254,29 +232,6 @@ func (this *UserController) Edit(writer http.ResponseWriter, request *http.Reque if user.Role == USER_ROLE_ADMINISTRATOR { //only admin can edit user's sizeLimit - var sizeLimit int64 = 0 - if sizeLimitStr == "" { - panic("user's limit size is required") - } else { - intSizeLimit, err := strconv.Atoi(sizeLimitStr) - if err != nil { - this.PanicError(err) - } - 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 if role == USER_ROLE_USER || role == USER_ROLE_ADMINISTRATOR { currentUser.Role = role @@ -437,8 +392,9 @@ func (this *UserController) Scan(writer http.ResponseWriter, request *http.Reque uuid := request.FormValue("uuid") currentUser := this.userDao.CheckByUuid(uuid) - this.matterService.DeleteByPhysics(request, currentUser) - this.matterService.ScanPhysics(request, currentUser) + space := this.spaceDao.CheckByUuid(currentUser.SpaceUuid) + this.matterService.DeleteByPhysics(request, currentUser, space) + this.matterService.ScanPhysics(request, currentUser, space) return this.Success("OK") } diff --git a/code/rest/user_dao.go b/code/rest/user_dao.go index 627b841..674c361 100644 --- a/code/rest/user_dao.go +++ b/code/rest/user_dao.go @@ -11,10 +11,17 @@ import ( type UserDao struct { BaseDao + spaceDao *SpaceDao } func (this *UserDao) Init() { this.BaseDao.Init() + + b := core.CONTEXT.GetBean(this.spaceDao) + if b, ok := b.(*SpaceDao); ok { + this.spaceDao = b + } + } func (this *UserDao) Create(user *User) *User { @@ -36,7 +43,7 @@ func (this *UserDao) Create(user *User) *User { return user } -//find by uuid. if not found return nil. +// find by uuid. if not found return nil. func (this *UserDao) FindByUuid(uuid string) *User { var entity = &User{} db := core.CONTEXT.GetDB().Where("uuid = ?", uuid).First(entity) @@ -50,7 +57,7 @@ func (this *UserDao) FindByUuid(uuid string) *User { return entity } -//find by uuid. if not found panic NotFound error +// find by uuid. if not found panic NotFound error func (this *UserDao) CheckByUuid(uuid string) *User { entity := this.FindByUuid(uuid) if entity == nil { @@ -111,8 +118,8 @@ func (this *UserDao) PlainPage(page int, pageSize int, username string, status s return int(count), users } -//handle user page by page. -func (this *UserDao) PageHandle(username string, status string, fun func(user *User)) { +// handle user page by page. +func (this *UserDao) PageHandle(username string, status string, fun func(user *User, space *Space)) { //delete share and bridges. pageSize := 1000 @@ -129,7 +136,8 @@ func (this *UserDao) PageHandle(username string, status string, fun func(user *U for page = 0; page < totalPages; page++ { _, users := this.PlainPage(0, pageSize, username, status, sortArray) for _, u := range users { - fun(u) + space := this.spaceDao.CheckByUuid(u.SpaceUuid) + fun(u, space) } } } @@ -154,7 +162,7 @@ func (this *UserDao) Save(user *User) *User { return user } -//find all 2.0 users. +// find all 2.0 users. func (this *UserDao) FindUsers20() []*User { var users []*User var wp = &builder.WherePair{} @@ -179,7 +187,7 @@ func (this *UserDao) Delete(user *User) { this.PanicError(db.Error) } -//System cleanup. +// System cleanup. func (this *UserDao) Cleanup() { this.logger.Info("[UserDao] clean up. Delete all User") db := core.CONTEXT.GetDB().Where("uuid is not null and role != ?", USER_ROLE_ADMINISTRATOR).Delete(User{}) diff --git a/code/rest/user_model.go b/code/rest/user_model.go index f2bc0cc..6d84891 100644 --- a/code/rest/user_model.go +++ b/code/rest/user_model.go @@ -27,18 +27,18 @@ const ( ) type User struct { - Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"` - Sort int64 `json:"sort" gorm:"type:bigint(20) not null"` - UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"` - CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"` - Role string `json:"role" gorm:"type:varchar(45)"` - Username string `json:"username" gorm:"type:varchar(45) not null;unique"` - Password string `json:"-" gorm:"type:varchar(255)"` - AvatarUrl string `json:"avatarUrl" gorm:"type:varchar(255)"` - LastIp string `json:"lastIp" gorm:"type:varchar(128)"` - LastTime time.Time `json:"lastTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"` - SizeLimit int64 `json:"sizeLimit" gorm:"type:bigint(20) not null;default:-1"` - TotalSizeLimit int64 `json:"totalSizeLimit" gorm:"type:bigint(20) not null;default:-1"` - TotalSize int64 `json:"totalSize" gorm:"type:bigint(20) not null;default:0"` - Status string `json:"status" gorm:"type:varchar(45)"` + Uuid string `json:"uuid" gorm:"type:char(36);primary_key;unique"` + Sort int64 `json:"sort" gorm:"type:bigint(20) not null"` + UpdateTime time.Time `json:"updateTime" gorm:"type:timestamp not null;default:CURRENT_TIMESTAMP"` + CreateTime time.Time `json:"createTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"` + Role string `json:"role" gorm:"type:varchar(45)"` + Username string `json:"username" gorm:"type:varchar(45) not null;unique"` + Password string `json:"-" gorm:"type:varchar(255)"` + AvatarUrl string `json:"avatarUrl" gorm:"type:varchar(255)"` + LastIp string `json:"lastIp" gorm:"type:varchar(128)"` + LastTime time.Time `json:"lastTime" gorm:"type:timestamp not null;default:'2018-01-01 00:00:00'"` + + SpaceUuid string `json:"spaceUuid" gorm:"type:char(36);unique"` + Status string `json:"status" gorm:"type:varchar(45)"` + Space *Space `json:"space" gorm:"-"` } diff --git a/code/rest/user_service.go b/code/rest/user_service.go index c99b231..dddee10 100644 --- a/code/rest/user_service.go +++ b/code/rest/user_service.go @@ -17,6 +17,8 @@ type UserService struct { userDao *UserDao sessionDao *SessionDao + spaceService *SpaceService + //file lock locker *cache.Table @@ -43,6 +45,11 @@ func (this *UserService) Init() { this.sessionDao = b } + b = core.CONTEXT.GetBean(this.spaceService) + if b, ok := b.(*SpaceService); ok { + this.spaceService = b + } + b = core.CONTEXT.GetBean(this.matterDao) if b, ok := b.(*MatterDao); ok { this.matterDao = b @@ -234,19 +241,26 @@ func (this *UserService) RemoveCacheUserByUuid(userUuid string) { } // create user -func (this *UserService) CreateUser(request *http.Request, username string, password string, role string, sizeLimit int64, totalSizeLimit int64) *User { +func (this *UserService) CreateUser(request *http.Request, username string, sizeLimit int64, totalSizeLimit int64, password string, role string) *User { user := &User{ - Username: username, - Password: util.GetBcrypt(password), - Role: role, - SizeLimit: sizeLimit, - TotalSizeLimit: totalSizeLimit, - Status: USER_STATUS_OK, + Username: username, + Password: util.GetBcrypt(password), + Role: role, + Status: USER_STATUS_OK, } user = this.userDao.Create(user) + //create space. + space := this.spaceService.CreateSpace(request, username, user, sizeLimit, totalSizeLimit, SPACE_TYPE_PRIVATE) + + //update user's space. + user.SpaceUuid = space.Uuid + this.userDao.Save(user) + + user.Space = space + return user } diff --git a/code/tool/i18n/i18n.go b/code/tool/i18n/i18n.go index 548e443..2cc1ed5 100644 --- a/code/tool/i18n/i18n.go +++ b/code/tool/i18n/i18n.go @@ -51,7 +51,6 @@ var ( SpaceNameExist = &Item{English: `space's name "%s" exists`, Chinese: `空间名称"%s"已被占用,请使用其他名字`} SpaceExclusive = &Item{English: `user can only own ONE space`, Chinese: `一个用户只能拥有一个私有空间`} SpaceMemberExist = &Item{English: `space member exists`, Chinese: `该用于已经是空间的成员`} - SpaceMemberRoleConflict = &Item{English: `space member cannot contain user with role space.`, Chinese: `空间成员不能是空间角色的用户`} PermissionDenied = &Item{English: `permission denied.`, Chinese: `没有操作权限`} )