Files
AetherForge/server/internal/builder/fusion_zip.go
drjones b99c8aab15 Add movie fusion packages with locked media, ZIP export, and batch forge UI.
Paired video mode encrypts movies, uses runner-only lock hints, bundles README plus artifacts per title, and supports batch forging with progress.
2026-05-29 01:33:09 -07:00

72 lines
1.3 KiB
Go

package builder
import (
"archive/zip"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)
func zipDirectory(sourceDir, zipPath string) error {
sourceDir, err := filepath.Abs(sourceDir)
if err != nil {
return err
}
zipPath, err = filepath.Abs(zipPath)
if err != nil {
return err
}
if strings.HasPrefix(zipPath, sourceDir+string(os.PathSeparator)) || zipPath == sourceDir {
return fmt.Errorf("zip path must be outside source directory")
}
out, err := os.Create(zipPath)
if err != nil {
return err
}
defer out.Close()
zw := zip.NewWriter(out)
defer zw.Close()
return filepath.Walk(sourceDir, func(path string, info os.FileInfo, walkErr error) error {
if walkErr != nil {
return walkErr
}
if info.IsDir() {
return nil
}
if strings.EqualFold(filepath.Ext(path), ".zip") {
return nil
}
rel, err := filepath.Rel(sourceDir, path)
if err != nil {
return err
}
rel = filepath.ToSlash(rel)
hdr, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
hdr.Name = rel
hdr.Method = zip.Deflate
w, err := zw.CreateHeader(hdr)
if err != nil {
return err
}
in, err := os.Open(path)
if err != nil {
return err
}
_, err = io.Copy(w, in)
in.Close()
return err
})
}
func fusionBundleZipName(subdir string) string {
return sanitizeFileName(subdir) + "-package.zip"
}