forked from kardianos/photoview
/
download.go
125 lines (108 loc) · 2.37 KB
/
download.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package main
import (
"archive/tar"
"bytes"
"crypto/rand"
"encoding/base32"
"io"
"net/http"
"os"
"path/filepath"
"time"
"github.com/disintegration/imaging"
)
type baseList struct {
folder string
list []string
small bool
}
var downloadMapper = make(map[string]baseList)
func (p *program) downloadAssignKey(folder string, list []string, small bool) (key string, err error) {
kb := make([]byte, 32)
_, err = rand.Read(kb)
if err != nil {
return "", err
}
key = base32.StdEncoding.EncodeToString(kb)
downloadMapper[key] = baseList{folder, list, small}
go func() {
<-time.After(time.Second * 3)
delete(downloadMapper, key)
}()
return key, nil
}
func (p *program) downloadWriteKey(key string, w http.ResponseWriter) error {
bl, found := downloadMapper[key]
if !found {
http.Error(w, "Not found", 404)
return nil
}
w.Header().Set("Content-Disposition", `attachment; filename="photos.tar"`)
tw := tar.NewWriter(w)
result := &bytes.Buffer{}
for _, item := range bl.list {
filename := filepath.Join(config.FileRoot, bl.folder, item)
fi, err := os.Stat(filename)
if err != nil {
return err
}
if !bl.small {
header, err := tar.FileInfoHeader(fi, "")
if err != nil {
return err
}
err = tw.WriteHeader(header)
if err != nil {
return err
}
f, err := os.Open(filename)
if err != nil {
return err
}
_, err = io.Copy(tw, f)
f.Close()
if err != nil {
return err
}
} else {
fullImage, err := imaging.Open(filename)
if err != nil {
return err
}
resized := imaging.Fit(fullImage, config.SmallRes, config.SmallRes, imaging.Linear)
err = imaging.Encode(result, resized, imaging.JPEG)
if err != nil {
return err
}
header := &tar.Header{
Name: item,
Size: int64(result.Len()),
Mode: 0666,
ModTime: fi.ModTime(),
}
err = tw.WriteHeader(header)
if err != nil {
return err
}
_, err = io.Copy(tw, result)
if err != nil {
return err
}
result.Reset()
}
}
return tw.Close()
}
func getImage(filename string, small bool) (io.ReadCloser, error) {
if !small {
return os.Open(filename)
}
fullImage, err := imaging.Open(filename)
if err != nil {
return nil, err
}
resized := imaging.Fit(fullImage, config.SmallRes, config.SmallRes, imaging.Linear)
r, w := io.Pipe()
go imaging.Encode(w, resized, imaging.JPEG)
return r, nil
}