diff --git a/main.go b/main.go index 3a490a4..3eb5277 100644 --- a/main.go +++ b/main.go @@ -78,6 +78,7 @@ func startWebServer() { http.HandleFunc("/select", handleSelect) http.HandleFunc("/process", handleProcess) http.HandleFunc("/progress", handleProgress) + http.HandleFunc("/abort", handleAbort) fmt.Println("Starting web server on http://0.0.0.0:8080") http.ListenAndServe(":8080", nil) @@ -114,3 +115,23 @@ func parseMetadata(metadata string) Metadata { Season: "S" + strings.TrimSpace(parts[2]), } } + +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() + abortChan, exists := jobs[filename] + jobsMutex.Unlock() + + if !exists { + http.Error(w, "Job not found", http.StatusNotFound) + return + } + + close(abortChan) + fmt.Fprintf(w, "Abort signal sent for %s", filename) +} diff --git a/templates/progress b/templates/progress index e5c05f4..5cd3bed 100644 --- a/templates/progress +++ b/templates/progress @@ -56,6 +56,18 @@ margin-top: 10px; word-wrap: break-word; } + #abort-button { + background-color: #f44336; + color: white; + border: none; + padding: 10px 15px; + margin-top: 10px; + border-radius: 4px; + cursor: pointer; + } + #abort-button:hover { + background-color: #d32f2f; + } @media (max-width: 600px) { body { padding: 10px; @@ -84,6 +96,7 @@
+ diff --git a/utils.go b/utils.go index 31351c3..5c3c758 100644 --- a/utils.go +++ b/utils.go @@ -9,10 +9,16 @@ import ( "regexp" "strconv" "strings" + "sync" "github.com/beevik/etree" ) +var ( + jobsMutex sync.Mutex + jobs = make(map[string]chan struct{}) +) + func sanitizeFilename(filename string) string { filename = regexp.MustCompile(`[<>:"/\\|?*]`).ReplaceAllString(filename, "_") @@ -173,11 +179,28 @@ func filterSelectedItems(items []Item, selectedItems []string) []Item { } func processItems(filename string, items []Item) error { + jobsMutex.Lock() + abortChan := make(chan struct{}) + jobs[filename] = abortChan + jobsMutex.Unlock() + + defer func() { + jobsMutex.Lock() + delete(jobs, filename) + jobsMutex.Unlock() + }() + for i, item := range items { - updateProgress(filename, float64(i)/float64(len(items))*100, item.Filename) - err := downloadFile(item) - if err != nil { - fmt.Printf("Error downloading file: %v\n", err) + select { + case <-abortChan: + updateProgress(filename, 100, "Aborted") + return fmt.Errorf("download aborted") + default: + updateProgress(filename, float64(i)/float64(len(items))*100, item.Filename) + err := downloadFile(item) + if err != nil { + fmt.Printf("Error downloading file: %v\n", err) + } } } updateProgress(filename, 100, "")