Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/drivers/alias/util.go
1987 views
1
package alias
2
3
import (
4
"context"
5
"fmt"
6
"net/url"
7
stdpath "path"
8
"strings"
9
10
"github.com/alist-org/alist/v3/internal/driver"
11
"github.com/alist-org/alist/v3/internal/errs"
12
"github.com/alist-org/alist/v3/internal/fs"
13
"github.com/alist-org/alist/v3/internal/model"
14
"github.com/alist-org/alist/v3/internal/op"
15
"github.com/alist-org/alist/v3/internal/sign"
16
"github.com/alist-org/alist/v3/pkg/utils"
17
"github.com/alist-org/alist/v3/server/common"
18
)
19
20
func (d *Alias) listRoot() []model.Obj {
21
var objs []model.Obj
22
for k := range d.pathMap {
23
obj := model.Object{
24
Name: k,
25
IsFolder: true,
26
Modified: d.Modified,
27
}
28
objs = append(objs, &obj)
29
}
30
return objs
31
}
32
33
// do others that not defined in Driver interface
34
func getPair(path string) (string, string) {
35
//path = strings.TrimSpace(path)
36
if strings.Contains(path, ":") {
37
pair := strings.SplitN(path, ":", 2)
38
if !strings.Contains(pair[0], "/") {
39
return pair[0], pair[1]
40
}
41
}
42
return stdpath.Base(path), path
43
}
44
45
func (d *Alias) getRootAndPath(path string) (string, string) {
46
if d.autoFlatten {
47
return d.oneKey, path
48
}
49
path = strings.TrimPrefix(path, "/")
50
parts := strings.SplitN(path, "/", 2)
51
if len(parts) == 1 {
52
return parts[0], ""
53
}
54
return parts[0], parts[1]
55
}
56
57
func (d *Alias) get(ctx context.Context, path string, dst, sub string) (model.Obj, error) {
58
obj, err := fs.Get(ctx, stdpath.Join(dst, sub), &fs.GetArgs{NoLog: true})
59
if err != nil {
60
return nil, err
61
}
62
return &model.Object{
63
Path: path,
64
Name: obj.GetName(),
65
Size: obj.GetSize(),
66
Modified: obj.ModTime(),
67
IsFolder: obj.IsDir(),
68
HashInfo: obj.GetHash(),
69
}, nil
70
}
71
72
func (d *Alias) list(ctx context.Context, dst, sub string, args *fs.ListArgs) ([]model.Obj, error) {
73
objs, err := fs.List(ctx, stdpath.Join(dst, sub), args)
74
// the obj must implement the model.SetPath interface
75
// return objs, err
76
if err != nil {
77
return nil, err
78
}
79
return utils.SliceConvert(objs, func(obj model.Obj) (model.Obj, error) {
80
thumb, ok := model.GetThumb(obj)
81
objRes := model.Object{
82
Name: obj.GetName(),
83
Size: obj.GetSize(),
84
Modified: obj.ModTime(),
85
IsFolder: obj.IsDir(),
86
}
87
if !ok {
88
return &objRes, nil
89
}
90
return &model.ObjThumb{
91
Object: objRes,
92
Thumbnail: model.Thumbnail{
93
Thumbnail: thumb,
94
},
95
}, nil
96
})
97
}
98
99
func (d *Alias) link(ctx context.Context, dst, sub string, args model.LinkArgs) (*model.Link, error) {
100
reqPath := stdpath.Join(dst, sub)
101
// 参考 crypt 驱动
102
storage, reqActualPath, err := op.GetStorageAndActualPath(reqPath)
103
if err != nil {
104
return nil, err
105
}
106
if _, ok := storage.(*Alias); !ok && !args.Redirect {
107
link, _, err := op.Link(ctx, storage, reqActualPath, args)
108
return link, err
109
}
110
_, err = fs.Get(ctx, reqPath, &fs.GetArgs{NoLog: true})
111
if err != nil {
112
return nil, err
113
}
114
if common.ShouldProxy(storage, stdpath.Base(sub)) {
115
link := &model.Link{
116
URL: fmt.Sprintf("%s/p%s?sign=%s",
117
common.GetApiUrl(args.HttpReq),
118
utils.EncodePath(reqPath, true),
119
sign.Sign(reqPath)),
120
}
121
if args.HttpReq != nil && d.ProxyRange {
122
link.RangeReadCloser = common.NoProxyRange
123
}
124
return link, nil
125
}
126
link, _, err := op.Link(ctx, storage, reqActualPath, args)
127
return link, err
128
}
129
130
func (d *Alias) getReqPath(ctx context.Context, obj model.Obj, isParent bool) (*string, error) {
131
root, sub := d.getRootAndPath(obj.GetPath())
132
if sub == "" && !isParent {
133
return nil, errs.NotSupport
134
}
135
dsts, ok := d.pathMap[root]
136
if !ok {
137
return nil, errs.ObjectNotFound
138
}
139
var reqPath *string
140
for _, dst := range dsts {
141
path := stdpath.Join(dst, sub)
142
_, err := fs.Get(ctx, path, &fs.GetArgs{NoLog: true})
143
if err != nil {
144
continue
145
}
146
if !d.ProtectSameName {
147
return &path, nil
148
}
149
if ok {
150
ok = false
151
} else {
152
return nil, errs.NotImplement
153
}
154
reqPath = &path
155
}
156
if reqPath == nil {
157
return nil, errs.ObjectNotFound
158
}
159
return reqPath, nil
160
}
161
162
func (d *Alias) getArchiveMeta(ctx context.Context, dst, sub string, args model.ArchiveArgs) (model.ArchiveMeta, error) {
163
reqPath := stdpath.Join(dst, sub)
164
storage, reqActualPath, err := op.GetStorageAndActualPath(reqPath)
165
if err != nil {
166
return nil, err
167
}
168
if _, ok := storage.(driver.ArchiveReader); ok {
169
return op.GetArchiveMeta(ctx, storage, reqActualPath, model.ArchiveMetaArgs{
170
ArchiveArgs: args,
171
Refresh: true,
172
})
173
}
174
return nil, errs.NotImplement
175
}
176
177
func (d *Alias) listArchive(ctx context.Context, dst, sub string, args model.ArchiveInnerArgs) ([]model.Obj, error) {
178
reqPath := stdpath.Join(dst, sub)
179
storage, reqActualPath, err := op.GetStorageAndActualPath(reqPath)
180
if err != nil {
181
return nil, err
182
}
183
if _, ok := storage.(driver.ArchiveReader); ok {
184
return op.ListArchive(ctx, storage, reqActualPath, model.ArchiveListArgs{
185
ArchiveInnerArgs: args,
186
Refresh: true,
187
})
188
}
189
return nil, errs.NotImplement
190
}
191
192
func (d *Alias) extract(ctx context.Context, dst, sub string, args model.ArchiveInnerArgs) (*model.Link, error) {
193
reqPath := stdpath.Join(dst, sub)
194
storage, reqActualPath, err := op.GetStorageAndActualPath(reqPath)
195
if err != nil {
196
return nil, err
197
}
198
if _, ok := storage.(driver.ArchiveReader); ok {
199
if _, ok := storage.(*Alias); !ok && !args.Redirect {
200
link, _, err := op.DriverExtract(ctx, storage, reqActualPath, args)
201
return link, err
202
}
203
_, err = fs.Get(ctx, reqPath, &fs.GetArgs{NoLog: true})
204
if err != nil {
205
return nil, err
206
}
207
if common.ShouldProxy(storage, stdpath.Base(sub)) {
208
link := &model.Link{
209
URL: fmt.Sprintf("%s/ap%s?inner=%s&pass=%s&sign=%s",
210
common.GetApiUrl(args.HttpReq),
211
utils.EncodePath(reqPath, true),
212
utils.EncodePath(args.InnerPath, true),
213
url.QueryEscape(args.Password),
214
sign.SignArchive(reqPath)),
215
}
216
if args.HttpReq != nil && d.ProxyRange {
217
link.RangeReadCloser = common.NoProxyRange
218
}
219
return link, nil
220
}
221
link, _, err := op.DriverExtract(ctx, storage, reqActualPath, args)
222
return link, err
223
}
224
return nil, errs.NotImplement
225
}
226
227