/
zipper.go
66 lines (52 loc) · 1.25 KB
/
zipper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package zipper
import (
"archive/zip"
"bytes"
"net/http"
"io"
"strings"
)
type URLDownload struct {
url string
body io.ReadCloser
err error
}
// Download all files from the given urls
// and write them on the output
func CreateZip(urls []string, output io.Writer) error{
buf := new(bytes.Buffer)
archive := zip.NewWriter(buf)
c := make(chan URLDownload, len(urls))
for _, url := range urls{
go downloadURL(url, c)
}
for i := 0; i < len(urls); i++ {
err := appendToArchive(archive, <-c)
if err != nil { return err }
}
err := archive.Close()
if err != nil { return err }
_, err = buf.WriteTo(output)
return err
}
func fileNameFromURL(url string) string{
a := strings.Split(url, "/")
return a[len(a)-1]
}
func downloadURL(url string, c chan URLDownload){
resp, err := http.Get(url)
if err != nil {
c <- URLDownload{url, nil, err}
}else{
c <- URLDownload{url, resp.Body, err}
}
}
func appendToArchive(archive *zip.Writer, download URLDownload) error{
if download.err != nil { return download.err }
fileName := fileNameFromURL(download.url)
w, err := archive.Create(fileName)
if err != nil { return err }
_, err = io.Copy(w, download.body)
defer download.body.Close()
return nil
}