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") // --- Получаем zip-файл --- tempFile, err := os.CreateTemp("", "modpack-*.zip") if err != nil { http.Error(w, "Could not create temp file", http.StatusInternalServerError) return } defer os.Remove(tempFile.Name()) defer tempFile.Close() if importMethod == "file" { file, _, err := r.FormFile("file") if err != nil { http.Error(w, "Invalid file upload", http.StatusBadRequest) return } defer file.Close() if _, err := io.Copy(tempFile, file); err != nil { http.Error(w, "Could not save temp file", http.StatusInternalServerError) return } } else if importMethod == "url" { http.Error(w, "Import by URL is not implemented yet", http.StatusNotImplemented) return } else { http.Error(w, "Invalid import method", http.StatusBadRequest) return } // --- Выбираем и запускаем импортер --- 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 } files, err := imp.Import(tempFile.Name()) 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()) }