Files
forever-files/fileUtilities/zip.go
2023-07-18 18:21:12 -06:00

87 lines
2.0 KiB
Go

package fileUtilities
import (
"archive/zip"
"fmt"
"forever-files/types"
"io"
"os"
"path"
"strings"
)
func CreateZip(fileName, outDir, baseDir string, partition []types.FileMetadata) error {
// Create a buffer to write our archive to.
outFile := path.Join(outDir, fileName+".zip")
zipFile, err := os.OpenFile(outFile, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("error opening/creating zip file: %w", err)
}
// Create a new zip archive.
w := zip.NewWriter(zipFile)
files := prepFiles(baseDir, partition)
for _, file := range files {
zf, err := w.Create(file.Name)
if err != nil {
return fmt.Errorf("error creating zip file: %w", err)
}
f, err := os.Open(file.Path)
if err != nil {
fmt.Println(fmt.Sprintf("error opening file: %v", err))
fmt.Println(fmt.Sprintf("skipping file: %v", file.Path))
continue
}
if _, err := io.Copy(zf, f); err != nil {
return fmt.Errorf("error copying file to zip file: %w", err)
}
err = f.Close()
if err != nil {
return fmt.Errorf("error closing file: %w", err)
}
}
// Make sure to check the error on Close.
err = w.Close()
if err != nil {
return fmt.Errorf("error closing zip file: %w", err)
}
err = zipFile.Close()
if err != nil {
return fmt.Errorf("error closing zip file: %w", err)
}
return nil
}
func prepFiles(baseDir string, partition []types.FileMetadata) []struct {
Name, Path string
} {
var files []struct {
Name, Path string
}
for _, file := range partition {
filePath := path.Join(file.Path, file.Name)
// from zip.Create documentation:
// ...The name must be a relative path: it must not start with a
// drive letter (e.g. C:) or leading slash, and only forward slashes
// are allowed...
fileName := strings.Replace(replaceBackslashes(strings.Replace(filePath, baseDir, "", 1)), "/", "", 1)
files = append(files, struct {
Name, Path string
}{
Name: fileName,
Path: filePath,
})
}
return files
}
func replaceBackslashes(input string) string {
return strings.ReplaceAll(input, "\\", "/")
}