Work-in-progress. This repository contains some scripts to prepare SD card images for the raspberry Pi.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

116 lines
2.1 KiB

package main
import (
"context"
"fmt"
"io"
"log"
"net/http"
"os"
"path"
"regexp"
"sort"
"strconv"
"strings"
"time"
"github.com/gocolly/colly"
"github.com/machinebox/progress"
)
func list() {
c := colly.NewCollector(
colly.AllowedDomains("downloads.raspberrypi.org"),
colly.UserAgent("github.com/klingtnet/raspi-toolbox"),
colly.Async(true),
)
c.Limit(&colly.LimitRule{Parallelism: 4})
urls := []string{}
imgMatcher := regexp.MustCompile(".*raspbian-stretch-lite.*\\.zip$")
c.OnHTML("a[href]", func(e *colly.HTMLElement) {
link := e.Attr("href")
if strings.HasPrefix(link, "raspbian_lite") {
c.Visit(e.Request.AbsoluteURL(link))
return
}
if imgMatcher.Match([]byte(link)) {
urls = append(urls, e.Request.AbsoluteURL(link))
}
})
c.Visit("https://downloads.raspberrypi.org/raspbian_lite/images/")
c.Wait()
sort.Strings(urls)
for _, u := range urls {
fmt.Println(u)
}
}
func download(u string) error {
filename := path.Base(u)
fmt.Printf("writing into %q\n", filename)
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
resp, err := http.Get(u)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("expected HTTP 200 OK but was %d", resp.StatusCode)
}
size, err := strconv.Atoi(resp.Header.Get("Content-Length"))
if err != nil {
return err
}
pr := progress.NewReader(resp.Body)
go func() {
progressChan := progress.NewTicker(context.Background(), pr, int64(size), 3*time.Second)
for p := range progressChan {
fmt.Printf("\r%.2f%%", p.Percent())
}
}()
_, err = io.Copy(f, pr)
fmt.Println("\r100.0%")
return err
}
func usage() {
fmt.Printf(`%s [list|usage|help|<url>]
usage|help:
Prints this message
list:
Prints all available images
<url>:
Downloads the image under <url>
`, os.Args[0])
}
func main() {
if len(os.Args) <= 1 {
usage()
os.Exit(1)
}
arg := os.Args[1]
switch arg {
case "usage":
fallthrough
case "help":
usage()
return
case "list":
list()
default:
if err := download(os.Args[1]); err != nil {
log.Fatalln(err)
}
}
}