8000 feat(alist_v3): support forward archive requests (#8230) · anwen-anyi/alist@704d385 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit 704d385

Browse files
authored
feat(alist_v3): support forward archive requests (AlistGo#8230)
* feat(alist_v3): support forward archive requests * fix: encode all inner path
1 parent 44cc71d commit 704d385

File tree

4 files changed

+239
-24
lines changed

4 files changed

+239
-24
lines changed

drivers/alist_v3/driver.go

Lines changed: 134 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import (
55
"fmt"
66
"io"
77
"net/http"
8+
"net/url"
89
"path"
910
"strings"
1011

1112
"github.com/alist-org/alist/v3/drivers/base"
1213
"github.com/alist-org/alist/v3/internal/conf"
1314
"github.com/alist-org/alist/v3/internal/driver"
15+
"github.com/alist-org/alist/v3/internal/errs"
1416
"github.com/alist-org/alist/v3/internal/model"
1517
"github.com/alist-org/alist/v3/pkg/utils"
1618
"github.com/alist-org/alist/v3/server/common"
@@ -34,7 +36,7 @@ func (d *AListV3) GetAddition() driver.Additional {
3436
func (d *AListV3) Init(ctx context.Context) error {
3537
d.Addition.Address = strings.TrimSuffix(d.Addition.Address, "/")
3638
var resp common.Resp[MeResp]
37-
_, err := d.request("/me", http.MethodGet, func(req *resty.Request) {
39+
_, _, err := d.request("/me", http.MethodGet, func(req *resty.Request) {
3840
req.SetResult(&resp)
3941
})
4042
if err != nil {
@@ -48,15 +50,15 @@ func (d *AListV3) Init(ctx context.Context) error {
4850
}
4951
}
5052
// re-get the user info
51-
_, err = d.request("/me", http.MethodGet, func(req *resty.Request) {
53+
_, _, err = d.request("/me", http.MethodGet, func(req *resty.Request) {
5254
req.SetResult(&resp)
5355
})
5456
if err != nil {
5557
return err
5658
}
5759
if resp.Data.Role == model.GUEST {
58-
url := d.Address + "/api/public/settings"
59-
res, err := base.RestyClient.R().Get(url)
60+
u := d.Address + "/api/public/settings"
61+
res, err := base.RestyClient.R().Get(u)
6062
if err != nil {
6163
return err
6264
}
@@ -74,7 +76,7 @@ func (d *AListV3) Drop(ctx context.Context) error {
7476

7577
func (d *AListV3) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
7678
var resp common.Resp[FsListResp]
77-
_, err := d.request("/fs/list", http.MethodPost, func(req *resty.Request) {
79+
_, _, err := d.request("/fs/list", http.MethodPost, func(req *resty.Request) {
7880
req.SetResult(&resp).SetBody(ListReq{
7981
PageReq: model.PageReq{
8082
Page: 1,
@@ -116,7 +118,7 @@ func (d *AListV3) Link(ctx context.Context, file model.Obj, args model.LinkArgs)
116118
userAgent = base.UserAgent
117119
}
118120
}
119-
_, err := d.request("/fs/get", http.MethodPost, func(req *resty.Request) {
121+
_, _, err := d.request("/fs/get", http.MethodPost, func(req *resty.Request) {
120122
req.SetResult(&resp).SetBody(FsGetReq{
121123
Path: file.GetPath(),
122124
Password: d.MetaPassword,
@@ -131,7 +133,7 @@ func (d *AListV3) Link(ctx context.Context, file model.Obj, args model.LinkArgs)
131133
}
132134

133135
func (d *AListV3) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
134-
_, err := d.request("/fs/mkdir", http.MethodPost, func(req *resty.Request) {
136+
_, _, err := d.request("/fs/mkdir", http.MethodPost, func(req *resty.Request) {
135137
req.SetBody(MkdirOrLinkReq{
136138
Path: path.Join(parentDir.GetPath(), dirName),
137139
})
@@ -140,7 +142,7 @@ func (d *AListV3) MakeDir(ctx context.Context, parentDir model.Obj, dirName stri
140142
}
141143

142144
func (d *AListV3) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
143-
_, err := d.request("/fs/move", http.MethodPost, func(req *resty.Request) {
145+
_, _, err := d.request("/fs/move", http.MethodPost, func(req *resty.Request) {
144146
req.SetBody(MoveCopyReq{
145147
SrcDir: path.Dir(srcObj.GetPath()),
146148
DstDir: dstDir.GetPath(),
@@ -151,7 +153,7 @@ func (d *AListV3) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
151153
}
152154

153155
func (d *AListV3) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
154-
_, err := d.request("/fs/rename", http.MethodPost, func(req *resty.Request) {
156+
_, _, err := d.request("/fs/rename", http.MethodPost, func(req *resty.Request) {
155157
req.SetBody(RenameReq{
156158
Path: srcObj.GetPath(),
157159
Name: newName,
@@ -161,7 +163,7 @@ func (d *AListV3) Rename(ctx context.Context, srcObj model.Obj, newName string)
161163
}
162164

163165
func (d *AListV3) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
164-
_, err := d.request("/fs/copy", http.MethodPost, func(req *resty.Request) {
166+
_, _, err := d.request("/fs/copy", http.MethodPost, func(req *resty.Request) {
165167
req.SetBody(MoveCopyReq{
166168
SrcDir: path.Dir(srcObj.GetPath()),
167169
DstDir: dstDir.GetPath(),
@@ -172,7 +174,7 @@ func (d *AListV3) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
172174
}
173175

174176
func (d *AListV3) Remove(ctx context.Context, obj model.Obj) error {
175-
_, err := d.request("/fs/remove", http.MethodPost, func(req *resty.Request) {
177+
_, _, err := d.request("/fs/remove", http.MethodPost, func(req *resty.Request) {
176178
req.SetBody(RemoveReq{
177179
Dir: path.Dir(obj.GetPath()),
178180
Names: []string{obj.GetName()},
@@ -232,6 +234,127 @@ func (d *AListV3) Put(ctx context.Context, dstDir model.Obj, s model.FileStreame
232234
return nil
233235
}
234236

237+
func (d *AListV3) GetArchiveMeta(ctx context.Context, obj model.Obj, args model.ArchiveArgs) (model.ArchiveMeta, error) {
238+
if !d.ForwardArchiveReq {
239+
return nil, errs.NotImplement
240+
}
241+
var resp common.Resp[ArchiveMetaResp]
242+
_, code, err := d.request("/fs/archive/meta", http.MethodPost, func(req *resty.Request) {
243+
req.SetResult(&resp).SetBody(ArchiveMetaReq{
244+
ArchivePass: args.Password,
245+
Password: d.MetaPassword,
246+
Path: obj.GetPath(),
247+
Refresh: false,
248+
})
249+
})
250+
if code == 202 {
251+
return nil, errs.WrongArchivePassword
252+
}
253+
if err != nil {
254+
return nil, err
255+
}
256+
var tree []model.ObjTree
257+
if resp.Data.Content != nil {
258+
tree = make([]model.ObjTree, 0, len(resp.Data.Content))
259+
for _, content := range resp.Data.Content {
260+
tree = append(tree, &content)
261+
}
262+
}
263+
return &model.ArchiveMetaInfo{
264+
Comment: resp.Data.Comment,
265+
Encrypted: resp.Data.Encrypted,
266+
Tree: tree,
267+
}, nil
268+
}
269+
270+
func (d *AListV3) ListArchive(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) ([]model.Obj, error) {
271+
if !d.ForwardArchiveReq {
272+
return nil, errs.NotImplement
273+
}
274+
var resp common.Resp[ArchiveListResp]
275+
_, code, err := d.request("/fs/archive/list", http.MethodPost, func(req *resty.Request) {
276+
req.SetResult(&resp).SetBody(ArchiveListReq{
277+
ArchiveMetaReq: ArchiveMetaReq{
278+
ArchivePass: args.Password,
279+
Password: d.MetaPassword,
280+
Path: obj.GetPath(),
281+
Refresh: false,
282+
},
283+
PageReq: model.PageReq{
284+
Page: 1,
285+
PerPage: 0,
286+
},
287+
InnerPath: args.InnerPath,
288+
})
289+
})
290+
if code == 202 {
291+
return nil, errs.WrongArchivePassword
292+
}
293+
if err != nil {
294+
return nil, err
295+
}
296+
var files []model.Obj
297+
for _, f := range resp.Data.Content {
298+
file := model.ObjThumb{
299+
Object: model.Object{
300+
Name: f.Name,
301+
Modified: f.Modified,
302+
Ctime: f.Created,
303+
Size: f.Size,
304+
IsFolder: f.IsDir,
305+
HashInfo: utils.FromString(f.HashInfo),
306+
},
307+
Thumbnail: model.Thumbnail{Thumbnail: f.Thumb},
308+
}
309+
files = append(files, &file)
310+
}
311+
return files, nil
312+
}
313+
314+
func (d *AListV3) Extract(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) (*model.Link, error) {
315+
if !d.ForwardArchiveReq {
316+
return nil, errs.NotSupport
317+
}
318+
var resp common.Resp[ArchiveMetaResp]
319+
_, _, err := d.request("/fs/archive/meta", http.MethodPost, func(req *resty.Request) {
320+
req.SetResult(&resp).SetBody(ArchiveMetaReq{
321+
ArchivePass: args.Password,
322+
Password: d.MetaPassword,
323+
Path: obj.GetPath(),
324+
Refresh: false,
325+
})
326+
})
327+
if err != nil {
328+
return nil, err
329+
}
330+
return &model.Link{
331+
URL: fmt.Sprintf("%s?inner=%s&pass=%s&sign=%s",
332+
resp.Data.RawURL,
333+
utils.EncodePath(args.InnerPath, true),
334+
url.QueryEscape(args.Password),
335+
resp.Data.Sign),
336+
}, nil
337+
}
338+
339+
func (d *AListV3) ArchiveDecompress(ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) error {
340+
if !d.ForwardArchiveReq {
341+
return errs.NotImplement
342+
}
343+
dir, name := path.Split(srcObj.GetPath())
344+
_, _, err := d.request("/fs/archive/decompress", http.MethodPost, func(req *resty.Request) {
345+
req.SetBody(DecompressReq{
346+
ArchivePass: args.Password,
347+
CacheFull: args.CacheFull,
348+
DstDir: dstDir.GetPath(),
349+
InnerPath: args.InnerPath,
350+
Name: []string{name},
351+
PutIntoNewDir: args.PutIntoNewDir,
352+
SrcDir: dir,
353+
})
354+
})
355+
return err
356+
}
357+
235358
//func (d *AList) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
236359
// return nil, errs.NotSupport
237360
//}

drivers/alist_v3/meta.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import (
77

88
type Addition struct {
99
driver.RootPath
10-
Address string `json:"url" required:"true"`
11-
MetaPassword string `json:"meta_password"`
12-
Username string `json:"username"`
13-
Password string `json:"password"`
14-
Token string `json:"token"`
15-
PassUAToUpsteam bool `json:"pass_ua_to_upsteam" default:"true"`
10+
Address string `json:"url" required:"true"`
11+
MetaPassword string `json:"meta_password"`
12+
Username string `json:"username"`
13+
Password string `json:"password"`
14+
Token string `json:"token"`
15+
PassUAToUpsteam bool `json:"pass_ua_to_upsteam" default:"true"`
16+
ForwardArchiveReq bool `json:"forward_archive_requests" default:"true"`
1617
}
1718

1819
var config = driver.Config{

drivers/alist_v3/types.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"time"
55

66
"github.com/alist-org/alist/v3/internal/model"
7+
"github.com/alist-org/alist/v3/pkg/utils"
78
)
89

910
type ListReq struct {
@@ -81,3 +82,89 @@ type MeResp struct {
8182
SsoId string `json:"sso_id"`
8283
Otp bool `json:"otp"`
8384
}
85+
86+
type ArchiveMetaReq struct {
87+
ArchivePass string `json:"archive_pass"`
88+
Password string `json:"password"`
89+
Path string `json:"path"`
90+
Refresh bool `json:"refresh"`
91+
}
92+
93+
type TreeResp struct {
94+
ObjResp
95+
Children []TreeResp `json:"children"`
96+
hashCache *utils.HashInfo
97+
}
98+
99+
func (t *TreeResp) GetSize() int64 {
100+
return t.Size
101+
}
102+
103+
func (t *TreeResp) GetName() string {
104+
return t.Name
105+
}
106+
107+
func (t *TreeResp) ModTime() time.Time {
108+
return t.Modified
109+
}
110+
111+
func (t *TreeResp) CreateTime() time.Time {
112+
return t.Created
113+
}
114+
115+
func (t *TreeResp) IsDir() bool {
116+
return t.ObjResp.IsDir
117+
}
118+
119+
func (t *TreeResp) GetHash() utils.HashInfo {
120+
return utils.FromString(t.HashInfo)
121+
}
122+
123+
func (t *TreeResp) GetID() string {
124+
return ""
125+
}
126+
127+
func (t *TreeResp) GetPath() string {
128+
return ""
129+
}
130+
131+
func (t *TreeResp) GetChildren() []model.ObjTree {
132+
ret := make([]model.ObjTree, 0, len(t.Children))
133+
for _, child := range t.Children {
134+
ret = append(ret, &child)
135+
}
136+
return ret
137+
}
138+
139+
func (t *TreeResp) Thumb() string {
140+
return t.ObjResp.Thumb
141+
}
142+
143+
type ArchiveMetaResp struct {
144+
Comment string `json:"comment"`
145+
Encrypted bool `json:"encrypted"`
146+
Content []TreeResp `json:"content"`
147+
RawURL string `json:"raw_url"`
148+
Sign string `json:"sign"`
149+
}
150+
151+
type ArchiveListReq struct {
152+
model.PageReq
153+
ArchiveMetaReq
154+
InnerPath string `json:"inner_path"`
155+
}
156+
157+
type ArchiveListResp struct {
158+
Content []ObjResp `json:"content"`
159+
Total int64 `json:"total"`
160+
}
161+
162+
type DecompressReq struct {
163+
ArchivePass string `json:"archive_pass"`
164+
CacheFull bool `json:"cache_full"`
165+
DstDir string `json:"dst_dir"`
166+
InnerPath string `json:"inner_path"`
167+
Name []string `json:"name"`
168+
PutIntoNewDir bool `json:"put_into_new_dir"`
169+
SrcDir string `json:"src_dir"`
170+
}

0 commit comments

Comments
 (0)
0