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) case "modrinth": imp = importer.NewModrinthImporter(storagePath) 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()) }