Skip to content

Instantly share code, notes, and snippets.

@KonradIT
Created December 17, 2022 16:17
Show Gist options
  • Save KonradIT/790c7db9b17ddc301e58d23b378e87b3 to your computer and use it in GitHub Desktop.
Save KonradIT/790c7db9b17ddc301e58d23b378e87b3 to your computer and use it in GitHub Desktop.
Download files off of GoPro concurrently
package main
import (
"io"
"log"
"net/http"
"os"
"path/filepath"
"strconv"
"sync"
"time"
"github.com/vbauerster/mpb/v8"
"github.com/vbauerster/mpb/v8/decor"
)
const (
FILE_1 = "http://172.23.120.51:8080/videos/DCIM/100GOPRO/GX010375.MP4"
FILE_2 = "http://172.23.120.51:8080/videos/DCIM/100GOPRO/GOPR0377.JPG"
FILE_3 = "http://172.23.120.51:8080/videos/DCIM/100GOPRO/G0010378.JPG"
)
var (
FILES = []string{FILE_1, FILE_2, FILE_3}
)
func head(path string) (int, error) {
client := &http.Client{}
req, err := http.NewRequest("HEAD", path, nil)
if err != nil {
return 0, err
}
resp, err := client.Do(req)
if err != nil {
return 0, err
}
length, err := strconv.Atoi(resp.Header.Get("Content-Length"))
if err != nil {
return 0, err
}
return length, nil
}
func downloadFile(filePath string, bar *mpb.Bar) error {
resp, err := http.Get(filePath)
if err != nil {
return err
}
defer resp.Body.Close()
name := filepath.Base(filePath)
file, err := os.Create(name)
if err != nil {
return err
}
defer file.Close()
proxyReader := bar.ProxyReader(resp.Body)
defer proxyReader.Close()
_, err = io.Copy(file, proxyReader)
if err != nil {
return err
}
return nil
}
func main() {
var wg sync.WaitGroup
p := mpb.New(mpb.WithWaitGroup(&wg),
mpb.WithWidth(60),
mpb.WithRefreshRate(180*time.Millisecond))
nfiles := len(FILES)
for i := 0; i < nfiles; i++ {
head, err := head(FILES[i])
if err != nil {
panic(err)
}
bar := p.AddBar(int64(head),
mpb.PrependDecorators(
decor.CountersKiloByte("% .2f / % .2f"),
),
mpb.AppendDecorators(
decor.OnComplete(
decor.EwmaETA(decor.ET_STYLE_GO, 60, decor.WCSyncWidth), "✔️",
),
),
)
wg.Add(1)
go func(current int) {
defer wg.Done()
err := downloadFile(FILES[current], bar)
if err != nil {
log.Fatal(err.Error())
}
}(i)
}
p.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment