Skip to content

Commit

Permalink
Parse the filename from target URL (#6)
Browse files Browse the repository at this point in the history
* Add support to parse filename from URL

* Add an option to keep part files

* Shoule not append to the final file

* Update the readme file

* Fix the lint errors

fix the comment of function DownloadFileWithMultipleThreadKeepParts
  • Loading branch information
LinuxSuRen authored Jan 23, 2021
1 parent 902ee22 commit c51fa51
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 13 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build: fmt
export GOPROXY=https://goproxy.io
CGO_ENABLE=0 go build -ldflags "-w -s" -o bin/hd

run:
Expand Down
8 changes: 7 additions & 1 deletion README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ mv hd /usr/local/bin
# 用法

```
hd get https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz -o jcli.tar.gz --thread 10
hd get https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz --thread 6
```

或者,用一个更加简便的办法:

```
hd get jenkins-zh/jenkins-cli/jcli --thread 6
```

# 功能
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ mv hd /usr/local/bin
# Usage

```
hd get https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz -o jcli.tar.gz --thread 10
hd get https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz --thread 6
```

Or use a simple way:

```
hd get jenkins-zh/jenkins-cli/jcli --thread 6
```

# Features
Expand Down
32 changes: 23 additions & 9 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
extver "github.com/linuxsuren/cobra-extension/version"
"github.com/linuxsuren/http-downloader/pkg"
"github.com/spf13/cobra"
"net/url"
"path"
"runtime"
"strings"
)
Expand All @@ -20,7 +22,7 @@ func NewRoot() (cmd *cobra.Command) {
getCmd := &cobra.Command{
Use: "get",
Short: "download the file",
Example: "hd get jenkins-zh/jenkins-cli/jcli -o jcli.tar.gz --thread 3",
Example: "hd get jenkins-zh/jenkins-cli/jcli --thread 6",
PreRunE: opt.preRunE,
RunE: opt.runE,
}
Expand All @@ -31,6 +33,8 @@ func NewRoot() (cmd *cobra.Command) {
flags.BoolVarP(&opt.ShowProgress, "show-progress", "", true, "If show the progress of download")
flags.Int64VarP(&opt.ContinueAt, "continue-at", "", -1, "ContinueAt")
flags.IntVarP(&opt.Thread, "thread", "", 0, "")
flags.BoolVarP(&opt.KeepPart, "keep-part", "", false,
"If you want to keep the part files instead of deleting them")
flags.StringVarP(&opt.Provider, "provider", "", ProviderGitHub, "The file provider")
flags.StringVarP(&opt.OS, "os", "", "", "The OS of target binary file")
flags.StringVarP(&opt.Arch, "arch", "", "", "The arch of target binary file")
Expand All @@ -52,7 +56,8 @@ type downloadOption struct {
Arch string
OS string

Thread int
Thread int
KeepPart bool
}

const (
Expand Down Expand Up @@ -118,18 +123,27 @@ func (o *downloadOption) preRunE(cmd *cobra.Command, args []string) (err error)
o.Arch = runtime.GOARCH
}

url := args[0]
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
if url, err = o.providerURLParse(url); err != nil {
targetURL := args[0]
if !strings.HasPrefix(targetURL, "http://") && !strings.HasPrefix(targetURL, "https://") {
if targetURL, err = o.providerURLParse(targetURL); err != nil {
err = fmt.Errorf("only http:// or https:// supported, error: %v", err)
return
}
cmd.Printf("start to download from %s\n", url)
cmd.Printf("start to download from %s\n", targetURL)
}
o.URL = url
o.URL = targetURL

if o.Output == "" {
err = fmt.Errorf("output cannot be empty")
var urlObj *url.URL
if urlObj, err = url.Parse(o.URL); err == nil {
o.Output = path.Base(urlObj.Path)

if o.Output == "" {
err = fmt.Errorf("output cannot be empty")
}
} else {
err = fmt.Errorf("cannot parse the target URL, error: '%v'", err)
}
}
return
}
Expand All @@ -138,7 +152,7 @@ func (o *downloadOption) runE(cmd *cobra.Command, args []string) (err error) {
if o.Thread <= 1 {
err = pkg.DownloadWithContinue(o.URL, o.Output, o.ContinueAt, 0, o.ShowProgress)
} else {
err = pkg.DownloadFileWithMultipleThread(o.URL, o.Output, o.Thread, o.ShowProgress)
err = pkg.DownloadFileWithMultipleThreadKeepParts(o.URL, o.Output, o.Thread, o.KeepPart, o.ShowProgress)
}
return
}
9 changes: 7 additions & 2 deletions pkg/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ func (h *HTTPDownloader) DownloadFile() error {

// DownloadFileWithMultipleThread downloads the files with multiple threads
func DownloadFileWithMultipleThread(targetURL, targetFilePath string, thread int, showProgress bool) (err error) {
return DownloadFileWithMultipleThreadKeepParts(targetURL, targetFilePath, thread, false, showProgress)
}

// DownloadFileWithMultipleThreadKeepParts downloads the files with multiple threads
func DownloadFileWithMultipleThreadKeepParts(targetURL, targetFilePath string, thread int, keepParts, showProgress bool) (err error) {
// get the total size of the target file
var total int64
var rangeSupport bool
Expand Down Expand Up @@ -211,7 +216,7 @@ func DownloadFileWithMultipleThread(targetURL, targetFilePath string, thread int

// concat all these partial files
var f *os.File
if f, err = os.OpenFile(targetFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil {
if f, err = os.OpenFile(targetFilePath, os.O_CREATE|os.O_WRONLY, 0644); err == nil {
defer func() {
_ = f.Close()
}()
Expand All @@ -222,7 +227,7 @@ func DownloadFileWithMultipleThread(targetURL, targetFilePath string, thread int
if _, err = f.Write(data); err != nil {
err = fmt.Errorf("failed to write file: '%s'", partFile)
break
} else {
} else if !keepParts {
_ = os.RemoveAll(partFile)
}
} else {
Expand Down

0 comments on commit c51fa51

Please sign in to comment.