mirror of https://github.com/go-sonic/sonic.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.5 KiB
Go
88 lines
2.5 KiB
Go
package theme
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"mime/multipart"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"go.uber.org/fx"
|
|
|
|
"github.com/go-sonic/sonic/model/dto"
|
|
"github.com/go-sonic/sonic/util"
|
|
"github.com/go-sonic/sonic/util/xerr"
|
|
)
|
|
|
|
type multipartZipThemeFetcherImpl struct {
|
|
fx.Out
|
|
PropertyScanner PropertyScanner
|
|
}
|
|
|
|
func NewMultipartZipThemeFetcher(propertyScanner PropertyScanner) ThemeFetcher {
|
|
return &multipartZipThemeFetcherImpl{
|
|
PropertyScanner: propertyScanner,
|
|
}
|
|
}
|
|
|
|
func (m *multipartZipThemeFetcherImpl) FetchTheme(ctx context.Context, file interface{}) (*dto.ThemeProperty, error) {
|
|
themeFileHeader, ok := file.(*multipart.FileHeader)
|
|
if !ok {
|
|
return nil, xerr.WithStatus(nil, xerr.StatusBadRequest).WithMsg("not support")
|
|
}
|
|
|
|
tempDir := os.TempDir()
|
|
srcThemeFile, err := themeFileHeader.Open()
|
|
if err != nil {
|
|
return nil, xerr.WithStatus(err, xerr.StatusBadRequest).WithMsg("upload theme file error")
|
|
}
|
|
defer srcThemeFile.Close()
|
|
|
|
fileName := themeFileHeader.Filename
|
|
if !strings.HasSuffix(fileName, ".zip") {
|
|
return nil, xerr.WithStatus(nil, xerr.StatusBadRequest).WithMsg("not zip file")
|
|
}
|
|
|
|
diskFilePath := filepath.Join(tempDir, fileName)
|
|
if util.FileIsExisted(diskFilePath) {
|
|
err = os.Remove(diskFilePath)
|
|
if err != nil {
|
|
return nil, xerr.WithStatus(err, xerr.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
diskFile, err := os.OpenFile(diskFilePath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o444)
|
|
if err != nil && !errors.Is(err, os.ErrExist) {
|
|
return nil, xerr.WithStatus(err, xerr.StatusInternalServerError).WithMsg("create file error")
|
|
}
|
|
|
|
defer diskFile.Close()
|
|
|
|
_, err = io.Copy(diskFile, srcThemeFile)
|
|
if err != nil {
|
|
return nil, xerr.WithStatus(err, xerr.StatusInternalServerError).WithMsg("save file error")
|
|
}
|
|
_, err = util.Unzip(filepath.Join(tempDir, fileName), filepath.Join(tempDir, strings.TrimSuffix(fileName, ".zip")))
|
|
if err != nil {
|
|
return nil, xerr.WithStatus(err, xerr.StatusInternalServerError).WithMsg("unzip file error")
|
|
}
|
|
dest := filepath.Join(tempDir, strings.TrimSuffix(fileName, ".zip"))
|
|
themeProperty, err := m.PropertyScanner.ReadThemeProperty(ctx, dest)
|
|
if err == nil && themeProperty != nil {
|
|
return themeProperty, nil
|
|
}
|
|
dirEntrys, err := os.ReadDir(dest)
|
|
for _, dirEntry := range dirEntrys {
|
|
if !dirEntry.IsDir() {
|
|
continue
|
|
}
|
|
themeProperty, err = m.PropertyScanner.ReadThemeProperty(ctx, filepath.Join(dest, dirEntry.Name()))
|
|
if err == nil && themeProperty != nil {
|
|
return themeProperty, nil
|
|
}
|
|
}
|
|
return nil, err
|
|
}
|