|
@@ -26,6 +26,7 @@ import (
|
|
|
"strings"
|
|
|
"time"
|
|
|
|
|
|
+ "imuslab.com/arozos/mod/filesystem/arozfs"
|
|
|
"imuslab.com/arozos/mod/filesystem/hidden"
|
|
|
|
|
|
archiver "github.com/mholt/archiver/v3"
|
|
@@ -161,13 +162,20 @@ func ArozUnzipFileWithProgress(filelist []string, outputfile string, progressHan
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-//Aroz Zip File with progress update function (current filename / current file count / total file count / progress in percentage)
|
|
|
-func ArozZipFileWithProgress(filelist []string, outputfile string, includeTopLevelFolder bool, progressHandler func(string, int, int, float64)) error {
|
|
|
+/*
|
|
|
+ Aroz Zip File with progress update function
|
|
|
+ Returns the following progress: (current filename / current file count / total file count / progress in percentage)
|
|
|
+ if output is local path that is out of the scope of any fsh, leave outputFsh as nil
|
|
|
+*/
|
|
|
+func ArozZipFileWithProgress(targetFshs []*FileSystemHandler, filelist []string, outputFsh *FileSystemHandler, outputfile string, includeTopLevelFolder bool, progressHandler func(string, int, int, float64)) error {
|
|
|
+ fmt.Println("WEBSOCKET ZIPPING", targetFshs, filelist)
|
|
|
//Get the file count from the filelist
|
|
|
totalFileCount := 0
|
|
|
- for _, srcpath := range filelist {
|
|
|
- if IsDir(srcpath) {
|
|
|
- filepath.Walk(srcpath, func(_ string, info os.FileInfo, _ error) error {
|
|
|
+ for i, srcpath := range filelist {
|
|
|
+ thisFsh := targetFshs[i]
|
|
|
+ fshAbs := thisFsh.FileSystemAbstraction
|
|
|
+ if thisFsh.FileSystemAbstraction.IsDir(srcpath) {
|
|
|
+ fshAbs.Walk(srcpath, func(_ string, info os.FileInfo, _ error) error {
|
|
|
if !info.IsDir() {
|
|
|
totalFileCount++
|
|
|
}
|
|
@@ -180,9 +188,16 @@ func ArozZipFileWithProgress(filelist []string, outputfile string, includeTopLev
|
|
|
}
|
|
|
|
|
|
//Create the target zip file
|
|
|
- file, err := os.Create(outputfile)
|
|
|
+ var file arozfs.File
|
|
|
+ var err error
|
|
|
+ if outputFsh != nil {
|
|
|
+ file, err = outputFsh.FileSystemAbstraction.Create(outputfile)
|
|
|
+ } else {
|
|
|
+ //Force local fs
|
|
|
+ file, err = os.Create(outputfile)
|
|
|
+ }
|
|
|
if err != nil {
|
|
|
- panic(err)
|
|
|
+ return err
|
|
|
}
|
|
|
defer file.Close()
|
|
|
|
|
@@ -190,11 +205,14 @@ func ArozZipFileWithProgress(filelist []string, outputfile string, includeTopLev
|
|
|
defer writer.Close()
|
|
|
|
|
|
currentFileCount := 0
|
|
|
- for _, srcpath := range filelist {
|
|
|
- if IsDir(srcpath) {
|
|
|
+ for i, srcpath := range filelist {
|
|
|
+ thisFsh := targetFshs[i]
|
|
|
+ fshAbs := thisFsh.FileSystemAbstraction
|
|
|
+ //Local File System
|
|
|
+ if fshAbs.IsDir(srcpath) {
|
|
|
//This is a directory
|
|
|
topLevelFolderName := filepath.ToSlash(filepath.Base(filepath.Dir(srcpath)) + "/" + filepath.Base(srcpath))
|
|
|
- err = filepath.Walk(srcpath, func(path string, info os.FileInfo, err error) error {
|
|
|
+ err = fshAbs.Walk(srcpath, func(path string, info os.FileInfo, err error) error {
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
@@ -202,11 +220,12 @@ func ArozZipFileWithProgress(filelist []string, outputfile string, includeTopLev
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
- if insideHiddenFolder(path) == true {
|
|
|
+ if insideHiddenFolder(path) {
|
|
|
//This is hidden file / folder. Skip this
|
|
|
return nil
|
|
|
}
|
|
|
- file, err := os.Open(path)
|
|
|
+
|
|
|
+ file, err := fshAbs.ReadStream(path)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
@@ -241,7 +260,7 @@ func ArozZipFileWithProgress(filelist []string, outputfile string, includeTopLev
|
|
|
} else {
|
|
|
//This is a file
|
|
|
topLevelFolderName := filepath.Base(filepath.Dir(srcpath))
|
|
|
- file, err := os.Open(srcpath)
|
|
|
+ file, err := fshAbs.ReadStream(srcpath)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
@@ -250,6 +269,7 @@ func ArozZipFileWithProgress(filelist []string, outputfile string, includeTopLev
|
|
|
if includeTopLevelFolder {
|
|
|
relativePath = topLevelFolderName + "/" + relativePath
|
|
|
}
|
|
|
+
|
|
|
f, err := writer.Create(relativePath)
|
|
|
if err != nil {
|
|
|
return err
|
|
@@ -270,10 +290,22 @@ func ArozZipFileWithProgress(filelist []string, outputfile string, includeTopLev
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-//ArOZ Zip FIle, but with no progress display
|
|
|
-func ArozZipFile(filelist []string, outputfile string, includeTopLevelFolder bool) error {
|
|
|
+/*
|
|
|
+ ArozZipFile
|
|
|
+ Zip file without progress update, support local file system or buffer space
|
|
|
+ To use it with local file system, pass in nil in fsh for each item in filelist, e.g.
|
|
|
+ filesystem.ArozZipFile([]*filesystem.FileSystemHandler{nil}, []string{zippingSource}, nil, targetZipFilename, false)
|
|
|
+*/
|
|
|
+func ArozZipFile(sourceFshs []*FileSystemHandler, filelist []string, outputFsh *FileSystemHandler, outputfile string, includeTopLevelFolder bool) error {
|
|
|
//Create the target zip file
|
|
|
- file, err := os.Create(outputfile)
|
|
|
+ var file arozfs.File
|
|
|
+ var err error
|
|
|
+ if outputFsh != nil {
|
|
|
+ file, err = outputFsh.FileSystemAbstraction.Create(outputfile)
|
|
|
+ } else {
|
|
|
+ //Force local fs
|
|
|
+ file, err = os.Create(outputfile)
|
|
|
+ }
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
@@ -282,35 +314,140 @@ func ArozZipFile(filelist []string, outputfile string, includeTopLevelFolder boo
|
|
|
writer := zip.NewWriter(file)
|
|
|
defer writer.Close()
|
|
|
|
|
|
- for _, srcpath := range filelist {
|
|
|
- if IsDir(srcpath) {
|
|
|
- //This is a directory
|
|
|
- topLevelFolderName := filepath.ToSlash(filepath.Base(filepath.Dir(srcpath)) + "/" + filepath.Base(srcpath))
|
|
|
- err = filepath.Walk(srcpath, func(path string, info os.FileInfo, err error) error {
|
|
|
+ for i, srcpath := range filelist {
|
|
|
+ thisFsh := sourceFshs[i]
|
|
|
+ var fshAbs FileSystemAbstraction
|
|
|
+ if thisFsh == nil {
|
|
|
+ //Use local fs functions
|
|
|
+ if IsDir(srcpath) {
|
|
|
+ //This is a directory
|
|
|
+ topLevelFolderName := filepath.ToSlash(filepath.Base(filepath.Dir(srcpath)) + "/" + filepath.Base(srcpath))
|
|
|
+ err = filepath.Walk(srcpath, func(path string, info os.FileInfo, err error) error {
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if info.IsDir() {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if insideHiddenFolder(path) {
|
|
|
+ //This is hidden file / folder. Skip this
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ file, err := os.Open(path)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer file.Close()
|
|
|
+
|
|
|
+ relativePath := strings.ReplaceAll(filepath.ToSlash(path), filepath.ToSlash(filepath.Clean(srcpath))+"/", "")
|
|
|
+ if includeTopLevelFolder {
|
|
|
+ relativePath = topLevelFolderName + "/" + relativePath
|
|
|
+ } else {
|
|
|
+ relativePath = filepath.Base(srcpath) + "/" + relativePath
|
|
|
+ }
|
|
|
+
|
|
|
+ f, err := writer.Create(relativePath)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err = io.Copy(f, file)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- if info.IsDir() {
|
|
|
- return nil
|
|
|
+ } else {
|
|
|
+ //This is a file
|
|
|
+ topLevelFolderName := filepath.Base(filepath.Dir(srcpath))
|
|
|
+ file, err := os.Open(srcpath)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer file.Close()
|
|
|
+ relativePath := filepath.Base(srcpath)
|
|
|
+ if includeTopLevelFolder {
|
|
|
+ relativePath = topLevelFolderName + "/" + relativePath
|
|
|
+ }
|
|
|
+ f, err := writer.Create(relativePath)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
|
|
|
- if insideHiddenFolder(path) == true {
|
|
|
- //This is hidden file / folder. Skip this
|
|
|
+ _, err = io.Copy(f, file)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //Use file system abstraction
|
|
|
+ fshAbs = thisFsh.FileSystemAbstraction
|
|
|
+ if fshAbs.IsDir(srcpath) {
|
|
|
+ //This is a directory
|
|
|
+ topLevelFolderName := filepath.ToSlash(filepath.Base(filepath.Dir(srcpath)) + "/" + filepath.Base(srcpath))
|
|
|
+ err = fshAbs.Walk(srcpath, func(path string, info os.FileInfo, err error) error {
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ if info.IsDir() {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ if insideHiddenFolder(path) {
|
|
|
+ //This is hidden file / folder. Skip this
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ file, err := fshAbs.ReadStream(path)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(err)
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ defer file.Close()
|
|
|
+
|
|
|
+ relativePath := strings.ReplaceAll(filepath.ToSlash(path), filepath.ToSlash(filepath.Clean(srcpath))+"/", "")
|
|
|
+ if includeTopLevelFolder {
|
|
|
+ relativePath = topLevelFolderName + "/" + relativePath
|
|
|
+ } else {
|
|
|
+ relativePath = filepath.Base(srcpath) + "/" + relativePath
|
|
|
+ }
|
|
|
+
|
|
|
+ f, err := writer.Create(relativePath)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
+ _, err = io.Copy(f, file)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+
|
|
|
return nil
|
|
|
+ })
|
|
|
+
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
- file, err := os.Open(path)
|
|
|
+ } else {
|
|
|
+ //This is a file
|
|
|
+ topLevelFolderName := filepath.Base(filepath.Dir(srcpath))
|
|
|
+ file, err := fshAbs.ReadStream(srcpath)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
defer file.Close()
|
|
|
-
|
|
|
- relativePath := strings.ReplaceAll(filepath.ToSlash(path), filepath.ToSlash(filepath.Clean(srcpath))+"/", "")
|
|
|
+ relativePath := filepath.Base(srcpath)
|
|
|
if includeTopLevelFolder {
|
|
|
relativePath = topLevelFolderName + "/" + relativePath
|
|
|
- } else {
|
|
|
- relativePath = filepath.Base(srcpath) + "/" + relativePath
|
|
|
}
|
|
|
-
|
|
|
f, err := writer.Create(relativePath)
|
|
|
if err != nil {
|
|
|
return err
|
|
@@ -321,34 +458,7 @@ func ArozZipFile(filelist []string, outputfile string, includeTopLevelFolder boo
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- return nil
|
|
|
- })
|
|
|
-
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- } else {
|
|
|
- //This is a file
|
|
|
- topLevelFolderName := filepath.Base(filepath.Dir(srcpath))
|
|
|
- file, err := os.Open(srcpath)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- defer file.Close()
|
|
|
- relativePath := filepath.Base(srcpath)
|
|
|
- if includeTopLevelFolder {
|
|
|
- relativePath = topLevelFolderName + "/" + relativePath
|
|
|
- }
|
|
|
- f, err := writer.Create(relativePath)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- _, err = io.Copy(f, file)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -682,6 +792,8 @@ func BasicFileCopy(src string, dst string) error {
|
|
|
}
|
|
|
|
|
|
//Use for copying large file using buffering method. Allowing copying large file with little RAM
|
|
|
+//Deprecated Since ArozOS v2.000
|
|
|
+/*
|
|
|
func BufferedLargeFileCopy(src string, dst string, BUFFERSIZE int64) error {
|
|
|
sourceFileStat, err := os.Stat(src)
|
|
|
if err != nil {
|
|
@@ -724,9 +836,11 @@ func BufferedLargeFileCopy(src string, dst string, BUFFERSIZE int64) error {
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
+*/
|
|
|
|
|
|
+//Check if a local path is dir, do not use with file system abstraction realpath
|
|
|
func IsDir(path string) bool {
|
|
|
- if FileExists(path) == false {
|
|
|
+ if !FileExists(path) {
|
|
|
return false
|
|
|
}
|
|
|
fi, err := os.Stat(path)
|
|
@@ -743,7 +857,7 @@ func IsDir(path string) bool {
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
-//Unzip tar.gz file
|
|
|
+//Unzip tar.gz file, use for unpacking web.tar.gz for lazy people
|
|
|
func ExtractTarGzipFile(filename string, outfile string) error {
|
|
|
f, err := os.Open(filename)
|
|
|
if err != nil {
|