35
|
1 /*
|
36
|
2 Last Change: 2019-11-21 Thu 02:11:35.
|
35
|
3
|
36
|
4 gf.go: Get Files (ver.0.6)
|
35
|
5
|
|
6 ./gf.json: server & file list
|
|
7 e.g.
|
|
8 {
|
|
9 "Server": {
|
36
|
10 "Address": "hoge.com",
|
35
|
11 "Port": "80"
|
|
12 },
|
|
13 "Files": [
|
|
14 "mahjong.html",
|
|
15 "gammon",
|
|
16 "gammon/backgammon.html"
|
|
17 ]
|
|
18 }
|
|
19
|
|
20 TODO:
|
36
|
21 + reserve dirtree option [-r]
|
|
22 + gunzip/untar option
|
35
|
23 */
|
|
24 package main
|
|
25
|
|
26 import (
|
|
27 "encoding/json"
|
|
28 "fmt"
|
|
29 "flag"
|
|
30 "io/ioutil"
|
|
31 "log"
|
|
32 "os"
|
|
33 "path"
|
36
|
34 "path/filepath"
|
35
|
35 "net/http"
|
|
36 )
|
|
37
|
36
|
38 const version = "0.6"
|
35
|
39 const defaultjson = "gf.json"
|
36
|
40 const samplejson = `{
|
|
41 "Server": {
|
|
42 "Address": "hoge.com",
|
|
43 "Port": "80"
|
|
44 },
|
|
45 "Files": [
|
|
46 "mahjong.html",
|
|
47 "gammon/backgammon.html"
|
|
48 ]
|
|
49 }`
|
35
|
50
|
|
51 type SV struct {
|
|
52 Address string
|
|
53 Port string
|
|
54 }
|
|
55
|
|
56 func (sv SV) String() string {
|
|
57 return sv.Address + ":" + sv.Port
|
|
58 }
|
|
59
|
|
60 type GF struct {
|
|
61 Server SV
|
|
62 Files []string
|
|
63 }
|
|
64
|
36
|
65 type HO struct { // html object
|
|
66 Status string
|
|
67 StatusCode int
|
|
68 Content []byte
|
|
69 }
|
|
70
|
|
71 // option valiables
|
35
|
72 var (
|
|
73 ver bool
|
|
74 quiet bool
|
|
75 jsonfile string
|
36
|
76 sample bool
|
|
77 somefile string
|
|
78 tdir string
|
35
|
79 )
|
|
80
|
|
81 func init() {
|
|
82 flag.BoolVar(&ver, "v", false, "version.")
|
|
83 flag.BoolVar(&quiet, "s", false, "silence.")
|
|
84 flag.StringVar(&jsonfile, "j", defaultjson, "specify json file.")
|
36
|
85 flag.BoolVar(&sample, "p", false, "print json sample.")
|
|
86 flag.StringVar(&somefile, "o", "", "get specity file.")
|
|
87 flag.StringVar(&tdir, "d", "", "specity save directory.")
|
35
|
88 }
|
|
89
|
|
90 func main() {
|
|
91 flag.Parse()
|
|
92
|
|
93 if ver {
|
|
94 fmt.Println("gf", version)
|
36
|
95 flag.PrintDefaults()
|
35
|
96 os.Exit(0)
|
|
97 }
|
|
98
|
36
|
99 if sample {
|
|
100 fmt.Println(samplejson)
|
|
101 os.Exit(0)
|
|
102 }
|
|
103
|
|
104 if somefile != "" {
|
|
105 ho, err := http_get(somefile)
|
|
106 if err != nil {
|
|
107 log.Fatal(err)
|
|
108 }
|
|
109 fmt.Print(string(ho.Content))
|
|
110 os.Exit(0)
|
|
111 }
|
|
112
|
35
|
113 content, err := ioutil.ReadFile(jsonfile)
|
|
114 if err != nil {
|
|
115 log.Fatal(err)
|
|
116 }
|
|
117
|
|
118 var gf GF
|
|
119
|
|
120 err = json.Unmarshal(content, &gf)
|
|
121 if err != nil {
|
|
122 log.Fatal(err)
|
|
123 }
|
36
|
124
|
|
125 if tdir != "" {
|
|
126 if err := os.Mkdir(tdir, 0755); err != nil {
|
|
127 log.Fatal(err)
|
|
128 }
|
|
129 }
|
|
130
|
35
|
131 n := len(gf.Files)
|
|
132 if n > 1 {
|
36
|
133 print_msg(fmt.Sprintf("%d files downloading", n))
|
35
|
134 }
|
|
135
|
36
|
136 ch := make(chan string)
|
35
|
137 for _, f := range gf.Files {
|
36
|
138 go http_gets(gf.Server.String(), f, ch)
|
35
|
139 }
|
36
|
140
|
|
141 for range gf.Files {
|
|
142 print_msg(<-ch)
|
|
143 }
|
35
|
144 }
|
|
145
|
36
|
146 func http_get(url string) (HO, error) {
|
|
147 var ho HO
|
|
148
|
35
|
149 res, err := http.Get(url)
|
|
150 if err != nil {
|
36
|
151 return ho, err
|
35
|
152 }
|
|
153
|
|
154 content, err := ioutil.ReadAll(res.Body)
|
|
155 res.Body.Close()
|
|
156 if err != nil {
|
36
|
157 return ho, err
|
35
|
158 }
|
|
159
|
36
|
160 ho.Status = res.Status
|
|
161 ho.StatusCode = res.StatusCode
|
|
162 ho.Content = content
|
|
163
|
|
164 return ho, nil
|
35
|
165 }
|
|
166
|
36
|
167 func http_gets(server, file string, ch chan<- string) {
|
|
168 msg := " getting " + file + "... "
|
|
169
|
|
170 url := "http://" + server + "/" + file
|
|
171
|
|
172 ho, err := http_get(url)
|
|
173 if err != nil {
|
|
174 ch <- msg + fmt.Sprint(err)
|
|
175 return
|
|
176 }
|
|
177
|
|
178 if ho.StatusCode == http.StatusOK {
|
|
179 file = path.Base(file)
|
|
180 if tdir != "" {
|
|
181 file = filepath.Join(tdir, file)
|
|
182 }
|
|
183 if err := ioutil.WriteFile(file, ho.Content, 0644); err != nil {
|
|
184 ch <- msg + fmt.Sprint(err)
|
|
185 return
|
|
186 }
|
|
187 }
|
|
188
|
|
189 ch <- msg + "[" + ho.Status + "]"
|
|
190 }
|
|
191
|
|
192 func print_msg(msg string) {
|
|
193 if !quiet {
|
|
194 fmt.Println(msg)
|
35
|
195 }
|
|
196 }
|
|
197
|