diff --git a/downloaders.go b/downloaders.go index 67d615c..f11d206 100644 --- a/downloaders.go +++ b/downloaders.go @@ -115,6 +115,9 @@ func downloadFile(item Item, jobInfo *JobInfo) error { } return fmt.Errorf("download aborted") case err := <-done: + if jobInfo.Paused { + return fmt.Errorf("download paused") + } if err != nil { return fmt.Errorf("error executing download command: %v", err) } diff --git a/go.mod b/go.mod index 7614d61..bc9873f 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( require ( github.com/asticode/go-astikit v0.20.0 // indirect github.com/asticode/go-astits v1.8.0 // indirect - github.com/pkg/exec v0.0.0-20150614095509-0bd164ad2a5a golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect golang.org/x/text v0.3.2 // indirect ) diff --git a/handlers.go b/handlers.go index c1c1642..8d2074e 100644 --- a/handlers.go +++ b/handlers.go @@ -135,3 +135,73 @@ func handleProgress(w http.ResponseWriter, r *http.Request) { 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() + } + + fmt.Fprintf(w, "Abort signal sent for %s", filename) +} diff --git a/main.go b/main.go index fe74b32..86360aa 100644 --- a/main.go +++ b/main.go @@ -79,6 +79,8 @@ func startWebServer() { http.HandleFunc("/process", handleProcess) http.HandleFunc("/progress", handleProgress) http.HandleFunc("/abort", handleAbort) + http.HandleFunc("/pause", handlePause) + http.HandleFunc("/resume", handleResume) fmt.Println("Starting web server on http://0.0.0.0:8080") http.ListenAndServe(":8080", nil) @@ -115,27 +117,3 @@ 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() - 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() - } - - fmt.Fprintf(w, "Abort signal sent for %s", filename) -} diff --git a/templates/progress b/templates/progress index 5cd3bed..b7160f1 100644 --- a/templates/progress +++ b/templates/progress @@ -68,6 +68,21 @@ #abort-button:hover { background-color: #d32f2f; } + #pause-button, #resume-button { + background-color: #2196F3; + color: white; + border: none; + padding: 10px 15px; + margin-top: 10px; + border-radius: 4px; + cursor: pointer; + } + #pause-button:hover, #resume-button:hover { + background-color: #1976D2; + } + #resume-button { + display: none; + } @media (max-width: 600px) { body { padding: 10px; @@ -97,6 +112,8 @@
+ +