120 lines
3.4 KiB
Go
120 lines
3.4 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
|
|
"gitea.mrixs.me/minecraft-platform/backend/internal/core"
|
|
"gitea.mrixs.me/minecraft-platform/backend/internal/core/importer"
|
|
"gitea.mrixs.me/minecraft-platform/backend/internal/database"
|
|
"gitea.mrixs.me/minecraft-platform/backend/internal/models"
|
|
)
|
|
|
|
type ModpackHandler struct {
|
|
ModpackRepo *database.ModpackRepository
|
|
JanitorService *core.FileJanitorService
|
|
}
|
|
|
|
// ImportModpack обрабатывает загрузку и импорт модпака.
|
|
func (h *ModpackHandler) ImportModpack(w http.ResponseWriter, r *http.Request) {
|
|
if err := r.ParseMultipartForm(512 << 20); err != nil {
|
|
http.Error(w, "File too large", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
importerType := r.FormValue("importerType")
|
|
importMethod := r.FormValue("importMethod")
|
|
sourceURL := r.FormValue("sourceUrl")
|
|
|
|
var tempZipPath string
|
|
var err error
|
|
|
|
// --- Выбираем импортер ---
|
|
var imp importer.ModpackImporter
|
|
storagePath := os.Getenv("MODPACKS_STORAGE_PATH")
|
|
|
|
switch importerType {
|
|
case "simple":
|
|
imp = &importer.SimpleZipImporter{StoragePath: storagePath}
|
|
case "curseforge":
|
|
apiKey := os.Getenv("CURSEFORGE_API_KEY")
|
|
if apiKey == "" {
|
|
http.Error(w, "CurseForge API key is not configured on the server", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
imp = importer.NewCurseForgeImporter(storagePath, apiKey)
|
|
default:
|
|
http.Error(w, "Invalid importer type", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// --- Получаем zip-файл ---
|
|
if importMethod == "file" {
|
|
file, _, err := r.FormFile("file")
|
|
if err != nil {
|
|
http.Error(w, "Invalid file upload", http.StatusBadRequest)
|
|
return
|
|
}
|
|
defer file.Close()
|
|
|
|
tempFile, err := os.CreateTemp("", "modpack-*.zip")
|
|
if err != nil {
|
|
http.Error(w, "Could not create temp file", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
defer tempFile.Close()
|
|
defer os.Remove(tempFile.Name())
|
|
|
|
if _, err := io.Copy(tempFile, file); err != nil {
|
|
http.Error(w, "Could not save temp file", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
tempZipPath = tempFile.Name()
|
|
|
|
} else if importMethod == "url" {
|
|
cfImporter, ok := imp.(*importer.CurseForgeImporter)
|
|
if !ok {
|
|
http.Error(w, "Importer type does not support URL import", http.StatusBadRequest)
|
|
return
|
|
}
|
|
tempZipPath, err = cfImporter.DownloadModpackFromURL(sourceURL)
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Failed to download from URL: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
defer os.Remove(tempZipPath)
|
|
|
|
} else {
|
|
http.Error(w, "Invalid import method", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// --- Запускаем импорт ---
|
|
files, err := imp.Import(tempZipPath)
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Import failed: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
// --- Сохраняем результат в БД ---
|
|
modpack := &models.Modpack{
|
|
Name: r.FormValue("name"),
|
|
DisplayName: r.FormValue("displayName"),
|
|
MinecraftVersion: r.FormValue("mcVersion"),
|
|
}
|
|
|
|
err = h.ModpackRepo.CreateModpackTx(r.Context(), modpack, files)
|
|
if err != nil {
|
|
http.Error(w, fmt.Sprintf("Database save failed: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
w.WriteHeader(http.StatusCreated)
|
|
fmt.Fprintf(w, "Modpack '%s' imported successfully with %d files.", modpack.DisplayName, len(files))
|
|
|
|
go h.JanitorService.CleanOrphanedFiles(context.Background())
|
|
}
|