-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfile.go
195 lines (159 loc) · 4.9 KB
/
file.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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
package seafile
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"mime/multipart"
"net/http"
"net/url"
)
//上传文件内容
// fileContentMap的key是文件名,value是文件内容
//当目标文件存在时,会自动重命名上传
func (lib *Library) UploadFileContent(dir string, fileContentMap map[string][]byte) error {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
//填充文件内容
for filename, content := range fileContentMap {
part, err := writer.CreateFormFile("file", filename)
if err != nil {
return fmt.Errorf("创建Multipart错误:%s", err)
}
part.Write(content)
}
//填充其他字段
writer.WriteField("replace", "1")
writer.WriteField("parent_dir", "/")
writer.WriteField("relative_path", dir)
err := writer.Close()
if err != nil {
return fmt.Errorf("写Multipart文件错误:%s", err)
}
//设置请求Header
header := http.Header{"Content-Type": {writer.FormDataContentType()}}
//获取上传地址
uploadLink, err := lib.UploadLink()
if err != nil {
return fmt.Errorf("获取上传地址错误:%s", err)
}
//执行上传
resp, err := lib.client.request("POST", uploadLink+"?ret-json=1", header, body)
if err != nil {
return fmt.Errorf("请求错误:%s", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
b, _ := ioutil.ReadAll(resp.Body)
return fmt.Errorf("[%s] %s", resp.Status, string(b))
}
respInfo := []DirectoryEntry{}
err = json.NewDecoder(resp.Body).Decode(&respInfo)
if err != nil {
return fmt.Errorf("解析错误:%s", err)
}
return nil
}
//删除文件
func (lib *Library) RemoveFile(file string) error {
query := url.Values{"p": {file}}
resp, err := lib.doRequest("DELETE", "/file/?"+query.Encode(), nil, nil)
if err != nil {
return fmt.Errorf("请求错误:%s", err)
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("读取错误:%s %s", resp.Status, err)
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("错误:%s %s", resp.Status, string(b))
}
return nil
}
//生成文件下载的链接
// 该链接有效期只有一个小时,过期后无效
// reuse设置为true时可以不限访问次数,否则访问一次后链接就无效
func (lib *Library) GenerateFileDownloadLink(path string, reuse bool) (string, error) {
q := url.Values{"p": {path}}
if reuse {
q.Set("reuse", "1")
}
resp, err := lib.doRequest("GET", "/file/?"+q.Encode(), nil, nil)
if err != nil {
return "", fmt.Errorf("请求错误:%s", err)
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil || len(b) == 0 {
return "", fmt.Errorf("读取下载地址错误: %s", err)
}
//需要去掉头尾的引号
return string(b[1 : len(b)-1]), nil
}
//获取文件内容
func (lib *Library) FetchFileContent(path string) ([]byte, error) {
link, err := lib.GenerateFileDownloadLink(path, false)
if err != nil {
return nil, fmt.Errorf("请求下载地址错误:%s", err)
}
resp, err := http.Get(link)
if err != nil {
return nil, fmt.Errorf("读取文件内容错误: %s", err)
}
defer resp.Body.Close()
return ioutil.ReadAll(resp.Body)
}
//复制文件到另一个资料库的指定目录
//Note:
// 目标目录必须存在
// 目标目录下如果有同名文件,新文件会自动重命名
func (lib *Library) CopyFileToLibrary(path, dstLibId, dstLibPath string) error {
q := url.Values{"p": {path}}
d := url.Values{
"operation": {"copy"},
"dst_repo": {dstLibId},
"dst_dir": {dstLibPath},
}
body := bytes.NewBufferString(d.Encode())
hdr := http.Header{"Content-Type": {"application/x-www-form-urlencoded"}}
resp, err := lib.doRequest("POST", "/file/?"+q.Encode(), hdr, body)
if err != nil {
return fmt.Errorf("请求错误:%s", err)
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil || len(b) == 0 {
return fmt.Errorf("读取错误: %s", err)
}
//FIXME:文档上说返回HTTP 301为成功,实测却是HTTP 200。
if resp.StatusCode == http.StatusOK {
return nil
}
return fmt.Errorf("[%s] %s", resp.Status, string(b))
}
//复制文件到另一个资料库的指定目录,目标目录必须存在
func (lib *Library) MoveFileToLibrary(path, dstLibId, dstLibPath string) error {
q := url.Values{"p": {path}}
d := url.Values{
"operation": {"move"},
"dst_repo": {dstLibId},
"dst_dir": {dstLibPath},
}
body := bytes.NewBufferString(d.Encode())
hdr := http.Header{"Content-Type": {"application/x-www-form-urlencoded"}}
resp, err := lib.doRequest("POST", "/file/?"+q.Encode(), hdr, body)
if err != nil {
return fmt.Errorf("请求错误:%s", err)
}
defer resp.Body.Close()
b, err := ioutil.ReadAll(resp.Body)
if err != nil || len(b) == 0 {
return fmt.Errorf("读取错误: %s", err)
}
//FIXME:文档上说返回HTTP 301为成功,实测却是HTTP 200。
if resp.StatusCode == http.StatusOK {
return nil
}
return fmt.Errorf("[%s] %s", resp.Status, string(b))
}