-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
128 lines (117 loc) · 2.73 KB
/
main.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
126
127
128
package main
import (
"flag"
sysio "io"
"io/ioutil"
"log"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"github.com/qiniu/api.v6/conf"
"github.com/qiniu/api.v6/resumable/io"
"github.com/qiniu/api.v6/rs"
"gopkg.in/gcfg.v1"
)
type Config struct {
Qiniu struct {
UpHost string `gcfg:"uphost"`
AccessKey string `gcfg:"accesskey"`
SecretKey string `gcfg:"secretkey"`
Bucket string
KeyPrefix string `gcfg:"keyprefix"`
}
Local struct {
SyncDir string `gcfg:"syncdir"`
}
Gorelease struct {
Host string `gcfg:"host"`
Token string `gcfg:"token"`
}
}
var cfg Config
func genUptoken(bucket, key string) string {
gr := cfg.Gorelease
if gr.Token != "" {
log.Println("Use gorelease, key:", key)
u := url.URL{
Scheme: "http",
Host: gr.Host,
Path: "/uptoken",
}
query := u.Query()
query.Set("private_token", gr.Token)
query.Set("bucket", bucket)
query.Set("key", key)
u.RawQuery = query.Encode()
resp, err := http.Get(u.String())
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
sysio.Copy(os.Stdout, resp.Body)
log.Fatalf("status: %d", resp.StatusCode)
}
uptoken, _ := ioutil.ReadAll(resp.Body)
return string(uptoken)
}
putPolicy := rs.PutPolicy{
Scope: bucket + ":" + key,
}
return putPolicy.Token(nil)
}
func uploadFile(bucket, key, filename string) error {
uptoken := genUptoken(bucket, key) // in order to rewrite exists file
var ret io.PutRet
var extra = &io.PutExtra{
ChunkSize: 256 << 10,
TryTimes: 5,
}
return io.PutFile(nil, &ret, uptoken, key, filename, extra)
}
func syncDir(bucket, keyPrefix, dir string) int {
keyPrefix = strings.TrimPrefix(keyPrefix, "/")
errCount := 0
wg := &sync.WaitGroup{}
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}
rel, _ := filepath.Rel(dir, path)
key := filepath.Join(keyPrefix, rel)
wg.Add(1)
go func() {
log.Printf("Upload %v ...", strconv.Quote(key))
if err := uploadFile(bucket, key, path); err != nil {
errCount += 1
log.Printf("Failed %v, %v", strconv.Quote(path), err)
} else {
log.Printf("Done %v", strconv.Quote(key))
}
wg.Done()
}()
return nil
})
wg.Wait()
return errCount
}
func main() {
cfgFile := flag.String("c", "conf.ini", "config file")
flag.Parse()
if err := gcfg.ReadFileInto(&cfg, *cfgFile); err != nil {
log.Fatal(err)
}
conf.ACCESS_KEY = cfg.Qiniu.AccessKey
conf.SECRET_KEY = cfg.Qiniu.SecretKey
conf.UP_HOST = cfg.Qiniu.UpHost
log.Printf("Use upload host: %v", conf.UP_HOST)
errcnt := syncDir(cfg.Qiniu.Bucket, cfg.Qiniu.KeyPrefix, cfg.Local.SyncDir)
if errcnt != 0 {
log.Println("Failed count =", errcnt)
os.Exit(1)
}
}