package updates import ( "errors" "os" "path/filepath" "time" ) //Download updates from given URL, return real time progress of stage (int), progress (int) and status text (string) func DownloadUpdatesFromURL(binaryURL string, webpackURL string, progressUpdateFunction func(int, float64, string)) error { //Create the update download folder os.RemoveAll("./updates") os.MkdirAll("./updates", 0755) //Get the total size of download expected binarySize, webpackSize, err := GetUpdateSizes(binaryURL, webpackURL) if err != nil { return errors.New("Unable to access given URL") } //Generate the download position binaryDownloadTarget := "./updates/" + filepath.Base(binaryURL) webpackDownloadTarget := "./updates/" + filepath.Base(webpackURL) //Start the download of binary //0 = false, 1 = true, 2 = error binaryDownloadComplete := 0 webpackDownloadComplete := 0 errorMessage := "" go func() { for binaryDownloadComplete == 0 { binaryFileSize := getFileSize(binaryDownloadTarget) progress := (float64(binaryFileSize) / float64(binarySize) * 100) progressUpdateFunction(0, progress, "Downloading binary") time.Sleep(100 * time.Millisecond) } if binaryDownloadComplete == 1 { progressUpdateFunction(0, 100, "Binary Download Completed") } else { progressUpdateFunction(0, 100, "Error: "+errorMessage) } }() err = downloadFile(binaryURL, binaryDownloadTarget) if err != nil { errorMessage = err.Error() binaryDownloadComplete = 2 return err } binaryDownloadComplete = 1 //Downlaod webpack go func() { for webpackDownloadComplete == 0 { webpackFileSize := getFileSize(webpackDownloadTarget) progress := (float64(webpackFileSize) / float64(webpackSize) * 100) progressUpdateFunction(1, progress, "Downloading webpack") time.Sleep(100 * time.Millisecond) } if webpackDownloadComplete == 1 { progressUpdateFunction(1, 100, "Webpack Download Completed") } else { progressUpdateFunction(1, 100, "Error: "+errorMessage) } }() err = downloadFile(webpackURL, webpackDownloadTarget) if err != nil { errorMessage = err.Error() webpackDownloadComplete = 2 return err } webpackDownloadComplete = 1 //Download completed. Try unzip webpack gzipstrean, err := os.Open(webpackDownloadTarget) if err != nil { return err } progressUpdateFunction(2, 0, "Extracting webpack") err = extractTarGz(gzipstrean, "./updates/", progressUpdateFunction) if err != nil { return err } gzipstrean.Close() //Remove the webpack compressed file os.Remove(webpackDownloadTarget) progressUpdateFunction(3, 100, "Updates Downloaded") return nil } //Get the update sizes, return binary size, webpack size and error if any func GetUpdateSizes(binaryURL string, webpackURL string) (int, int, error) { bps, err := getDownloadFileSize(binaryURL) if err != nil { return -1, -1, err } wps, err := getDownloadFileSize(webpackURL) if err != nil { return -1, -1, err } return bps, wps, nil }