feat(modpacks): implement simple zip importer and API
This commit is contained in:
9
internal/core/importer/importer.go
Normal file
9
internal/core/importer/importer.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package importer
|
||||
|
||||
import "gitea.mrixs.me/minecraft-platform/backend/internal/models"
|
||||
|
||||
// ModpackImporter определяет контракт для всех типов импортеров.
|
||||
// Он принимает путь к временному zip-файлу и возвращает список файлов модпака.
|
||||
type ModpackImporter interface {
|
||||
Import(zipPath string) ([]models.ModpackFile, error)
|
||||
}
|
||||
78
internal/core/importer/simple_zip.go
Normal file
78
internal/core/importer/simple_zip.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package importer
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"gitea.mrixs.me/minecraft-platform/backend/internal/models"
|
||||
)
|
||||
|
||||
// SimpleZipImporter реализует интерфейс ModpackImporter для простых zip-архивов.
|
||||
type SimpleZipImporter struct {
|
||||
StoragePath string // Путь к хранилищу файлов модпаков
|
||||
}
|
||||
|
||||
// processFile - это наша "общая конвейерная лента".
|
||||
// Он читает файл, вычисляет хеш, сохраняет его на диск и возвращает метаданные.
|
||||
func (i *SimpleZipImporter) processFile(reader io.Reader) (hash string, size int64, err error) {
|
||||
data, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return "", 0, err
|
||||
}
|
||||
|
||||
hasher := sha1.New()
|
||||
hasher.Write(data)
|
||||
hash = hex.EncodeToString(hasher.Sum(nil))
|
||||
size = int64(len(data))
|
||||
|
||||
filePath := filepath.Join(i.StoragePath, hash)
|
||||
|
||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||
if err := os.WriteFile(filePath, data, 0644); err != nil {
|
||||
return "", 0, fmt.Errorf("failed to save file %s: %w", hash, err)
|
||||
}
|
||||
}
|
||||
|
||||
return hash, size, nil
|
||||
}
|
||||
|
||||
// Import реализует основной метод интерфейса.
|
||||
func (i *SimpleZipImporter) Import(zipPath string) ([]models.ModpackFile, error) {
|
||||
r, err := zip.OpenReader(zipPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
var files []models.ModpackFile
|
||||
|
||||
for _, f := range r.File {
|
||||
if f.FileInfo().IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
fileReader, err := f.Open()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open file in zip %s: %w", f.Name, err)
|
||||
}
|
||||
defer fileReader.Close()
|
||||
|
||||
hash, size, err := i.processFile(fileReader)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to process file %s: %w", f.Name, err)
|
||||
}
|
||||
|
||||
files = append(files, models.ModpackFile{
|
||||
RelativePath: f.Name,
|
||||
FileHash: hash,
|
||||
FileSize: size,
|
||||
})
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
Reference in New Issue
Block a user