package filemdl import ( "archive/zip" "io" "io/ioutil" "os" "path" "path/filepath" "strings" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/errormdl" "corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/loggermdl" // "github.com/DataDog/zstd" "github.com/klauspost/compress/zstd" ) var encoder, _ = zstd.NewWriter(nil) var decoder, _ = zstd.NewReader(nil) //Zip - Zip func Zip(source, target string) error { source = filepath.Clean(source) target = filepath.Clean(target) zipfile, err := os.Create(target) if err != nil { return err } defer zipfile.Close() archive := zip.NewWriter(zipfile) defer archive.Close() info, err := os.Stat(source) if err != nil { return err } var baseDir string if info.IsDir() { baseDir = filepath.Base(source) } filepath.Walk(source, func(path string, info os.FileInfo, err error) error { if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } header, err := zip.FileInfoHeader(info) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } if baseDir != "" { header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source)) // Replace all occurances of \\ with /. This is necessary to properly unzip the zip file created on windows system on ubuntu system header.Name = strings.Replace(header.Name, "\\", "/", -1) } if info.IsDir() { header.Name += "/" } else { header.Method = zip.Deflate } writer, err := archive.CreateHeader(header) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } if info.IsDir() { return nil } file, err := os.Open(path) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } _, err = io.Copy(writer, file) if errormdl.CheckErr(err) != nil { } file.Close() return errormdl.CheckErr(err) }) return errormdl.CheckErr(err) } //ZipWithoutBaseDirectory Zip Without Base Directory func ZipWithoutBaseDirectory(source, target string) error { source = filepath.Clean(source) target = filepath.Clean(target) zipfile, err := os.Create(target) if err != nil { return err } defer zipfile.Close() archive := zip.NewWriter(zipfile) defer archive.Close() info, err := os.Stat(source) if err != nil { return err } var baseDir string if info.IsDir() { baseDir = filepath.Base(source) } filepath.Walk(source, func(path string, info os.FileInfo, err error) error { if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } header, err := zip.FileInfoHeader(info) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } if baseDir != "" { header.Name = strings.TrimPrefix(path, source) // Replace all occurances of \\ with /. This is necessary to properly unzip the zip file created on windows system on ubuntu system header.Name = strings.Replace(header.Name, "\\", "/", -1) } if info.IsDir() { header.Name += "/" } else { header.Method = zip.Deflate } writer, err := archive.CreateHeader(header) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } if info.IsDir() { return nil } file, err := os.Open(path) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } _, err = io.Copy(writer, file) if errormdl.CheckErr(err) != nil { } file.Close() return errormdl.CheckErr(err) }) return errormdl.CheckErr(err) } //ZipWithSkipFileList This method will skip the file added in skiplist from zip func ZipWithSkipFileList(source, target string, skipFileList []string) error { source = filepath.Clean(source) target = filepath.Clean(target) zipfile, err := os.Create(target) if err != nil { return err } defer zipfile.Close() archive := zip.NewWriter(zipfile) defer archive.Close() info, err := os.Stat(source) if err != nil { return err } var baseDir string if info.IsDir() { baseDir = filepath.Base(source) } filepath.Walk(source, func(path string, info os.FileInfo, err error) error { if !checkPathInSkipList(info.Name(), skipFileList) { header, err := zip.FileInfoHeader(info) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } if baseDir != "" { header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source)) // Replace all occurances of \\ with /. This is necessary to properly unzip the zip file created on windows system on ubuntu system header.Name = strings.Replace(header.Name, "\\", "/", -1) } if info.IsDir() { header.Name += "/" } else { header.Method = zip.Deflate } writer, err := archive.CreateHeader(header) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } if info.IsDir() { return nil } file, err := os.Open(path) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } _, err = io.Copy(writer, file) if err != nil { } file.Close() return nil } return nil }) return errormdl.CheckErr(err) } func checkPathInSkipList(path string, skipList []string) bool { for _, prefix := range skipList { if strings.HasPrefix(path, prefix) { return true } if strings.HasSuffix(path, prefix) { return true } } return false } //Unzip Unzip func Unzip(archive, target string) error { reader, err := zip.OpenReader(archive) if err != nil { loggermdl.LogError(err) return err } mkcDirError := os.MkdirAll(target, 0755) if errormdl.CheckErr(mkcDirError) != nil { loggermdl.LogError(errormdl.CheckErr(mkcDirError)) return errormdl.CheckErr(mkcDirError) } for _, file := range reader.File { filePath := filepath.Join(target, file.Name) parentPath := path.Dir(CleanPath(filePath)) if !FileAvailabilityCheck(parentPath) { CreateDirectoryRecursive(parentPath) } if file.FileInfo().IsDir() { os.MkdirAll(filePath, file.Mode()) continue } fileReader, openError := file.Open() if errormdl.CheckErr(openError) != nil { loggermdl.LogError(errormdl.CheckErr(openError)) return errormdl.CheckErr(openError) } targetFile, targetOpenError := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode()) if errormdl.CheckErr(targetOpenError) != nil { loggermdl.LogError(errormdl.CheckErr(targetOpenError)) return errormdl.CheckErr(targetOpenError) } _, copyError := io.Copy(targetFile, fileReader) if errormdl.CheckErr(copyError) != nil { loggermdl.LogError(errormdl.CheckErr(copyError)) return errormdl.CheckErr(copyError) } targetCloseError := targetFile.Close() if errormdl.CheckErr(targetCloseError) != nil { loggermdl.LogError(errormdl.CheckErr(targetCloseError)) return errormdl.CheckErr(targetCloseError) } fileCloseError := fileReader.Close() if errormdl.CheckErr(fileCloseError) != nil { loggermdl.LogError(errormdl.CheckErr(fileCloseError)) return errormdl.CheckErr(fileCloseError) } } closeError := reader.Close() if errormdl.CheckErr(closeError) != nil { loggermdl.LogError(errormdl.CheckErr(closeError)) return errormdl.CheckErr(closeError) } return nil } //ZipBytes - zip byte array func ZipBytes(inputData []byte) ([]byte, error) { // compressedData, err := zstd.CompressLevel(nil, inputData, 9) compressedData := encoder.EncodeAll(inputData, make([]byte, 0, len(inputData))) return compressedData, nil } // ZipSingleFile - Zip single file func ZipSingleFile(sourceFilePath, destFilePath string) error { inputData, err := ioutil.ReadFile(sourceFilePath) if err != nil { return err } compressedData, err := ZipBytes(inputData) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } err = ioutil.WriteFile(destFilePath, compressedData, 0644) if err != nil { return err } return nil } //UnZipBytes bytes - Decompress func UnZipBytes(compressedData []byte) ([]byte, error) { // decompressedData, err := zstd.Decompress(nil, compressedData) decompressedData, err := decoder.DecodeAll(compressedData, nil) return decompressedData, errormdl.CheckErr(err) } // UnZipSingleFile - UnZip Single File func UnZipSingleFile(sourceFilePath, destFilePath string) error { inputData, err := ioutil.ReadFile(sourceFilePath) if err != nil { return err } uncompressedData, err := UnZipBytes(inputData) if errormdl.CheckErr(err) != nil { return errormdl.CheckErr(err) } err = ioutil.WriteFile(destFilePath, uncompressedData, 0644) if err != nil { return err } return nil }