196 lines
5.0 KiB
Go
196 lines
5.0 KiB
Go
package domain
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bufio"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
type FileRepositoryInterface interface {
|
|
FileExists(fileName, basePath string) bool
|
|
CreateDir(dirPath string) error
|
|
DeleteFile(fileName, basePath string) error
|
|
MoveFile(srcFileName, destPath, basePath string) error
|
|
UnzipHTMLContent(zipFilePath, softwareName, version, basePath string) error
|
|
GetSoftwareDir(softwareName, basePath string) string
|
|
GetSoftwareVersionDir(softwareName, version, basePath string) string
|
|
GetFileInSoftwareVersionDir(softwareName, version, fileName, basePath string) string
|
|
GetHTMLContentDir(softwareName, version, basePath string) string
|
|
GetCartridgePath(softwareName, version, basePath string) string
|
|
GetSourcePath(softwareName, version, basePath string) string
|
|
ReadMetaFromFile(filePath string, basePath string) (map[string]string, error)
|
|
}
|
|
|
|
type FileRepository struct{}
|
|
|
|
func NewFileRepository() *FileRepository {
|
|
return &FileRepository{}
|
|
}
|
|
|
|
func (r *FileRepository) FileExists(fileName, basePath string) bool {
|
|
var filePath string
|
|
if filepath.IsAbs(fileName) {
|
|
filePath = fileName
|
|
} else if basePath != "" {
|
|
filePath = filepath.Join(basePath, fileName)
|
|
} else {
|
|
filePath = fileName // Assume it's relative to current working dir or absolute
|
|
}
|
|
|
|
_, err := os.Stat(filePath)
|
|
return err == nil
|
|
}
|
|
|
|
func (r *FileRepository) CreateDir(dirPath string) error {
|
|
return os.MkdirAll(dirPath, os.ModePerm)
|
|
}
|
|
|
|
func (r *FileRepository) DeleteFile(fileName, basePath string) error {
|
|
var filePath string
|
|
if filepath.IsAbs(fileName) {
|
|
filePath = fileName
|
|
} else if basePath != "" {
|
|
filePath = filepath.Join(basePath, fileName)
|
|
} else {
|
|
filePath = fileName
|
|
}
|
|
return os.Remove(filePath)
|
|
}
|
|
|
|
func (r *FileRepository) MoveFile(srcFileName, destPath, basePath string) error {
|
|
var srcPath string
|
|
if filepath.IsAbs(srcFileName) {
|
|
srcPath = srcFileName
|
|
} else if basePath != "" {
|
|
srcPath = filepath.Join(basePath, srcFileName)
|
|
} else {
|
|
srcPath = srcFileName
|
|
}
|
|
return os.Rename(srcPath, destPath)
|
|
}
|
|
|
|
func (r *FileRepository) UnzipHTMLContent(zipFilePath, softwareName, version, basePath string) error {
|
|
destDir := r.GetHTMLContentDir(softwareName, version, basePath)
|
|
|
|
fmt.Printf("FileRepository: Unzipping %s to %s\n", zipFilePath, destDir)
|
|
|
|
reader, err := zip.OpenReader(zipFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer reader.Close()
|
|
|
|
destDir, err = filepath.Abs(destDir)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, f := range reader.File {
|
|
fpath := filepath.Join(destDir, f.Name)
|
|
|
|
if !strings.HasPrefix(fpath, destDir) {
|
|
return fmt.Errorf("%s: illegal file path", fpath)
|
|
}
|
|
|
|
if f.FileInfo().IsDir() {
|
|
os.MkdirAll(fpath, os.ModePerm)
|
|
continue
|
|
}
|
|
|
|
if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil {
|
|
return err
|
|
}
|
|
|
|
outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
|
if err != nil {
|
|
outFile.Close()
|
|
return err
|
|
}
|
|
|
|
rc, err := f.Open()
|
|
if err != nil {
|
|
outFile.Close()
|
|
return err
|
|
}
|
|
|
|
_, err = io.Copy(outFile, rc)
|
|
outFile.Close()
|
|
rc.Close()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *FileRepository) GetSoftwareDir(softwareName, basePath string) string {
|
|
return filepath.Join(basePath, softwareName)
|
|
}
|
|
|
|
func (r *FileRepository) GetSoftwareVersionDir(softwareName, version, basePath string) string {
|
|
return filepath.Join(r.GetSoftwareDir(softwareName, basePath), version)
|
|
}
|
|
|
|
func (r *FileRepository) GetFileInSoftwareVersionDir(softwareName, version, fileName, basePath string) string {
|
|
return filepath.Join(r.GetSoftwareVersionDir(softwareName, version, basePath), fileName)
|
|
}
|
|
|
|
func (r *FileRepository) GetHTMLContentDir(softwareName, version, basePath string) string {
|
|
return filepath.Join(r.GetSoftwareVersionDir(softwareName, version, basePath), "html")
|
|
}
|
|
|
|
func (r *FileRepository) GetCartridgePath(softwareName, version, basePath string) string {
|
|
return filepath.Join(r.GetSoftwareVersionDir(softwareName, version, basePath), fmt.Sprintf("%s.tic", softwareName))
|
|
}
|
|
|
|
func (r *FileRepository) GetSourcePath(softwareName, version, basePath string) string {
|
|
return filepath.Join(r.GetSoftwareVersionDir(softwareName, version, basePath), fmt.Sprintf("%s.lua", softwareName))
|
|
}
|
|
|
|
func (r *FileRepository) ReadMetaFromFile(filePath string, basePath string) (map[string]string, error) {
|
|
var fullPath string
|
|
if filepath.IsAbs(filePath) {
|
|
fullPath = filePath
|
|
} else if basePath != "" {
|
|
fullPath = filepath.Join(basePath, filePath)
|
|
} else {
|
|
fullPath = filePath
|
|
}
|
|
|
|
file, err := os.Open(fullPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer file.Close()
|
|
|
|
metaData := make(map[string]string)
|
|
scanner := bufio.NewScanner(file)
|
|
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if strings.HasPrefix(line, "--") {
|
|
parts := strings.SplitN(strings.TrimPrefix(line, "--"), ":", 2)
|
|
if len(parts) != 2 {
|
|
continue
|
|
}
|
|
key := strings.TrimSpace(parts[0])
|
|
val := strings.TrimSpace(parts[1])
|
|
metaData[strings.ToLower(key)] = val
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return metaData, nil
|
|
}
|