From 5d5780379916f7271c5e905c7b115cc0b2ce9299 Mon Sep 17 00:00:00 2001 From: Justin Hawkins Date: Sat, 25 Nov 2023 22:03:06 +1030 Subject: [PATCH] Add feature to do bulk downloads, bump version --- CHANGELOG.md | 4 ++ main.go | 2 +- web/data/templates/bulk.tmpl | 91 +++++++++++++++++++++++++++ web/data/templates/menu.tmpl | 4 +- web/data/templates/popup_create.tmpl | 4 +- web/web.go | 92 ++++++++++++++++++++++++++++ 6 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 web/data/templates/bulk.tmpl diff --git a/CHANGELOG.md b/CHANGELOG.md index ee31951..126b39d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project will be documented in this file. +## [v1.1.0] - 2023-11-25 + +- Add feature to bulk add URL's for downloading + ## [v1.0.1] - 2023-11-24 - Fix crash on migrating a config that had > 1 destinations diff --git a/main.go b/main.go index 0ba799e..7687180 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,7 @@ import ( func main() { versionInfo := &version.Manager{ - VersionInfo: version.Info{CurrentVersion: "v1.0.1"}, + VersionInfo: version.Info{CurrentVersion: "v1.1.0"}, } log.Printf("Starting gropple %s - https://github.com/tardisx/gropple", versionInfo.GetInfo().CurrentVersion) diff --git a/web/data/templates/bulk.tmpl b/web/data/templates/bulk.tmpl new file mode 100644 index 0000000..bf69688 --- /dev/null +++ b/web/data/templates/bulk.tmpl @@ -0,0 +1,91 @@ +{{ define "content" }} + +{{ template "menu.tmpl" . }} + +
+ +

Bulk upload

+ +

+

+ +

Paste URLs here, one per line:

+ + + +

+ + + + + + + + + + + + + + + +
profile + +
download option + +
  + +
+ + + + +
+ +{{ end }} + +{{ define "js" }} + +{{ end }} \ No newline at end of file diff --git a/web/data/templates/menu.tmpl b/web/data/templates/menu.tmpl index ee38f68..4a8bc40 100644 --- a/web/data/templates/menu.tmpl +++ b/web/data/templates/menu.tmpl @@ -7,9 +7,11 @@
  • Config
  • +
  • + Bulk +
  • Github
  • - \ No newline at end of file diff --git a/web/data/templates/popup_create.tmpl b/web/data/templates/popup_create.tmpl index e921db7..559f6a1 100644 --- a/web/data/templates/popup_create.tmpl +++ b/web/data/templates/popup_create.tmpl @@ -13,7 +13,7 @@ @@ -24,7 +24,7 @@ diff --git a/web/web.go b/web/web.go index 10dd891..33cabfe 100644 --- a/web/web.go +++ b/web/web.go @@ -55,6 +55,9 @@ func CreateRoutes(cs *config.ConfigService, dm *download.Manager, vm *version.Ma r.HandleFunc("/fetch", fetchHandler(cs, vm, dm)) r.HandleFunc("/fetch/{id}", fetchHandler(cs, vm, dm)) + // handle the bulk uploader + r.HandleFunc("/bulk", bulkHandler(cs, vm, dm)) + // get/update info on a download r.HandleFunc("/rest/fetch/{id}", fetchInfoOneRESTHandler(cs, dm)) @@ -399,3 +402,92 @@ func fetchHandler(cs *config.ConfigService, vm *version.Manager, dm *download.Ma } } + +func bulkHandler(cs *config.ConfigService, vm *version.Manager, dm *download.Manager) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + log.Printf("bulkHandler") + + method := r.Method + if method == "GET" { + + t, err := template.ParseFS(webFS, "data/templates/layout.tmpl", "data/templates/menu.tmpl", "data/templates/bulk.tmpl") + if err != nil { + panic(err) + } + templateData := map[string]interface{}{"config": cs.Config, "Version": vm.GetInfo()} + + err = t.ExecuteTemplate(w, "layout", templateData) + if err != nil { + panic(err) + } + + return + + } else if method == "POST" { + type reqBulkType struct { + URLs string `json:"urls"` + ProfileChosen string `json:"profile"` + DownloadOptionChosen string `json:"download_option"` + } + + req := reqBulkType{} + json.NewDecoder(r.Body).Decode(&req) + + log.Printf("bulk POST request: %#v", req) + + if req.URLs == "" { + w.WriteHeader(400) + json.NewEncoder(w).Encode(errorResponse{ + Success: false, + Error: "No URLs supplied", + }) + return + } + + if req.ProfileChosen == "" { + + w.WriteHeader(400) + json.NewEncoder(w).Encode(errorResponse{ + Success: false, + Error: "you must choose a profile", + }) + return + } + + profile := cs.Config.ProfileCalled(req.ProfileChosen) + if profile == nil { + w.WriteHeader(400) + json.NewEncoder(w).Encode(errorResponse{ + Success: false, + Error: fmt.Sprintf("no such profile: '%s'", req.ProfileChosen), + }) + return + } + + option := cs.Config.DownloadOptionCalled(req.DownloadOptionChosen) + + // create the new downloads + urls := strings.Split(req.URLs, "\n") + count := 0 + for _, thisURL := range urls { + thisURL = strings.TrimSpace(thisURL) + if thisURL != "" { + newDL := download.NewDownload(thisURL, cs.Config) + newDL.DownloadOption = option + newDL.DownloadProfile = *profile + dm.AddDownload(newDL) + dm.Queue(newDL) + log.Printf("queued %s", thisURL) + count++ + } + } + + w.WriteHeader(200) + json.NewEncoder(w).Encode(successResponse{ + Success: true, + Message: fmt.Sprintf("queued %d downloads", count), + }) + return + } + } +}