Skip to content

Commit

Permalink
Replaced int with uint where ever possible, Added more stats, Added d…
Browse files Browse the repository at this point in the history
…eps in travis.yml, Polishing
  • Loading branch information
ishanjain28 committed Sep 9, 2017
1 parent 5cff8de commit 88dc701
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 22 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ go:
- 1.8.x
- 1.9.x
- master

install:
- go get github.com/dustin/go-humanize
35 changes: 19 additions & 16 deletions pluto/pluto.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import (
)

type worker struct {
begin int64
end int64
begin uint64
end uint64
url *url.URL
}

// FileMeta contains information about the file like it's Size and if the server where it is hosted supports multipart downloads
type FileMeta struct {
u *url.URL
Size int64
Size uint64
Name string
MultipartSupported bool
}
Expand All @@ -31,7 +31,7 @@ type FileMeta struct {
// Verbose is to enable verbose mode.
// Writer is the place where downloaded data is written.
type Config struct {
Parts int
Parts uint
Verbose bool
Writer io.WriterAt
Meta *FileMeta
Expand All @@ -51,14 +51,15 @@ func Download(c *Config) error {
c.Parts = 1
}

perPartLimit := c.Meta.Size / int64(c.Parts)
difference := c.Meta.Size % int64(c.Parts)
perPartLimit := c.Meta.Size / uint64(c.Parts)
difference := c.Meta.Size % uint64(c.Parts)

workers := make([]*worker, c.Parts)

for i := 0; i < c.Parts; i++ {
begin := perPartLimit * int64(i)
end := perPartLimit * (int64(i) + 1)
var i uint
for i = 0; i < c.Parts; i++ {
begin := perPartLimit * uint64(i)
end := perPartLimit * (uint64(i) + 1)

if i == c.Parts-1 {
end += difference
Expand Down Expand Up @@ -115,7 +116,9 @@ func startDownload(w []*worker, verbose bool, writer io.WriterAt) error {

d, err := copyAt(writer, downloadPart, begin)
if err != nil {
log.Printf("error in copyAt at offset %d: %v", v.begin, err)
if verbose {
log.Printf("error in copyAt at offset %d: %v", v.begin, err)
}
begin += d
continue
}
Expand Down Expand Up @@ -155,7 +158,7 @@ func startDownload(w []*worker, verbose bool, writer io.WriterAt) error {
}

// copyAt reads 64 kilobytes from source and copies them to destination at a given offset
func copyAt(dst io.WriterAt, src io.Reader, offset int64) (int64, error) {
func copyAt(dst io.WriterAt, src io.Reader, offset uint64) (uint64, error) {
bufBytes := make([]byte, 64*1024)

var bytesWritten int64
Expand All @@ -164,9 +167,9 @@ func copyAt(dst io.WriterAt, src io.Reader, offset int64) (int64, error) {
for {
nsr, serr := src.Read(bufBytes)
if nsr > 0 {
ndw, derr := dst.WriteAt(bufBytes[:nsr], offset)
ndw, derr := dst.WriteAt(bufBytes[:nsr], int64(offset))
if ndw > 0 {
offset += int64(ndw)
offset += uint64(ndw)
bytesWritten += int64(ndw)
}
if derr != nil {
Expand All @@ -188,7 +191,7 @@ func copyAt(dst io.WriterAt, src io.Reader, offset int64) (int64, error) {
}
}

return bytesWritten, err
return uint64(bytesWritten), err
}

// FetchMeta fetches information about the file like it's Size, Name and if it supports Multipart Download
Expand All @@ -215,10 +218,10 @@ func FetchMeta(u *url.URL) (*FileMeta, error) {
m = false
}

return &FileMeta{Size: size, u: u, MultipartSupported: m}, nil
return &FileMeta{Size: uint64(size), u: u, MultipartSupported: m}, nil
}

func download(begin, end int64, u *url.URL) (io.ReadCloser, error) {
func download(begin, end uint64, u *url.URL) (io.ReadCloser, error) {

client := &http.Client{}
req, err := http.NewRequest("GET", u.String(), nil)
Expand Down
36 changes: 30 additions & 6 deletions pluto_cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func main() {
os.Exit(0)
}()

parts := flag.Int("part", 32, "Number of Download parts")
parts := flag.Uint("part", 32, "Number of Download parts")
verbose := flag.Bool("verbose", false, "Enable Verbose Mode")
name := flag.String("name", "", "Path or Name of save File")

Expand Down Expand Up @@ -57,18 +57,19 @@ func main() {
}
}

func download(u, filename string, parts int, verbose bool) {
func download(u, filename string, parts uint, verbose bool) {

// This variable is used to check if an error occurred anywhere in program
// If an error occurs, Then it'll not exit.
// And if no error occurs, Then it'll exit after 10 seconds
var errored bool
var dlFinished bool

defer func() {
if errored {
select {}
} else {
time.Sleep(10 * time.Second)
time.Sleep(5 * time.Second)
}
}()

Expand Down Expand Up @@ -112,13 +113,36 @@ func download(u, filename string, parts int, verbose bool) {
Writer: saveFile,
}

a := time.Now()
startTime := time.Now()
go func() {
for {
time.Sleep(1 * time.Second)
elapsed := time.Since(startTime)

avgSpeed := meta.Size / uint64(elapsed.Seconds())

time.Sleep(100 * time.Millisecond)

if dlFinished {
break
}
fmt.Printf("Average Speed: %s/s, Elapsed Time: %s\r", humanize.IBytes(avgSpeed), elapsed.String())
}
}()

err = pluto.Download(config)
if err != nil {
errored = true
log.Printf("%v", err)
return
}
timeTaken := time.Since(a)
fmt.Printf("Downloaded complete in %s. Avg. Speed - %s/s\n", timeTaken, humanize.IBytes(uint64(meta.Size)/uint64(timeTaken.Seconds())))
timeTaken := time.Since(startTime)
dlFinished = true
fmt.Printf("Downloaded complete in %s. Avg. Speed - %s/s\n", timeTaken, humanize.IBytes(meta.Size/uint64(timeTaken.Seconds())))

p, err := filepath.Abs(meta.Name)
if err != nil {
fmt.Printf("File saved in %s\n", meta.Name)
}
fmt.Printf("File saved in %s\n", p)
}

0 comments on commit 88dc701

Please sign in to comment.