diff --git a/handlers.go b/handlers.go index 11f5ce3..6fcd0c8 100644 --- a/handlers.go +++ b/handlers.go @@ -5,8 +5,10 @@ import ( "fmt" "io" "net/http" + "net/url" "os" "path/filepath" + "strings" ) type ProgressInfo struct { @@ -50,53 +52,101 @@ func handleRoot(w http.ResponseWriter, r *http.Request) { } func handleUpload(w http.ResponseWriter, r *http.Request) { - file, header, err := r.FormFile("file") + err := r.ParseMultipartForm(32 << 20) 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) + files := r.MultipartForm.File["files"] + if len(files) == 0 { + http.Error(w, "No files uploaded", http.StatusBadRequest) return } - tempFilename := filepath.Base(tempFile.Name()) + uploadedFiles := []string{} - _, err = parseInputFile(tempFile.Name()) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) + for _, fileHeader := range files { + file, err := fileHeader.Open() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer file.Close() + + dst, err := os.Create(filepath.Join(uploadDir, fileHeader.Filename)) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer dst.Close() + + _, err = io.Copy(dst, file) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + uploadedFiles = append(uploadedFiles, fileHeader.Filename) + + _, err = parseInputFile(dst.Name()) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } + + validFiles := []string{} + for _, file := range uploadedFiles { + if file != "" { + validFiles = append(validFiles, file) + } + } + + if len(validFiles) == 0 { + http.Error(w, "No valid files were uploaded", http.StatusBadRequest) return } - http.Redirect(w, r, "/select?filename="+tempFilename, http.StatusSeeOther) + http.Redirect(w, r, "/select?files="+url.QueryEscape(strings.Join(validFiles, ",")), 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) + filesParam := r.URL.Query().Get("files") + filenames := strings.Split(filesParam, ",") + + allItems := make(map[string]map[string][]Item) + + for _, filename := range filenames { + if filename == "" { + continue + } + fullPath := filepath.Join(uploadDir, filename) + + if _, err := os.Stat(fullPath); os.IsNotExist(err) { + continue + } + + items, err := parseInputFile(fullPath) + if err != nil { + continue + } + + groupedItems := groupItemsBySeason(items) + allItems[filename] = groupedItems + } + + if len(allItems) == 0 { + http.Error(w, "No valid files were processed", http.StatusBadRequest) return } - groupedItems := groupItemsBySeason(items) - - err = templates.ExecuteTemplate(w, "select", struct { - Filename string - Items map[string][]Item + err := templates.ExecuteTemplate(w, "select", struct { + Filenames string + AllItems map[string]map[string][]Item }{ - Filename: filename, - Items: groupedItems, + Filenames: filesParam, + AllItems: allItems, }) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) @@ -104,36 +154,47 @@ func handleSelect(w http.ResponseWriter, r *http.Request) { } 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) + if err := r.ParseForm(); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) return } - filteredItems := filterSelectedItems(items, selectedItems) + selectedItems := r.Form["items"] + if len(selectedItems) == 0 { + http.Error(w, "No items selected", http.StatusBadRequest) + return + } - go func() { - err := processItems(filename, filteredItems) + itemsByFile := make(map[string][]string) + for _, item := range selectedItems { + parts := strings.SplitN(item, ":", 2) + if len(parts) != 2 { + continue + } + filename, itemName := parts[0], parts[1] + itemsByFile[filename] = append(itemsByFile[filename], itemName) + } + + for filename, items := range itemsByFile { + fullPath := filepath.Join(uploadDir, filename) + allItems, err := parseInputFile(fullPath) if err != nil { - fmt.Printf("Error processing file: %v\n", err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return } - os.Remove(filepath.Join(uploadDir, filename)) - }() + selectedItems := filterSelectedItems(allItems, items) + go processItems(filename, selectedItems) + } - http.Redirect(w, r, "/progress?filename="+filename, http.StatusSeeOther) + http.Redirect(w, r, "/", 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) @@ -144,7 +205,6 @@ func handleProgress(w http.ResponseWriter, r *http.Request) { 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 } @@ -206,7 +266,6 @@ func handleResume(w http.ResponseWriter, r *http.Request) { jobInfo.Paused = false jobInfo.ResumeChan <- struct{}{} - // Update the progress information progressMutex.Lock() if progressInfo, ok := progress[filename]; ok { progressInfo.Paused = false @@ -291,5 +350,4 @@ func updateProgress(filename string, value float64, currentFile string) { Paused: paused, } } - fmt.Printf("Progress updated for %s: %.2f%%, Current file: %s, Paused: %v\n", filename, value, currentFile, paused) } diff --git a/templates/index b/templates/index index cc55ff1..af57727 100644 --- a/templates/index +++ b/templates/index @@ -112,7 +112,7 @@