Skip to content

Commit b3836b1

Browse files
committed
added resumable download, untested
1 parent a1e4e02 commit b3836b1

File tree

7 files changed

+56
-14
lines changed

7 files changed

+56
-14
lines changed

common/functions.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ package common
3131

3232
import (
3333
"archive/zip"
34+
"bytes"
3435
"fmt"
3536
"io/ioutil"
3637
"net/http"
@@ -154,14 +155,25 @@ func TruncateDir(dir string) error {
154155
}
155156

156157
// DownloadPackage downloads a package from arduino repository, applying a label for the progress bar.
157-
func DownloadPackage(URL string, downloadLabel string, progressBar *pb.ProgressBar) ([]byte, error) {
158+
func DownloadPackage(URL string, downloadLabel string, progressBar *pb.ProgressBar, initialData []byte) ([]byte, error) {
158159
client := http.DefaultClient
159160

160161
request, err := http.NewRequest("GET", URL, nil)
161162
if err != nil {
162163
return nil, fmt.Errorf("Cannot create HTTP request: %s", err)
163164
}
164165

166+
var initialSize int
167+
if initialData == nil {
168+
initialSize = 0
169+
} else {
170+
initialSize = len(initialData)
171+
}
172+
173+
if initialSize > 0 {
174+
request.Header.Add("Range", fmt.Sprintf("bytes=%d-", initialSize))
175+
}
176+
//TODO : how to add progressbar with resume download?
165177
response, err := client.Do(request)
166178

167179
if err != nil {
@@ -174,12 +186,20 @@ func DownloadPackage(URL string, downloadLabel string, progressBar *pb.ProgressB
174186

175187
source := response.Body
176188
if progressBar != nil {
189+
progressBar.Add(initialSize)
177190
source = progressBar.NewProxyReader(response.Body)
178191
}
179192

180193
body, err := ioutil.ReadAll(source)
181194
if err != nil {
182195
return nil, fmt.Errorf("Cannot read response body")
183196
}
184-
return body, nil
197+
var total []byte
198+
if initialData != nil {
199+
total = bytes.Join([][]byte{initialData, body}, nil)
200+
} else {
201+
total = body
202+
}
203+
204+
return total, nil
185205
}

cores/cores.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ func (core *Core) Versions() semver.Versions {
7575

7676
// Latest obtains latest version of a core package.
7777
func (core *Core) Latest() *Release {
78-
latest := core.latestVersion()
79-
return core.GetVersion(latest)
78+
return core.GetVersion(core.latestVersion())
8079
}
8180

8281
// latestVersion obtains latest version number.

cores/package_manager.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,15 @@ func (pm *Package) AddCore(indexCore *indexCoreRelease) {
5353
}
5454
}
5555

56+
// Items returns the list of cores of this package.
57+
func (pm Package) Items() map[string]interface{} {
58+
ret := make(map[string]interface{}, len(pm.Cores))
59+
for key, val := range pm.Cores {
60+
ret[key] = val
61+
}
62+
return ret
63+
}
64+
5665
// Names returns an array with all the names of the registered cores.
5766
func (pm Package) Names() []string {
5867
res := make([]string, len(pm.Cores))

cores/status.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,6 @@ func (sc *StatusContext) AddPackage(indexPackage *indexPackage) {
4646
sc.Packages[indexPackage.Name] = indexPackage.extractPackage()
4747
}
4848

49-
// Items returns a map matching core name and core struct.
50-
func (pm Package) Items() map[string]interface{} {
51-
ret := make(map[string]interface{}, len(pm.Cores))
52-
for key, val := range pm.Cores {
53-
ret[key] = val
54-
}
55-
return ret
56-
}
57-
5849
// Names returns the array containing the name of the packages.
5950
func (sc StatusContext) Names() []string {
6051
res := make([]string, len(sc.Packages))

cores/tools.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package cores
2+
3+
type Tool struct {
4+
5+
}

libraries/download.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ func downloadRelease(library *Library, progBar *pb.ProgressBar, version string)
8585
if release == nil {
8686
return nil, errors.New("Invalid version number")
8787
}
88-
return common.DownloadPackage(release.URL, fmt.Sprintf("library %s", library.Name), progBar)
88+
initialData := release.ReadLocalArchive()
89+
return common.DownloadPackage(release.URL, fmt.Sprintf("library %s", library.Name), progBar, initialData)
8990
}
9091

9192
// DownloadLibrariesFile downloads the lib file from arduino repository.

libraries/libraries.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,23 @@ type Release struct {
128128
Checksum string `json:"checksum"`
129129
}
130130

131+
// ReadLocalArchive reads the data from the local archive if present,
132+
// and returns the []byte of the file content. Used by resume Download.
133+
func (r Release) ReadLocalArchive() []byte {
134+
staging, err := getDownloadCacheFolder()
135+
if err != nil {
136+
return nil
137+
}
138+
path := filepath.Join(staging, r.ArchiveFileName)
139+
content, err := ioutil.ReadFile(path)
140+
// if the size is the same the archive has been downloaded and if we force redownload
141+
// it won't work.
142+
if err != nil || len(content) == r.Size {
143+
return nil
144+
}
145+
return content
146+
}
147+
131148
/*
132149
133150
type releaseAlias Release

0 commit comments

Comments
 (0)