feat: remove the space props in the user model.

This commit is contained in:
lishuang
2023-05-27 14:12:35 +08:00
parent 691fb2a380
commit 9e6d2c1043
21 changed files with 422 additions and 356 deletions
+26 -16
View File
@@ -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)
+2 -2
View File
@@ -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)
+5 -4
View File
@@ -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)
}
+10 -3
View File
@@ -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)
}
+17 -17
View File
@@ -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 `<D:collection xmlns:D="DAV:"/>`
} 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 `` +
`<D:lockentry xmlns:D="DAV:">` +
`<D:lockscope><D:exclusive/></D:lockscope>` +
@@ -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,
},
+56 -56
View File
@@ -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" {
+6 -6
View File
@@ -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{})
+1 -1
View File
@@ -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
}
+4 -4
View File
@@ -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)
+20 -5
View File
@@ -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")
+29 -16
View File
@@ -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)
+36 -6
View File
@@ -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{}
+11 -10
View File
@@ -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
}
+114 -108
View File
@@ -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)
})
})
+1 -1
View File
@@ -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"`
+17 -11
View File
@@ -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 {
+17 -61
View File
@@ -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")
}
+15 -7
View File
@@ -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{})
+14 -14
View File
@@ -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:"-"`
}
+21 -7
View File
@@ -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
}
-1
View File
@@ -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: `没有操作权限`}
)