|
@@ -188,6 +188,7 @@ func FileSystemInit() {
|
|
router.HandleFunc("/system/file_system/share/delete", shareManager.HandleDeleteShare)
|
|
router.HandleFunc("/system/file_system/share/delete", shareManager.HandleDeleteShare)
|
|
router.HandleFunc("/system/file_system/share/edit", shareManager.HandleEditShare)
|
|
router.HandleFunc("/system/file_system/share/edit", shareManager.HandleEditShare)
|
|
router.HandleFunc("/system/file_system/share/checkShared", shareManager.HandleShareCheck)
|
|
router.HandleFunc("/system/file_system/share/checkShared", shareManager.HandleShareCheck)
|
|
|
|
+ router.HandleFunc("/system/file_system/share/list", shareManager.HandleListAllShares)
|
|
|
|
|
|
//Handle the main share function
|
|
//Handle the main share function
|
|
//Share function is now routed by the main router
|
|
//Share function is now routed by the main router
|
|
@@ -250,7 +251,7 @@ func system_fs_handleFileSearch(w http.ResponseWriter, r *http.Request) {
|
|
//Check if case sensitive is enabled
|
|
//Check if case sensitive is enabled
|
|
casesensitve, _ := common.Mv(r, "casesensitive", true)
|
|
casesensitve, _ := common.Mv(r, "casesensitive", true)
|
|
|
|
|
|
- vrootID, subpath, err := fs.GetIDFromVirtualPath(vpath)
|
|
|
|
|
|
+ vrootID, _, err := fs.GetIDFromVirtualPath(vpath)
|
|
var targetFSH *filesystem.FileSystemHandler = nil
|
|
var targetFSH *filesystem.FileSystemHandler = nil
|
|
if err != nil {
|
|
if err != nil {
|
|
common.SendErrorResponse(w, "Invalid path given")
|
|
common.SendErrorResponse(w, "Invalid path given")
|
|
@@ -317,44 +318,24 @@ func system_fs_handleFileSearch(w http.ResponseWriter, r *http.Request) {
|
|
//Recursive keyword
|
|
//Recursive keyword
|
|
results := []fs.FileData{}
|
|
results := []fs.FileData{}
|
|
var err error = nil
|
|
var err error = nil
|
|
- if targetFSH != nil && targetFSH.UUID == "share" {
|
|
|
|
- //To be done: Move hardcoded vroot ID to interface for all virtual storage devices
|
|
|
|
|
|
+
|
|
|
|
+ fshAbs := targetFSH.FileSystemAbstraction
|
|
|
|
+ err = fshAbs.Walk(rpath, func(path string, info os.FileInfo, err error) error {
|
|
|
|
+ thisFilename := filepath.Base(path)
|
|
if casesensitve != "true" {
|
|
if casesensitve != "true" {
|
|
- keyword = strings.ToLower(keyword)
|
|
|
|
|
|
+ thisFilename = strings.ToLower(thisFilename)
|
|
}
|
|
}
|
|
- err = shareManager.Walk(subpath, userinfo, func(fileData fs.FileData) error {
|
|
|
|
- filename := filepath.Base(fileData.Filename)
|
|
|
|
- if casesensitve != "true" {
|
|
|
|
- filename = strings.ToLower(filename)
|
|
|
|
- }
|
|
|
|
- if matcher.Match(filename) {
|
|
|
|
- //This is a matching file
|
|
|
|
- if !fs.IsInsideHiddenFolder(fileData.Filepath) {
|
|
|
|
- results = append(results, fileData)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return nil
|
|
|
|
- })
|
|
|
|
|
|
|
|
- } else {
|
|
|
|
- fshAbs := targetFSH.FileSystemAbstraction
|
|
|
|
- err = fshAbs.Walk(rpath, func(path string, info os.FileInfo, err error) error {
|
|
|
|
- thisFilename := filepath.Base(path)
|
|
|
|
- if casesensitve != "true" {
|
|
|
|
- thisFilename = strings.ToLower(thisFilename)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if !fs.IsInsideHiddenFolder(path) {
|
|
|
|
- if matcher.Match(thisFilename) {
|
|
|
|
- //This is a matching file
|
|
|
|
- thisVpath, _ := fshAbs.RealPathToVirtualPath(path, userinfo.Username)
|
|
|
|
- results = append(results, fs.GetFileDataFromPath(targetFSH, thisVpath, path, 2))
|
|
|
|
- }
|
|
|
|
|
|
+ if !fs.IsInsideHiddenFolder(path) {
|
|
|
|
+ if matcher.Match(thisFilename) {
|
|
|
|
+ //This is a matching file
|
|
|
|
+ thisVpath, _ := fshAbs.RealPathToVirtualPath(path, userinfo.Username)
|
|
|
|
+ results = append(results, fs.GetFileDataFromPath(targetFSH, thisVpath, path, 2))
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
|
|
- return nil
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
|
|
+ return nil
|
|
|
|
+ })
|
|
|
|
|
|
if err != nil {
|
|
if err != nil {
|
|
common.SendErrorResponse(w, err.Error())
|
|
common.SendErrorResponse(w, err.Error())
|
|
@@ -2238,13 +2219,6 @@ func system_fs_listRoot(w http.ResponseWriter, r *http.Request) {
|
|
} else if store.Hierarchy == "backup" {
|
|
} else if store.Hierarchy == "backup" {
|
|
//Backup drive.
|
|
//Backup drive.
|
|
backupRoots = append(backupRoots, store.HierarchyConfig.(hybridBackup.BackupTask).ParentUID)
|
|
backupRoots = append(backupRoots, store.HierarchyConfig.(hybridBackup.BackupTask).ParentUID)
|
|
- } else if store.Hierarchy == "share" {
|
|
|
|
- //Share emulated drive
|
|
|
|
- var thisDevice = new(rootObject)
|
|
|
|
- thisDevice.RootName = store.Name
|
|
|
|
- thisDevice.RootPath = store.UUID + ":/"
|
|
|
|
- thisDevice.rootID = store.UUID
|
|
|
|
- roots = append(roots, thisDevice)
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2349,97 +2323,68 @@ func system_fs_getFileProperties(w http.ResponseWriter, r *http.Request) {
|
|
vrootID, subpath, _ := filesystem.GetIDFromVirtualPath(vpath)
|
|
vrootID, subpath, _ := filesystem.GetIDFromVirtualPath(vpath)
|
|
fsh, _ := GetFsHandlerByUUID(vrootID)
|
|
fsh, _ := GetFsHandlerByUUID(vrootID)
|
|
fshAbs := fsh.FileSystemAbstraction
|
|
fshAbs := fsh.FileSystemAbstraction
|
|
- if vrootID == "share" && subpath == "" {
|
|
|
|
- result = fileProperties{
|
|
|
|
- VirtualPath: vpath,
|
|
|
|
- StoragePath: "(Emulated File System)",
|
|
|
|
- Basename: "Share",
|
|
|
|
- VirtualDirname: filepath.ToSlash(filepath.Dir(vpath)),
|
|
|
|
- StorageDirname: "N/A",
|
|
|
|
- Ext: "N/A",
|
|
|
|
- MimeType: "emulated/fs",
|
|
|
|
- Filesize: -1,
|
|
|
|
- Permission: "N/A",
|
|
|
|
- LastModTime: "N/A",
|
|
|
|
- LastModUnix: 0,
|
|
|
|
- IsDirectory: true,
|
|
|
|
- Owner: "system",
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- rpath, err := fshAbs.VirtualPathToRealPath(subpath, userinfo.Username)
|
|
|
|
- if err != nil {
|
|
|
|
- common.SendErrorResponse(w, err.Error())
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fileStat, err := fshAbs.Stat(rpath)
|
|
|
|
- if err != nil {
|
|
|
|
- common.SendErrorResponse(w, err.Error())
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
|
|
|
|
- fileMime := "text/directory"
|
|
|
|
- if !fileStat.IsDir() {
|
|
|
|
- m, _, err := fs.GetMime(rpath)
|
|
|
|
- if err != nil {
|
|
|
|
- fileMime = mime.TypeByExtension(filepath.Ext(rpath))
|
|
|
|
- } else {
|
|
|
|
- fileMime = m
|
|
|
|
- }
|
|
|
|
|
|
+ rpath, err := fshAbs.VirtualPathToRealPath(subpath, userinfo.Username)
|
|
|
|
+ if err != nil {
|
|
|
|
+ common.SendErrorResponse(w, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ fileStat, err := fshAbs.Stat(rpath)
|
|
|
|
+ if err != nil {
|
|
|
|
+ common.SendErrorResponse(w, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
|
|
- filesize := fileStat.Size()
|
|
|
|
- //Get file overall size if this is folder
|
|
|
|
- if fileStat.IsDir() {
|
|
|
|
- var size int64
|
|
|
|
- fshAbs.Walk(rpath, func(_ string, info os.FileInfo, err error) error {
|
|
|
|
- if err != nil {
|
|
|
|
- return err
|
|
|
|
- }
|
|
|
|
- if !info.IsDir() {
|
|
|
|
- size += info.Size()
|
|
|
|
- }
|
|
|
|
- return err
|
|
|
|
- })
|
|
|
|
- filesize = size
|
|
|
|
|
|
+ fileMime := "text/directory"
|
|
|
|
+ if !fileStat.IsDir() {
|
|
|
|
+ m, _, err := fs.GetMime(rpath)
|
|
|
|
+ if err != nil {
|
|
|
|
+ fileMime = mime.TypeByExtension(filepath.Ext(rpath))
|
|
|
|
+ } else {
|
|
|
|
+ fileMime = m
|
|
}
|
|
}
|
|
|
|
|
|
- //Get file owner
|
|
|
|
- owner := userinfo.GetFileOwner(rpath)
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- if owner == "" {
|
|
|
|
- //Handle special virtual roots
|
|
|
|
- vrootID, subpath, _ := filesystem.GetIDFromVirtualPath(vpath)
|
|
|
|
- if vrootID == "share" {
|
|
|
|
- //Share objects
|
|
|
|
- shareOption, _ := shareEntryTable.ResolveShareOptionFromShareSubpath(subpath)
|
|
|
|
- if shareOption != nil {
|
|
|
|
- owner = shareOption.Owner
|
|
|
|
- } else {
|
|
|
|
- owner = "Unknown"
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- owner = "Unknown"
|
|
|
|
|
|
+ filesize := fileStat.Size()
|
|
|
|
+ //Get file overall size if this is folder
|
|
|
|
+ if fileStat.IsDir() {
|
|
|
|
+ var size int64
|
|
|
|
+ fshAbs.Walk(rpath, func(_ string, info os.FileInfo, err error) error {
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ if !info.IsDir() {
|
|
|
|
+ size += info.Size()
|
|
}
|
|
}
|
|
|
|
+ return err
|
|
|
|
+ })
|
|
|
|
+ filesize = size
|
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ //Get file owner
|
|
|
|
+ owner := userinfo.GetFileOwner(rpath)
|
|
|
|
|
|
- result = fileProperties{
|
|
|
|
- VirtualPath: vpath,
|
|
|
|
- StoragePath: filepath.ToSlash(filepath.Clean(rpath)),
|
|
|
|
- Basename: filepath.Base(rpath),
|
|
|
|
- VirtualDirname: filepath.ToSlash(filepath.Dir(vpath)),
|
|
|
|
- StorageDirname: filepath.ToSlash(filepath.Dir(rpath)),
|
|
|
|
- Ext: filepath.Ext(rpath),
|
|
|
|
- MimeType: fileMime,
|
|
|
|
- Filesize: filesize,
|
|
|
|
- Permission: fileStat.Mode().Perm().String(),
|
|
|
|
- LastModTime: fileStat.ModTime().Format("2006-01-02 15:04:05"),
|
|
|
|
- LastModUnix: fileStat.ModTime().Unix(),
|
|
|
|
- IsDirectory: fileStat.IsDir(),
|
|
|
|
- Owner: owner,
|
|
|
|
- }
|
|
|
|
|
|
+ if owner == "" {
|
|
|
|
+ //Handle special virtual roots
|
|
|
|
+ owner = "Unknown"
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ result = fileProperties{
|
|
|
|
+ VirtualPath: vpath,
|
|
|
|
+ StoragePath: filepath.ToSlash(filepath.Clean(rpath)),
|
|
|
|
+ Basename: filepath.Base(rpath),
|
|
|
|
+ VirtualDirname: filepath.ToSlash(filepath.Dir(vpath)),
|
|
|
|
+ StorageDirname: filepath.ToSlash(filepath.Dir(rpath)),
|
|
|
|
+ Ext: filepath.Ext(rpath),
|
|
|
|
+ MimeType: fileMime,
|
|
|
|
+ Filesize: filesize,
|
|
|
|
+ Permission: fileStat.Mode().Perm().String(),
|
|
|
|
+ LastModTime: fileStat.ModTime().Format("2006-01-02 15:04:05"),
|
|
|
|
+ LastModUnix: fileStat.ModTime().Unix(),
|
|
|
|
+ IsDirectory: fileStat.IsDir(),
|
|
|
|
+ Owner: owner,
|
|
}
|
|
}
|
|
|
|
|
|
jsonString, _ := json.Marshal(result)
|
|
jsonString, _ := json.Marshal(result)
|
|
@@ -2489,87 +2434,81 @@ func system_fs_handleList(w http.ResponseWriter, r *http.Request) {
|
|
fshAbs := fsh.FileSystemAbstraction
|
|
fshAbs := fsh.FileSystemAbstraction
|
|
|
|
|
|
var parsedFilelist []fs.FileData
|
|
var parsedFilelist []fs.FileData
|
|
- //Handle some special virtual file systems / mount points
|
|
|
|
- if fsh.UUID == "share" && subpath == "" {
|
|
|
|
- userpgs := userinfo.GetUserPermissionGroupNames()
|
|
|
|
- files := shareManager.ListRootForUser(userinfo, userpgs)
|
|
|
|
- parsedFilelist = files
|
|
|
|
- } else {
|
|
|
|
- //Normal file systems
|
|
|
|
- realpath, err := fshAbs.VirtualPathToRealPath(subpath, userinfo.Username)
|
|
|
|
- if err != nil {
|
|
|
|
- common.SendErrorResponse(w, err.Error())
|
|
|
|
|
|
+
|
|
|
|
+ //Normal file systems
|
|
|
|
+ realpath, err := fshAbs.VirtualPathToRealPath(subpath, userinfo.Username)
|
|
|
|
+ if err != nil {
|
|
|
|
+ common.SendErrorResponse(w, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if !fshAbs.FileExists(realpath) {
|
|
|
|
+ //Path not exists
|
|
|
|
+ userRoot, _ := fshAbs.VirtualPathToRealPath("", userinfo.Username)
|
|
|
|
+ if filepath.Clean(realpath) == filepath.Clean(userRoot) {
|
|
|
|
+ //Initiate user folder (Initiaed in user object)
|
|
|
|
+ userinfo.GetHomeDirectory()
|
|
|
|
+ } else if !strings.Contains(filepath.ToSlash(filepath.Clean(currentDir)), "/") {
|
|
|
|
+ //User root not created. Create the root folder
|
|
|
|
+ os.MkdirAll(filepath.Clean(realpath), 0775)
|
|
|
|
+ } else {
|
|
|
|
+ //Folder not exists
|
|
|
|
+ log.Println("[File Explorer] Requested path: ", realpath, " does not exists!")
|
|
|
|
+ common.SendErrorResponse(w, "Folder not exists")
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- if !fshAbs.FileExists(realpath) {
|
|
|
|
- //Path not exists
|
|
|
|
- userRoot, _ := fshAbs.VirtualPathToRealPath("", userinfo.Username)
|
|
|
|
- if filepath.Clean(realpath) == filepath.Clean(userRoot) {
|
|
|
|
- //Initiate user folder (Initiaed in user object)
|
|
|
|
- userinfo.GetHomeDirectory()
|
|
|
|
- } else if !strings.Contains(filepath.ToSlash(filepath.Clean(currentDir)), "/") {
|
|
|
|
- //User root not created. Create the root folder
|
|
|
|
- os.MkdirAll(filepath.Clean(realpath), 0775)
|
|
|
|
- } else {
|
|
|
|
- //Folder not exists
|
|
|
|
- log.Println("[File Explorer] Requested path: ", realpath, " does not exists!")
|
|
|
|
- common.SendErrorResponse(w, "Folder not exists")
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- if sortMode == "" {
|
|
|
|
- sortMode = "default"
|
|
|
|
- }
|
|
|
|
|
|
+ if sortMode == "" {
|
|
|
|
+ sortMode = "default"
|
|
|
|
+ }
|
|
|
|
|
|
- //Check for really special exception in where the path contains [ or ] which cannot be handled via Golang Glob function
|
|
|
|
- files, err := fshAbs.Glob(realpath + "/*")
|
|
|
|
- if err != nil {
|
|
|
|
- log.Println("[File System] Unable to list dir: " + err.Error())
|
|
|
|
- return
|
|
|
|
|
|
+ //Check for really special exception in where the path contains [ or ] which cannot be handled via Golang Glob function
|
|
|
|
+ files, err := fshAbs.Glob(realpath + "/*")
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Println("[File System] Unable to list dir: " + err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ var shortCutInfo *shortcut.ShortcutData = nil
|
|
|
|
+ for _, v := range files {
|
|
|
|
+ //Check if it is hidden file
|
|
|
|
+ isHidden, _ := hidden.IsHidden(v, false)
|
|
|
|
+ if showHidden != "true" && isHidden {
|
|
|
|
+ //Skipping hidden files
|
|
|
|
+ continue
|
|
}
|
|
}
|
|
- var shortCutInfo *shortcut.ShortcutData = nil
|
|
|
|
- for _, v := range files {
|
|
|
|
- //Check if it is hidden file
|
|
|
|
- isHidden, _ := hidden.IsHidden(v, false)
|
|
|
|
- if showHidden != "true" && isHidden {
|
|
|
|
- //Skipping hidden files
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
|
|
|
|
- //Check if this is an aodb file
|
|
|
|
- if filepath.Base(v) == "aofs.db" || filepath.Base(v) == "aofs.db.lock" {
|
|
|
|
- //Database file (reserved)
|
|
|
|
- continue
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //Check if it is shortcut file. If yes, render a shortcut data struct
|
|
|
|
- if filepath.Ext(v) == ".shortcut" {
|
|
|
|
- //This is a shortcut file
|
|
|
|
- shorcutData, err := shortcut.ReadShortcut(v)
|
|
|
|
- if err == nil {
|
|
|
|
- shortCutInfo = shorcutData
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ //Check if this is an aodb file
|
|
|
|
+ if filepath.Base(v) == "aofs.db" || filepath.Base(v) == "aofs.db.lock" {
|
|
|
|
+ //Database file (reserved)
|
|
|
|
+ continue
|
|
|
|
+ }
|
|
|
|
|
|
- rawsize := fshAbs.GetFileSize(v)
|
|
|
|
- modtime, _ := fshAbs.GetModTime(v)
|
|
|
|
- thisvPath, _ := fshAbs.RealPathToVirtualPath(v, userinfo.Username)
|
|
|
|
- thisFile := fs.FileData{
|
|
|
|
- Filename: filepath.Base(v),
|
|
|
|
- Filepath: currentDir + filepath.Base(v),
|
|
|
|
- Realpath: v,
|
|
|
|
- IsDir: fsh.FileSystemAbstraction.IsDir(v),
|
|
|
|
- Filesize: rawsize,
|
|
|
|
- Displaysize: fs.GetFileDisplaySize(rawsize, 2),
|
|
|
|
- ModTime: modtime,
|
|
|
|
- IsShared: shareManager.FileIsShared(userinfo, thisvPath),
|
|
|
|
- Shortcut: shortCutInfo,
|
|
|
|
|
|
+ //Check if it is shortcut file. If yes, render a shortcut data struct
|
|
|
|
+ if filepath.Ext(v) == ".shortcut" {
|
|
|
|
+ //This is a shortcut file
|
|
|
|
+ shorcutData, err := shortcut.ReadShortcut(v)
|
|
|
|
+ if err == nil {
|
|
|
|
+ shortCutInfo = shorcutData
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
|
|
- parsedFilelist = append(parsedFilelist, thisFile)
|
|
|
|
|
|
+ rawsize := fshAbs.GetFileSize(v)
|
|
|
|
+ modtime, _ := fshAbs.GetModTime(v)
|
|
|
|
+ thisvPath, _ := fshAbs.RealPathToVirtualPath(v, userinfo.Username)
|
|
|
|
+ thisFile := fs.FileData{
|
|
|
|
+ Filename: filepath.Base(v),
|
|
|
|
+ Filepath: currentDir + filepath.Base(v),
|
|
|
|
+ Realpath: v,
|
|
|
|
+ IsDir: fsh.FileSystemAbstraction.IsDir(v),
|
|
|
|
+ Filesize: rawsize,
|
|
|
|
+ Displaysize: fs.GetFileDisplaySize(rawsize, 2),
|
|
|
|
+ ModTime: modtime,
|
|
|
|
+ IsShared: shareManager.FileIsShared(userinfo, thisvPath),
|
|
|
|
+ Shortcut: shortCutInfo,
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ parsedFilelist = append(parsedFilelist, thisFile)
|
|
}
|
|
}
|
|
|
|
|
|
//Sort the filelist
|
|
//Sort the filelist
|
|
@@ -2617,13 +2556,9 @@ func system_fs_handleDirHash(w http.ResponseWriter, r *http.Request) {
|
|
common.SendErrorResponse(w, "Unable to resolve target directory")
|
|
common.SendErrorResponse(w, "Unable to resolve target directory")
|
|
return
|
|
return
|
|
}
|
|
}
|
|
- if fsh.UUID == "share" && subpath == "" {
|
|
|
|
- common.SendTextResponse(w, hex.EncodeToString([]byte("0")))
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
fshAbs := fsh.FileSystemAbstraction
|
|
fshAbs := fsh.FileSystemAbstraction
|
|
|
|
|
|
- rpath, err := fshAbs.VirtualPathToRealPath(currentDir, userinfo.Username)
|
|
|
|
|
|
+ rpath, err := fshAbs.VirtualPathToRealPath(subpath, userinfo.Username)
|
|
if err != nil {
|
|
if err != nil {
|
|
common.SendErrorResponse(w, "Invalid dir given")
|
|
common.SendErrorResponse(w, "Invalid dir given")
|
|
return
|
|
return
|