2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 06:47:20 +08:00
Files
panel/pkg/io/compress.go
2025-02-04 20:40:47 +08:00

141 lines
3.1 KiB
Go

package io
import (
"errors"
"os"
"path/filepath"
"strings"
"github.com/tnb-labs/panel/pkg/shell"
)
type FormatArchive string
const (
Zip FormatArchive = "zip"
Bz2 FormatArchive = "bz2"
Tar FormatArchive = "tar"
TGz FormatArchive = "tgz"
Xz FormatArchive = "xz"
SevenZip FormatArchive = "7z"
)
// Compress 压缩文件
func Compress(dir string, src []string, dst string) error {
if !filepath.IsAbs(dir) || !filepath.IsAbs(dst) {
return errors.New("dir and dst must be absolute path")
}
if len(src) == 0 {
src = append(src, ".")
}
format, err := formatArchiveByPath(dst)
if err != nil {
return err
}
switch format {
case Zip:
_, err = shell.ExecfWithDir(dir, "zip -qr -o %s %s", dst, strings.Join(src, " "))
case TGz:
_, err = shell.ExecfWithDir(dir, "tar -czf %s %s", dst, strings.Join(src, " "))
case Bz2:
_, err = shell.ExecfWithDir(dir, "tar -cjf %s %s", dst, strings.Join(src, " "))
case Tar:
_, err = shell.ExecfWithDir(dir, "tar -cf %s %s", dst, strings.Join(src, " "))
case Xz:
_, err = shell.ExecfWithDir(dir, "tar -cJf %s %s", dst, strings.Join(src, " "))
case SevenZip:
_, err = shell.ExecfWithDir(dir, "7z a -y %s %s", dst, strings.Join(src, " "))
default:
return errors.New("unsupported format")
}
return err
}
// UnCompress 解压文件
func UnCompress(src string, dst string) error {
if !filepath.IsAbs(src) || !filepath.IsAbs(dst) {
return errors.New("src and dst must be absolute path")
}
if !Exists(dst) {
if err := os.MkdirAll(dst, 0755); err != nil {
return err
}
}
format, err := formatArchiveByPath(src)
if err != nil {
return err
}
switch format {
case Zip:
_, err = shell.Execf("unzip -qo '%s' -d '%s'", src, dst)
case TGz:
_, err = shell.Execf("tar -xzf '%s' -C '%s'", src, dst)
case Bz2:
_, err = shell.Execf("tar -xjf '%s' -C '%s'", src, dst)
case Tar:
_, err = shell.Execf("tar -xf '%s' -C '%s'", src, dst)
case Xz:
_, err = shell.Execf("tar -xJf '%s' -C '%s'", src, dst)
case SevenZip:
_, err = shell.Execf("7z x -y '%s' -o'%s'", src, dst)
default:
return errors.New("unsupported format")
}
return err
}
// ListCompress 获取压缩包内文件列表
func ListCompress(src string) ([]string, error) {
format, err := formatArchiveByPath(src)
if err != nil {
return nil, err
}
var out string
switch format {
case Zip:
out, err = shell.Execf("unzip -Z1 '%s'", src)
case TGz, Bz2, Tar, Xz:
out, err = shell.Execf("tar -tf '%s'", src)
case SevenZip:
out, err = shell.Execf(`7z l -ba -slt '%s' | grep "^Path = " | sed 's/^Path = //'`, src)
default:
return nil, errors.New("unsupported format")
}
if err != nil {
return nil, err
}
return strings.Split(out, "\n"), nil
}
// formatArchiveByPath 根据文件后缀获取压缩格式
func formatArchiveByPath(path string) (FormatArchive, error) {
switch filepath.Ext(path) {
case ".zip":
return Zip, nil
case ".bz2":
return Bz2, nil
case ".tar":
return Tar, nil
case ".tgz":
return TGz, nil
case ".gz":
if strings.HasSuffix(path, ".tar.gz") {
return TGz, nil
}
case ".xz":
return Xz, nil
case ".7z":
return SevenZip, nil
}
return "", errors.New("unknown format")
}