From 4c88a4edb3927b3c4dc52b65e097de0814ce5c50 Mon Sep 17 00:00:00 2001 From: Fabian Siegel Date: Fri, 27 Nov 2020 01:24:54 +0100 Subject: [PATCH 1/2] starting to fix download --- cmd/commands/downloads/download/download.go | 47 ++++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/cmd/commands/downloads/download/download.go b/cmd/commands/downloads/download/download.go index b1d1c0d..b4083e3 100644 --- a/cmd/commands/downloads/download/download.go +++ b/cmd/commands/downloads/download/download.go @@ -2,6 +2,10 @@ package download import ( "fmt" + "io" + "net/http" + "os" + "strings" "github.com/craftamap/bb/cmd/options" "github.com/craftamap/bb/internal" @@ -34,14 +38,45 @@ func Add(prCmd *cobra.Command, globalOpts *options.GlobalOptions) { } downloadMap := downloadsToMap(downloads) - dwnld, ok := downloadMap[args[0]] if !ok { - fmt.Println("Zu hülfe!!") + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), err) + return + } + + downloadLink := dwnld.Links["self"].Href + + fmt.Printf("%s%s\n", aurora.Green(":: "), fmt.Sprintf("Downloading file from %s", downloadLink)) + + req, err := http.NewRequest("GET", downloadLink, strings.NewReader("")) + if err != nil { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), err) + return + } + req.SetBasicAuth(c.Username, c.Password) + resp, err := http.DefaultClient.Do(req) + if err != nil { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), err) + return + } + defer resp.Body.Close() + + fmt.Printf("%s%s\n", aurora.Green(":: "), "Downloaded!") + fmt.Printf("%s%s\n", aurora.Green(":: "), "Saving file to .") + + out, err := os.Create("./" + args[0]) + if err != nil { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), err) + return + } + defer out.Close() + + _, err = io.Copy(out, resp.Body) + if err != nil { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), err) return } - fmt.Println(dwnld.Links) }, } @@ -49,10 +84,10 @@ func Add(prCmd *cobra.Command, globalOpts *options.GlobalOptions) { prCmd.AddCommand(downloadCmd) } -func downloadsToMap(downloads *internal.Downloads) map[string]*internal.Download { - downloadMap := map[string]*internal.Download{} +func downloadsToMap(downloads *internal.Downloads) map[string]internal.Download { + downloadMap := map[string]internal.Download{} for _, dwnld := range downloads.Values { - downloadMap[dwnld.Name] = &dwnld + downloadMap[dwnld.Name] = dwnld } return downloadMap } From 347d6403cb4ca8f72c078edb963cffe009d031b9 Mon Sep 17 00:00:00 2001 From: Fabian Siegel Date: Fri, 27 Nov 2020 09:37:59 +0100 Subject: [PATCH 2/2] Fixed target location --- cmd/commands/downloads/download/download.go | 77 +++++++++++++++++++-- cmd/commands/downloads/list/list.go | 1 - 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/cmd/commands/downloads/download/download.go b/cmd/commands/downloads/download/download.go index b4083e3..5faaab1 100644 --- a/cmd/commands/downloads/download/download.go +++ b/cmd/commands/downloads/download/download.go @@ -1,10 +1,13 @@ package download import ( + "crypto/rand" "fmt" "io" + "math/big" "net/http" "os" + "path/filepath" "strings" "github.com/craftamap/bb/cmd/options" @@ -26,11 +29,66 @@ func Add(prCmd *cobra.Command, globalOpts *options.GlobalOptions) { "RequiresRepository": "true", }, Run: func(cmd *cobra.Command, args []string) { - // TODO: Get rid of this "list" workaround + var ( + remoteName string + storagePath string + ) + if len(args) == 0 { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), "No file selected") + return + } + if len(args) >= 1 { + remoteName = args[0] + storagePath = "." + } + if len(args) == 2 { + storagePath = args[1] + } + if len(args) > 2 { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), "Too many arguments") + return + } + + // First, check if dir exists and is dir. if not, fail. + // Then check if filename exists. If not, use it as filename + // Else, check if its file or dir + // If file, use it as filename + // Else, use storagePath as dir and remoteName as file + + dir, fname := filepath.Split(storagePath) + if dir != "" { + info, err := os.Stat(dir) + if err != nil { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), err) + return + } + if !info.IsDir() { + fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), fmt.Sprintf("%s is not a directory", dir)) + } + } + + info, err := os.Stat(storagePath) + if !os.IsNotExist(err) && info.IsDir() { + dir = storagePath + _, fname = filepath.Split(remoteName) + } + storagePath = filepath.Join(dir, fname) + + // Safe downloads collition-free + info, err = os.Stat(storagePath) + if !os.IsNotExist(err) && !info.IsDir() { + dir, file := filepath.Split(storagePath) + file += "." + RandomString(10) + storagePath = filepath.Join(dir, file) + } + + // Actual logic c := globalOpts.Client bbrepo := globalOpts.BitbucketRepo + fmt.Printf("%s%s\n", aurora.Green(":: "), "Getting all downloads") + downloads, err := c.GetDownloads(bbrepo.RepoOrga, bbrepo.RepoSlug) if err != nil { fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), err) @@ -38,7 +96,7 @@ func Add(prCmd *cobra.Command, globalOpts *options.GlobalOptions) { } downloadMap := downloadsToMap(downloads) - dwnld, ok := downloadMap[args[0]] + dwnld, ok := downloadMap[remoteName] if !ok { fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), err) return @@ -62,9 +120,9 @@ func Add(prCmd *cobra.Command, globalOpts *options.GlobalOptions) { defer resp.Body.Close() fmt.Printf("%s%s\n", aurora.Green(":: "), "Downloaded!") - fmt.Printf("%s%s\n", aurora.Green(":: "), "Saving file to .") + fmt.Printf("%s%s\n", aurora.Green(":: "), fmt.Sprintf("Saving file to %s", storagePath)) - out, err := os.Create("./" + args[0]) + out, err := os.Create(storagePath) if err != nil { fmt.Printf("%s%s%s\n", aurora.Red(":: "), aurora.Bold("An error occurred: "), err) return @@ -91,3 +149,14 @@ func downloadsToMap(downloads *internal.Downloads) map[string]internal.Download } return downloadMap } + +func RandomString(n int) string { + var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") + + s := make([]rune, n) + for i := range s { + a, _ := rand.Int(rand.Reader, big.NewInt(int64(len(letters)))) + s[i] = letters[a.Int64()] + } + return string(s) +} diff --git a/cmd/commands/downloads/list/list.go b/cmd/commands/downloads/list/list.go index 7231440..2544a13 100644 --- a/cmd/commands/downloads/list/list.go +++ b/cmd/commands/downloads/list/list.go @@ -22,7 +22,6 @@ func Add(downloadsCmd *cobra.Command, globalOpts *options.GlobalOptions) { "RequiresRepository": "true", }, Run: func(cmd *cobra.Command, args []string) { - c := globalOpts.Client bbrepo := globalOpts.BitbucketRepo