Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/drivers/kodbox/driver.go
1986 views
1
package kodbox
2
3
import (
4
"context"
5
"fmt"
6
"net/http"
7
"path/filepath"
8
"strings"
9
"time"
10
11
"github.com/alist-org/alist/v3/internal/driver"
12
"github.com/alist-org/alist/v3/internal/model"
13
"github.com/alist-org/alist/v3/pkg/utils"
14
"github.com/go-resty/resty/v2"
15
)
16
17
type KodBox struct {
18
model.Storage
19
Addition
20
authorization string
21
}
22
23
func (d *KodBox) Config() driver.Config {
24
return config
25
}
26
27
func (d *KodBox) GetAddition() driver.Additional {
28
return &d.Addition
29
}
30
31
func (d *KodBox) Init(ctx context.Context) error {
32
d.Address = strings.TrimSuffix(d.Address, "/")
33
d.RootFolderPath = strings.TrimPrefix(utils.FixAndCleanPath(d.RootFolderPath), "/")
34
return d.getToken()
35
}
36
37
func (d *KodBox) Drop(ctx context.Context) error {
38
return nil
39
}
40
41
func (d *KodBox) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
42
var (
43
resp *CommonResp
44
listPathData *ListPathData
45
)
46
47
_, err := d.request(http.MethodPost, "/?explorer/list/path", func(req *resty.Request) {
48
req.SetResult(&resp).SetFormData(map[string]string{
49
"path": dir.GetPath(),
50
})
51
}, true)
52
if err != nil {
53
return nil, err
54
}
55
56
dataBytes, err := utils.Json.Marshal(resp.Data)
57
if err != nil {
58
return nil, err
59
}
60
61
err = utils.Json.Unmarshal(dataBytes, &listPathData)
62
if err != nil {
63
return nil, err
64
}
65
FolderAndFiles := append(listPathData.FolderList, listPathData.FileList...)
66
67
return utils.SliceConvert(FolderAndFiles, func(f FolderOrFile) (model.Obj, error) {
68
return &model.ObjThumb{
69
Object: model.Object{
70
Path: f.Path,
71
Name: f.Name,
72
Ctime: time.Unix(f.CreateTime, 0),
73
Modified: time.Unix(f.ModifyTime, 0),
74
Size: f.Size,
75
IsFolder: f.Type == "folder",
76
},
77
//Thumbnail: model.Thumbnail{},
78
}, nil
79
})
80
}
81
82
func (d *KodBox) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
83
path := file.GetPath()
84
return &model.Link{
85
URL: fmt.Sprintf("%s/?explorer/index/fileOut&path=%s&download=1&accessToken=%s",
86
d.Address,
87
path,
88
d.authorization)}, nil
89
}
90
91
func (d *KodBox) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {
92
var resp *CommonResp
93
newDirPath := filepath.Join(parentDir.GetPath(), dirName)
94
95
_, err := d.request(http.MethodPost, "/?explorer/index/mkdir", func(req *resty.Request) {
96
req.SetResult(&resp).SetFormData(map[string]string{
97
"path": newDirPath,
98
})
99
})
100
if err != nil {
101
return nil, err
102
}
103
code := resp.Code.(bool)
104
if !code {
105
return nil, fmt.Errorf("%s", resp.Data)
106
}
107
108
return &model.ObjThumb{
109
Object: model.Object{
110
Path: resp.Info.(string),
111
Name: dirName,
112
IsFolder: true,
113
Modified: time.Now(),
114
Ctime: time.Now(),
115
},
116
}, nil
117
}
118
119
func (d *KodBox) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
120
var resp *CommonResp
121
_, err := d.request(http.MethodPost, "/?explorer/index/pathCuteTo", func(req *resty.Request) {
122
req.SetResult(&resp).SetFormData(map[string]string{
123
"dataArr": fmt.Sprintf("[{\"path\": \"%s\", \"name\": \"%s\"}]",
124
srcObj.GetPath(),
125
srcObj.GetName()),
126
"path": dstDir.GetPath(),
127
})
128
}, true)
129
if err != nil {
130
return nil, err
131
}
132
code := resp.Code.(bool)
133
if !code {
134
return nil, fmt.Errorf("%s", resp.Data)
135
}
136
137
return &model.ObjThumb{
138
Object: model.Object{
139
Path: srcObj.GetPath(),
140
Name: srcObj.GetName(),
141
IsFolder: srcObj.IsDir(),
142
Modified: srcObj.ModTime(),
143
Ctime: srcObj.CreateTime(),
144
},
145
}, nil
146
}
147
148
func (d *KodBox) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) {
149
var resp *CommonResp
150
_, err := d.request(http.MethodPost, "/?explorer/index/pathRename", func(req *resty.Request) {
151
req.SetResult(&resp).SetFormData(map[string]string{
152
"path": srcObj.GetPath(),
153
"newName": newName,
154
})
155
}, true)
156
if err != nil {
157
return nil, err
158
}
159
code := resp.Code.(bool)
160
if !code {
161
return nil, fmt.Errorf("%s", resp.Data)
162
}
163
return &model.ObjThumb{
164
Object: model.Object{
165
Path: srcObj.GetPath(),
166
Name: newName,
167
IsFolder: srcObj.IsDir(),
168
Modified: time.Now(),
169
Ctime: srcObj.CreateTime(),
170
},
171
}, nil
172
}
173
174
func (d *KodBox) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
175
var resp *CommonResp
176
_, err := d.request(http.MethodPost, "/?explorer/index/pathCopyTo", func(req *resty.Request) {
177
req.SetResult(&resp).SetFormData(map[string]string{
178
"dataArr": fmt.Sprintf("[{\"path\": \"%s\", \"name\": \"%s\"}]",
179
srcObj.GetPath(),
180
srcObj.GetName()),
181
"path": dstDir.GetPath(),
182
})
183
})
184
if err != nil {
185
return nil, err
186
}
187
code := resp.Code.(bool)
188
if !code {
189
return nil, fmt.Errorf("%s", resp.Data)
190
}
191
192
path := resp.Info.([]interface{})[0].(string)
193
objectName, err := d.getFileOrFolderName(ctx, path)
194
if err != nil {
195
return nil, err
196
}
197
return &model.ObjThumb{
198
Object: model.Object{
199
Path: path,
200
Name: *objectName,
201
IsFolder: srcObj.IsDir(),
202
Modified: time.Now(),
203
Ctime: time.Now(),
204
},
205
}, nil
206
}
207
208
func (d *KodBox) Remove(ctx context.Context, obj model.Obj) error {
209
var resp *CommonResp
210
_, err := d.request(http.MethodPost, "/?explorer/index/pathDelete", func(req *resty.Request) {
211
req.SetResult(&resp).SetFormData(map[string]string{
212
"dataArr": fmt.Sprintf("[{\"path\": \"%s\", \"name\": \"%s\"}]",
213
obj.GetPath(),
214
obj.GetName()),
215
"shiftDelete": "1",
216
})
217
})
218
if err != nil {
219
return err
220
}
221
code := resp.Code.(bool)
222
if !code {
223
return fmt.Errorf("%s", resp.Data)
224
}
225
return nil
226
}
227
228
func (d *KodBox) Put(ctx context.Context, dstDir model.Obj, s model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) {
229
var resp *CommonResp
230
_, err := d.request(http.MethodPost, "/?explorer/upload/fileUpload", func(req *resty.Request) {
231
r := driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{
232
Reader: s,
233
UpdateProgress: up,
234
})
235
req.SetFileReader("file", s.GetName(), r).
236
SetResult(&resp).
237
SetFormData(map[string]string{
238
"path": dstDir.GetPath(),
239
}).
240
SetContext(ctx)
241
})
242
if err != nil {
243
return nil, err
244
}
245
code := resp.Code.(bool)
246
if !code {
247
return nil, fmt.Errorf("%s", resp.Data)
248
}
249
return &model.ObjThumb{
250
Object: model.Object{
251
Path: resp.Info.(string),
252
Name: s.GetName(),
253
Size: s.GetSize(),
254
IsFolder: false,
255
Modified: time.Now(),
256
Ctime: time.Now(),
257
},
258
}, nil
259
}
260
261
func (d *KodBox) getFileOrFolderName(ctx context.Context, path string) (*string, error) {
262
var resp *CommonResp
263
_, err := d.request(http.MethodPost, "/?explorer/index/pathInfo", func(req *resty.Request) {
264
req.SetResult(&resp).SetFormData(map[string]string{
265
"dataArr": fmt.Sprintf("[{\"path\": \"%s\"}]", path)})
266
})
267
if err != nil {
268
return nil, err
269
}
270
code := resp.Code.(bool)
271
if !code {
272
return nil, fmt.Errorf("%s", resp.Data)
273
}
274
folderOrFileName := resp.Data.(map[string]any)["name"].(string)
275
return &folderOrFileName, nil
276
}
277
278
var _ driver.Driver = (*KodBox)(nil)
279
280