package main import ( "encoding/json" "fmt" "io" "net/http" "os" "path/filepath" ) func handleRoot(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } progressMutex.Lock() jobs := make(map[string]*ProgressInfo) for k, v := range progress { jobs[k] = v } progressMutex.Unlock() err := templates.ExecuteTemplate(w, "index", struct{ Jobs map[string]*ProgressInfo }{jobs}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func handleUpload(w http.ResponseWriter, r *http.Request) { file, header, err := r.FormFile("file") if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } defer file.Close() tempFile, err := os.CreateTemp(uploadDir, header.Filename) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer tempFile.Close() _, err = io.Copy(tempFile, file) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } tempFilename := filepath.Base(tempFile.Name()) _, err = parseInputFile(tempFile.Name()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } http.Redirect(w, r, "/select?filename="+tempFilename, http.StatusSeeOther) } func handleSelect(w http.ResponseWriter, r *http.Request) { filename := r.URL.Query().Get("filename") items, err := parseInputFile(filepath.Join(uploadDir, filename)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } groupedItems := groupItemsBySeason(items) err = templates.ExecuteTemplate(w, "select", struct { Filename string Items map[string][]Item }{ Filename: filename, Items: groupedItems, }) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func handleProcess(w http.ResponseWriter, r *http.Request) { filename := r.FormValue("filename") selectedItems := r.Form["items"] items, err := parseInputFile(filepath.Join(uploadDir, filename)) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } filteredItems := filterSelectedItems(items, selectedItems) go func() { err := processItems(filename, filteredItems) if err != nil { fmt.Printf("Error processing file: %v\n", err) } os.Remove(filepath.Join(uploadDir, filename)) }() http.Redirect(w, r, "/progress?filename="+filename, http.StatusSeeOther) } func handleProgress(w http.ResponseWriter, r *http.Request) { filename := r.URL.Query().Get("filename") fmt.Printf("Handling progress request for filename: %s\n", filename) if r.Header.Get("Accept") == "application/json" { progressInfo := getProgress(filename) fmt.Printf("Progress info for %s: %+v\n", filename, progressInfo) if progressInfo == nil { w.WriteHeader(http.StatusNotFound) json.NewEncoder(w).Encode(map[string]string{"error": "No progress information found"}) return } w.Header().Set("Content-Type", "application/json") err := json.NewEncoder(w).Encode(progressInfo) if err != nil { fmt.Printf("Error encoding progress info: %v\n", err) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } return } err := templates.ExecuteTemplate(w, "progress", struct{ Filename string }{filename}) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } func handlePause(w http.ResponseWriter, r *http.Request) { filename := r.URL.Query().Get("filename") if filename == "" { http.Error(w, "Filename is required", http.StatusBadRequest) return } jobsMutex.Lock() jobInfo, exists := jobs[filename] jobsMutex.Unlock() if !exists { http.Error(w, "Job not found", http.StatusNotFound) return } jobInfo.Paused = true if jobInfo.Cmd != nil && jobInfo.Cmd.Process != nil { jobInfo.Cmd.Process.Kill() } fmt.Fprintf(w, "Pause signal sent for %s", filename) } func handleResume(w http.ResponseWriter, r *http.Request) { filename := r.URL.Query().Get("filename") if filename == "" { http.Error(w, "Filename is required", http.StatusBadRequest) return } jobsMutex.Lock() jobInfo, exists := jobs[filename] jobsMutex.Unlock() if !exists { http.Error(w, "Job not found", http.StatusNotFound) return } jobInfo.Paused = false jobInfo.ResumeChan <- struct{}{} fmt.Fprintf(w, "Resume signal sent for %s", filename) } func handleAbort(w http.ResponseWriter, r *http.Request) { filename := r.URL.Query().Get("filename") if filename == "" { http.Error(w, "Filename is required", http.StatusBadRequest) return } jobsMutex.Lock() jobInfo, exists := jobs[filename] jobsMutex.Unlock() if !exists { http.Error(w, "Job not found", http.StatusNotFound) return } close(jobInfo.AbortChan) if jobInfo.Cmd != nil && jobInfo.Cmd.Process != nil { jobInfo.Cmd.Process.Kill() } if jobInfo.TempDir != "" { os.RemoveAll(jobInfo.TempDir) } fmt.Fprintf(w, "Abort signal sent for %s", filename) }