diff --git a/cmd/lang.go b/cmd/lang.go index c18877cd70..0615b1223d 100644 --- a/cmd/lang.go +++ b/cmd/lang.go @@ -10,7 +10,6 @@ import ( "os" "strings" - _ "github.com/OpenListTeam/OpenList/v4/drivers" "github.com/OpenListTeam/OpenList/v4/internal/bootstrap" "github.com/OpenListTeam/OpenList/v4/internal/bootstrap/data" "github.com/OpenListTeam/OpenList/v4/internal/conf" diff --git a/cmd/root.go b/cmd/root.go index 42121aac7b..e01722594d 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -5,9 +5,10 @@ import ( "os" "github.com/OpenListTeam/OpenList/v4/cmd/flags" - _ "github.com/OpenListTeam/OpenList/v4/drivers" + "github.com/OpenListTeam/OpenList/v4/drivers" _ "github.com/OpenListTeam/OpenList/v4/internal/archive" _ "github.com/OpenListTeam/OpenList/v4/internal/offline_download" + "github.com/OpenListTeam/OpenList/v4/internal/op" "github.com/spf13/cobra" ) @@ -20,6 +21,10 @@ Complete documentation is available at https://doc.oplist.org/`, } func Execute() { + if err := op.InstallDrivers(drivers.All()); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } if err := RootCmd.Execute(); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) diff --git a/drivers/115/meta.go b/drivers/115/meta.go index 02c180c307..d0cbbbff6a 100644 --- a/drivers/115/meta.go +++ b/drivers/115/meta.go @@ -2,7 +2,6 @@ package _115 import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -20,8 +19,6 @@ var config = driver.Config{ LinkCacheMode: driver.LinkCacheUA, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Pan115{} - }) +func New() driver.Driver { + return &Pan115{} } diff --git a/drivers/115_open/meta.go b/drivers/115_open/meta.go index ed908e2e62..05940ca999 100644 --- a/drivers/115_open/meta.go +++ b/drivers/115_open/meta.go @@ -2,7 +2,6 @@ package _115_open import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -23,8 +22,6 @@ var config = driver.Config{ LinkCacheMode: driver.LinkCacheUA, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Open115{} - }) +func New() driver.Driver { + return &Open115{} } diff --git a/drivers/115_share/meta.go b/drivers/115_share/meta.go index d3b142e887..5634f32044 100644 --- a/drivers/115_share/meta.go +++ b/drivers/115_share/meta.go @@ -2,7 +2,6 @@ package _115_share import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,8 +21,6 @@ var config = driver.Config{ NoUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Pan115Share{} - }) +func New() driver.Driver { + return &Pan115Share{} } diff --git a/drivers/123/meta.go b/drivers/123/meta.go index 5b19ae82e4..ef9a7aee9c 100644 --- a/drivers/123/meta.go +++ b/drivers/123/meta.go @@ -2,7 +2,6 @@ package _123 import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -23,14 +22,12 @@ var config = driver.Config{ PreferProxy: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - // 新增默认选项 要在RegisterDriver初始化设置 才会对正在使用的用户生效 - return &Pan123{ - Addition: Addition{ - UploadThread: 3, - Platform: "web", - }, - } - }) +func New() driver.Driver { + // 新增默认选项 要在RegisterDriver初始化设置 才会对正在使用的用户生效 + return &Pan123{ + Addition: Addition{ + UploadThread: 3, + Platform: "web", + }, + } } diff --git a/drivers/123_link/meta.go b/drivers/123_link/meta.go index ab5e7dc133..4004a7bacb 100644 --- a/drivers/123_link/meta.go +++ b/drivers/123_link/meta.go @@ -2,7 +2,6 @@ package _123Link import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -16,8 +15,6 @@ var config = driver.Config{ Name: "123PanLink", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Pan123Link{} - }) +func New() driver.Driver { + return &Pan123Link{} } diff --git a/drivers/123_open/meta.go b/drivers/123_open/meta.go index d23f8eec65..1df8ba7073 100644 --- a/drivers/123_open/meta.go +++ b/drivers/123_open/meta.go @@ -2,7 +2,6 @@ package _123_open import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -42,8 +41,6 @@ var config = driver.Config{ PreferProxy: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Open123{} - }) +func New() driver.Driver { + return &Open123{} } diff --git a/drivers/123_share/meta.go b/drivers/123_share/meta.go index e40965fe96..68d0e4b0b7 100644 --- a/drivers/123_share/meta.go +++ b/drivers/123_share/meta.go @@ -2,7 +2,6 @@ package _123Share import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,8 +21,6 @@ var config = driver.Config{ PreferProxy: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Pan123Share{} - }) +func New() driver.Driver { + return &Pan123Share{} } diff --git a/drivers/139/meta.go b/drivers/139/meta.go index 8e963d705a..c8d72314f8 100644 --- a/drivers/139/meta.go +++ b/drivers/139/meta.go @@ -2,7 +2,6 @@ package _139 import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -29,10 +28,8 @@ var config = driver.Config{ ProxyRangeOption: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - d := &Yun139{} - d.ProxyRange = true - return d - }) +func New() driver.Driver { + d := &Yun139{} + d.ProxyRange = true + return d } diff --git a/drivers/189/meta.go b/drivers/189/meta.go index c989860bfc..8528d24ec0 100644 --- a/drivers/189/meta.go +++ b/drivers/189/meta.go @@ -2,7 +2,6 @@ package _189 import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -19,8 +18,6 @@ var config = driver.Config{ Alert: `info|You can try to use 189PC driver if this driver does not work.`, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Cloud189{} - }) +func New() driver.Driver { + return &Cloud189{} } diff --git a/drivers/189_tv/meta.go b/drivers/189_tv/meta.go index f50fe7ead1..12e2605cda 100644 --- a/drivers/189_tv/meta.go +++ b/drivers/189_tv/meta.go @@ -2,7 +2,6 @@ package _189_tv import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,8 +21,6 @@ var config = driver.Config{ CheckStatus: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Cloud189TV{} - }) +func New() driver.Driver { + return &Cloud189TV{} } diff --git a/drivers/189pc/meta.go b/drivers/189pc/meta.go index 3a5e02979d..190c7ef25d 100644 --- a/drivers/189pc/meta.go +++ b/drivers/189pc/meta.go @@ -2,7 +2,6 @@ package _189pc import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -31,8 +30,6 @@ var config = driver.Config{ CheckStatus: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Cloud189PC{} - }) +func New() driver.Driver { + return &Cloud189PC{} } diff --git a/drivers/alias/meta.go b/drivers/alias/meta.go index 72eb3c877e..faab8582cf 100644 --- a/drivers/alias/meta.go +++ b/drivers/alias/meta.go @@ -2,7 +2,6 @@ package alias import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -21,14 +20,11 @@ var config = driver.Config{ Name: "Alias", LocalSort: true, NoCache: true, - NoUpload: false, DefaultRoot: "/", ProxyRangeOption: true, LinkCacheMode: driver.LinkCacheAuto, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Alias{} - }) +func New() driver.Driver { + return &Alias{} } diff --git a/drivers/alidoc/meta.go b/drivers/alidoc/meta.go index 3c0fa19a94..e8fc30b1f5 100644 --- a/drivers/alidoc/meta.go +++ b/drivers/alidoc/meta.go @@ -2,7 +2,6 @@ package alidoc import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -11,13 +10,10 @@ type Addition struct { } var config = driver.Config{ - Name: "AliDoc", - LocalSort: true, - DefaultRoot: "", + Name: "AliDoc", + LocalSort: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &AliDoc{} - }) +func New() driver.Driver { + return &AliDoc{} } diff --git a/drivers/alist_v3/driver.go b/drivers/alist_v3/driver.go index ddfb0a9626..680587d6de 100644 --- a/drivers/alist_v3/driver.go +++ b/drivers/alist_v3/driver.go @@ -2,22 +2,14 @@ package alist_v3 import ( "context" - "fmt" - "io" "net/http" - "net/url" - "path" - "strings" - "github.com/OpenListTeam/OpenList/v4/drivers/base" - "github.com/OpenListTeam/OpenList/v4/internal/conf" + family "github.com/OpenListTeam/OpenList/v4/drivers/internal/openlist" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/errs" "github.com/OpenListTeam/OpenList/v4/internal/model" "github.com/OpenListTeam/OpenList/v4/pkg/utils" "github.com/OpenListTeam/OpenList/v4/server/common" "github.com/go-resty/resty/v2" - log "github.com/sirupsen/logrus" ) type AListV3 struct { @@ -25,356 +17,82 @@ type AListV3 struct { Addition } -func (d *AListV3) Config() driver.Config { - return config -} +func (d *AListV3) Config() driver.Config { return config } -func (d *AListV3) GetAddition() driver.Additional { - return &d.Addition -} +func (d *AListV3) GetAddition() driver.Additional { return &d.Addition } -func (d *AListV3) Init(ctx context.Context) error { - d.Addition.Address = strings.TrimSuffix(d.Addition.Address, "/") - var resp common.Resp[MeResp] - _, _, err := d.request("/me", http.MethodGet, func(req *resty.Request) { - req.SetResult(&resp) - }) - if err != nil { - return err - } - // if the username is not empty and the username is not the same as the current username, then login again - if d.Username != resp.Data.Username { - err = d.login() - if err != nil { - return err - } - } - // re-get the user info - _, _, err = d.request("/me", http.MethodGet, func(req *resty.Request) { - req.SetResult(&resp) - }) - if err != nil { - return err - } - if utils.SliceContains(resp.Data.Role, model.GUEST) { - u := d.Address + "/api/public/settings" - res, err := base.RestyClient.R().Get(u) - if err != nil { - return err - } - allowMounted := utils.Json.Get(res.Body(), "data", conf.AllowMounted).ToString() == "true" - if !allowMounted { - return fmt.Errorf("the site does not allow mounted") - } +func (d *AListV3) state() family.State { + return family.State{ + Driver: d, Address: &d.Address, MetaPassword: &d.MetaPassword, + Username: &d.Username, Password: &d.Password, Token: &d.Token, + PassIP: d.PassIPToUpsteam, PassUserAgent: d.PassUAToUpsteam, + ForwardArchives: d.ForwardArchiveReq, } - return err } -func (d *AListV3) Drop(ctx context.Context) error { - return nil +func (d *AListV3) Init(context.Context) error { + return family.Init(d.state(), func(s family.State) (family.Identity, error) { + var resp common.Resp[MeResp] + _, _, err := s.Request("/me", http.MethodGet, func(req *resty.Request) { req.SetResult(&resp) }) + return family.Identity{ + Username: resp.Data.Username, + Guest: utils.SliceContains(resp.Data.Role, model.GUEST), + }, err + }) } +func (d *AListV3) Drop(context.Context) error { return nil } + func (d *AListV3) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { - var resp common.Resp[FsListResp] - _, _, err := d.request("/fs/list", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(ListReq{ - PageReq: model.PageReq{ - Page: 1, - PerPage: 0, - }, - Path: dir.GetPath(), - Password: d.MetaPassword, - Refresh: false, - }) - }) - if err != nil { - return nil, err - } - var files []model.Obj - for _, f := range resp.Data.Content { - file := model.ObjThumb{ - Object: model.Object{ - Name: f.Name, - Path: path.Join(dir.GetPath(), f.Name), - Modified: f.Modified, - Ctime: f.Created, - Size: f.Size, - IsFolder: f.IsDir, - HashInfo: utils.FromString(f.HashInfo), - }, - Thumbnail: model.Thumbnail{Thumbnail: f.Thumb}, - } - files = append(files, &file) - } - return files, nil + return family.List(d.state(), ctx, dir, args) } func (d *AListV3) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { - var resp common.Resp[FsGetResp] - headers := map[string]string{ - "User-Agent": base.UserAgent, - } - // if PassUAToUpsteam is true, then pass the user-agent to the upstream - if d.PassUAToUpsteam { - userAgent := args.Header.Get("user-agent") - if userAgent != "" { - headers["User-Agent"] = userAgent - } - } - // if PassIPToUpsteam is true, then pass the ip address to the upstream - if d.PassIPToUpsteam { - ip := args.IP - if ip != "" { - headers["X-Forwarded-For"] = ip - headers["X-Real-Ip"] = ip - } - } - _, _, err := d.request("/fs/get", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(FsGetReq{ - Path: file.GetPath(), - Password: d.MetaPassword, - }).SetHeaders(headers) - }) - if err != nil { - return nil, err - } - return &model.Link{ - URL: resp.Data.RawURL, - }, nil + return family.Link(d.state(), ctx, file, args) } -func (d *AListV3) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error { - _, _, err := d.request("/fs/mkdir", http.MethodPost, func(req *resty.Request) { - req.SetBody(MkdirOrLinkReq{ - Path: path.Join(parentDir.GetPath(), dirName), - }) - }) - return err +func (d *AListV3) MakeDir(ctx context.Context, parent model.Obj, name string) error { + return family.MakeDir(d.state(), ctx, parent, name) } -func (d *AListV3) Move(ctx context.Context, srcObj, dstDir model.Obj) error { - _, _, err := d.request("/fs/move", http.MethodPost, func(req *resty.Request) { - req.SetBody(MoveCopyReq{ - SrcDir: path.Dir(srcObj.GetPath()), - DstDir: dstDir.GetPath(), - Names: []string{srcObj.GetName()}, - }) - }) - return err +func (d *AListV3) Move(ctx context.Context, src, dst model.Obj) error { + return family.Move(d.state(), ctx, src, dst) } -func (d *AListV3) Rename(ctx context.Context, srcObj model.Obj, newName string) error { - _, _, err := d.request("/fs/rename", http.MethodPost, func(req *resty.Request) { - req.SetBody(RenameReq{ - Path: srcObj.GetPath(), - Name: newName, - }) - }) - return err +func (d *AListV3) Rename(ctx context.Context, src model.Obj, name string) error { + return family.Rename(d.state(), ctx, src, name) } -func (d *AListV3) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { - _, _, err := d.request("/fs/copy", http.MethodPost, func(req *resty.Request) { - req.SetBody(MoveCopyReq{ - SrcDir: path.Dir(srcObj.GetPath()), - DstDir: dstDir.GetPath(), - Names: []string{srcObj.GetName()}, - }) - }) - return err +func (d *AListV3) Copy(ctx context.Context, src, dst model.Obj) error { + return family.Copy(d.state(), ctx, src, dst) } func (d *AListV3) Remove(ctx context.Context, obj model.Obj) error { - _, _, err := d.request("/fs/remove", http.MethodPost, func(req *resty.Request) { - req.SetBody(RemoveReq{ - Dir: path.Dir(obj.GetPath()), - Names: []string{obj.GetName()}, - }) - }) - return err + return family.Remove(d.state(), ctx, obj) } -func (d *AListV3) Put(ctx context.Context, dstDir model.Obj, s model.FileStreamer, up driver.UpdateProgress) error { - reader := driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{ - Reader: s, - UpdateProgress: up, - }) - req, err := http.NewRequestWithContext(ctx, http.MethodPut, d.Address+"/api/fs/put", reader) - if err != nil { - return err - } - req.Header.Set("Authorization", d.Token) - req.Header.Set("File-Path", path.Join(dstDir.GetPath(), s.GetName())) - req.Header.Set("Password", d.MetaPassword) - if md5 := s.GetHash().GetHash(utils.MD5); len(md5) > 0 { - req.Header.Set("X-File-Md5", md5) - } - if sha1 := s.GetHash().GetHash(utils.SHA1); len(sha1) > 0 { - req.Header.Set("X-File-Sha1", sha1) - } - if sha256 := s.GetHash().GetHash(utils.SHA256); len(sha256) > 0 { - req.Header.Set("X-File-Sha256", sha256) - } - - req.ContentLength = s.GetSize() - // client := base.NewHttpClient() - // client.Timeout = time.Hour * 6 - res, err := base.HttpClient.Do(req) - if err != nil { - return err - } - - bytes, err := io.ReadAll(res.Body) - if err != nil { - return err - } - log.Debugf("[openlist] response body: %s", string(bytes)) - if res.StatusCode >= 400 { - return fmt.Errorf("request failed, status: %s", res.Status) - } - code := utils.Json.Get(bytes, "code").ToInt() - if code != 200 { - if code == 401 || code == 403 { - err = d.login() - if err != nil { - return err - } - } - return fmt.Errorf("request failed,code: %d, message: %s", code, utils.Json.Get(bytes, "message").ToString()) - } - return nil +func (d *AListV3) Put(ctx context.Context, dst model.Obj, src model.FileStreamer, up driver.UpdateProgress) error { + return family.Put(d.state(), ctx, dst, src, up) } func (d *AListV3) GetArchiveMeta(ctx context.Context, obj model.Obj, args model.ArchiveArgs) (model.ArchiveMeta, error) { - if !d.ForwardArchiveReq { - return nil, errs.NotImplement - } - var resp common.Resp[ArchiveMetaResp] - _, code, err := d.request("/fs/archive/meta", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(ArchiveMetaReq{ - ArchivePass: args.Password, - Password: d.MetaPassword, - Path: obj.GetPath(), - Refresh: false, - }) - }) - if code == 202 { - return nil, errs.WrongArchivePassword - } - if err != nil { - return nil, err - } - var tree []model.ObjTree - if resp.Data.Content != nil { - tree = make([]model.ObjTree, 0, len(resp.Data.Content)) - for _, content := range resp.Data.Content { - tree = append(tree, &content) - } - } - return &model.ArchiveMetaInfo{ - Comment: resp.Data.Comment, - Encrypted: resp.Data.Encrypted, - Tree: tree, - }, nil + return family.GetArchiveMeta(d.state(), ctx, obj, args) } func (d *AListV3) ListArchive(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) ([]model.Obj, error) { - if !d.ForwardArchiveReq { - return nil, errs.NotImplement - } - var resp common.Resp[ArchiveListResp] - _, code, err := d.request("/fs/archive/list", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(ArchiveListReq{ - ArchiveMetaReq: ArchiveMetaReq{ - ArchivePass: args.Password, - Password: d.MetaPassword, - Path: obj.GetPath(), - Refresh: false, - }, - PageReq: model.PageReq{ - Page: 1, - PerPage: 0, - }, - InnerPath: args.InnerPath, - }) - }) - if code == 202 { - return nil, errs.WrongArchivePassword - } - if err != nil { - return nil, err - } - var files []model.Obj - for _, f := range resp.Data.Content { - file := model.ObjThumb{ - Object: model.Object{ - Name: f.Name, - Modified: f.Modified, - Ctime: f.Created, - Size: f.Size, - IsFolder: f.IsDir, - HashInfo: utils.FromString(f.HashInfo), - }, - Thumbnail: model.Thumbnail{Thumbnail: f.Thumb}, - } - files = append(files, &file) - } - return files, nil + return family.ListArchive(d.state(), ctx, obj, args) } func (d *AListV3) Extract(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) (*model.Link, error) { - if !d.ForwardArchiveReq { - return nil, errs.NotSupport - } - var resp common.Resp[ArchiveMetaResp] - _, _, err := d.request("/fs/archive/meta", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(ArchiveMetaReq{ - ArchivePass: args.Password, - Password: d.MetaPassword, - Path: obj.GetPath(), - Refresh: false, - }) - }) - if err != nil { - return nil, err - } - return &model.Link{ - URL: fmt.Sprintf("%s?inner=%s&pass=%s&sign=%s", - resp.Data.RawURL, - utils.EncodePath(args.InnerPath, true), - url.QueryEscape(args.Password), - resp.Data.Sign), - }, nil + return family.Extract(d.state(), ctx, obj, args) } -func (d *AListV3) ArchiveDecompress(ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) error { - if !d.ForwardArchiveReq { - return errs.NotImplement - } - dir, name := path.Split(srcObj.GetPath()) - _, _, err := d.request("/fs/archive/decompress", http.MethodPost, func(req *resty.Request) { - req.SetBody(DecompressReq{ - ArchivePass: args.Password, - CacheFull: args.CacheFull, - DstDir: dstDir.GetPath(), - InnerPath: args.InnerPath, - Name: []string{name}, - PutIntoNewDir: args.PutIntoNewDir, - SrcDir: dir, - }) - }) - return err +func (d *AListV3) ArchiveDecompress(ctx context.Context, src, dst model.Obj, args model.ArchiveDecompressArgs) error { + return family.ArchiveDecompress(d.state(), ctx, src, dst, args) } -func (d *AListV3) ResolveLinkCacheMode(_ string) driver.LinkCacheMode { - var mode driver.LinkCacheMode - if d.PassIPToUpsteam { - mode |= driver.LinkCacheIP - } - if d.PassUAToUpsteam { - mode |= driver.LinkCacheUA - } - return mode +func (d *AListV3) ResolveLinkCacheMode(path string) driver.LinkCacheMode { + return family.ResolveLinkCacheMode(d.state(), path) } var _ driver.Driver = (*AListV3)(nil) diff --git a/drivers/alist_v3/driver_test.go b/drivers/alist_v3/driver_test.go index bb8e009eab..dc1accc803 100644 --- a/drivers/alist_v3/driver_test.go +++ b/drivers/alist_v3/driver_test.go @@ -9,16 +9,27 @@ import ( "time" "github.com/OpenListTeam/OpenList/v4/drivers/base" + openlistdriver "github.com/OpenListTeam/OpenList/v4/drivers/openlist" "github.com/OpenListTeam/OpenList/v4/internal/driver" "github.com/OpenListTeam/OpenList/v4/internal/model" "github.com/go-resty/resty/v2" ) -// TestListSetsChildPaths descends two levels the way op.Get does, feeding an -// object from one listing back into List as dir. Without a Path on that object -// the driver asks upstream for "", which a real server answers with its own -// root -- hence the fake upstream's fallback, and the endless self-similar tree. -func TestListSetsChildPaths(t *testing.T) { +type familyDriver interface { + List(context.Context, model.Obj, model.ListArgs) ([]model.Obj, error) + ArchiveDecompress(context.Context, model.Obj, model.Obj, model.ArchiveDecompressArgs) error +} + +func useTestClient(t *testing.T) { + t.Helper() + prev := base.RestyClient + base.RestyClient = resty.New().SetTimeout(5 * time.Second) + t.Cleanup(func() { base.RestyClient = prev }) +} + +// This descends two levels the way op.Get does, feeding an object from one +// listing back into List. It is one behavioral contract for both products. +func TestFamilyListSetsChildPaths(t *testing.T) { tree := map[string][]ObjResp{ "/": {{Name: "root-marker", IsDir: true}}, "/drive": {{Name: "concerts", IsDir: true}}, @@ -31,35 +42,203 @@ func TestListSetsChildPaths(t *testing.T) { if !ok { content = tree["/"] } - w.Header().Set("Content-Type", "application/json") // resty only unmarshals JSON + w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(map[string]any{ "code": 200, "message": "success", "data": map[string]any{"content": content, "total": len(content)}, }) })) t.Cleanup(srv.Close) + useTestClient(t) - // conf.Conf is nil outside a booted server, so base.InitClient() is unusable. - prev := base.RestyClient - base.RestyClient = resty.New().SetTimeout(5 * time.Second) - t.Cleanup(func() { base.RestyClient = prev }) + drivers := map[string]familyDriver{ + "alist-v3": &AListV3{Addition: Addition{ + RootPath: driver.RootPath{RootFolderPath: "/drive"}, + Address: srv.URL, + }}, + "openlist": &openlistdriver.OpenList{Addition: openlistdriver.Addition{ + RootPath: driver.RootPath{RootFolderPath: "/drive"}, + Address: srv.URL, + }}, + } + for name, d := range drivers { + t.Run(name, func(t *testing.T) { + dir := model.Obj(&model.Object{Path: "/drive", IsFolder: true}) + for _, want := range []string{"/drive/concerts", "/drive/concerts/show.mkv"} { + objs, err := d.List(context.Background(), dir, model.ListArgs{}) + if err != nil { + t.Fatalf("List(%q): %v", dir.GetPath(), err) + } + if len(objs) != 1 { + t.Fatalf("List(%q) returned %d objects, want 1", dir.GetPath(), len(objs)) + } + if got := objs[0].GetPath(); got != want { + t.Fatalf("child of %q has path %q, want %q", dir.GetPath(), got, want) + } + dir = objs[0] + } + }) + } +} - d := &AListV3{Addition: Addition{ - RootPath: driver.RootPath{RootFolderPath: "/drive"}, - Address: srv.URL, - }} - dir := model.Obj(&model.Object{Path: "/drive", IsFolder: true}) - for _, want := range []string{"/drive/concerts", "/drive/concerts/show.mkv"} { - objs, err := d.List(context.Background(), dir, model.ListArgs{}) - if err != nil { - t.Fatalf("List(%q): %v", dir.GetPath(), err) - } - if len(objs) != 1 { - t.Fatalf("List(%q) returned %d objects, want 1", dir.GetPath(), len(objs)) - } - if got := objs[0].GetPath(); got != want { - t.Fatalf("child of %q has path %q, want %q", dir.GetPath(), got, want) - } - dir = objs[0] +func TestFamilyDialectRequests(t *testing.T) { + tests := []struct { + name string + newDriver func(string) familyDriver + wantRefresh bool + wantOverwrite bool + wantOverwriteKey bool + }{ + { + name: "alist-v3 keeps legacy request shape", + newDriver: func(address string) familyDriver { + return &AListV3{Addition: Addition{ + Address: address, ForwardArchiveReq: true, + }} + }, + }, + { + name: "openlist suppresses refresh unless enabled", + newDriver: func(address string) familyDriver { + return &openlistdriver.OpenList{Addition: openlistdriver.Addition{ + Address: address, ForwardArchiveReq: true, + }} + }, + wantOverwrite: true, wantOverwriteKey: true, + }, + { + name: "openlist forwards enabled flags", + newDriver: func(address string) familyDriver { + return &openlistdriver.OpenList{Addition: openlistdriver.Addition{ + Address: address, ForwardArchiveReq: true, PassRefreshFlagToUpsteam: true, + }} + }, + wantRefresh: true, wantOverwrite: true, wantOverwriteKey: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var listBody, decompressBody map[string]json.RawMessage + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/api/fs/list": + _ = json.NewDecoder(r.Body).Decode(&listBody) + case "/api/fs/archive/decompress": + _ = json.NewDecoder(r.Body).Decode(&decompressBody) + } + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"code":200,"message":"success","data":{"content":[]}}`)) + })) + t.Cleanup(srv.Close) + useTestClient(t) + + d := tt.newDriver(srv.URL) + dir := &model.Object{Path: "/dst", IsFolder: true} + if _, err := d.List(context.Background(), dir, model.ListArgs{Refresh: true}); err != nil { + t.Fatal(err) + } + if err := d.ArchiveDecompress( + context.Background(), + &model.Object{Path: "/src/a.zip"}, + dir, + model.ArchiveDecompressArgs{Overwrite: true}, + ); err != nil { + t.Fatal(err) + } + + var gotRefresh bool + if err := json.Unmarshal(listBody["refresh"], &gotRefresh); err != nil { + t.Fatal(err) + } + if gotRefresh != tt.wantRefresh { + t.Fatalf("refresh = %v, want %v", gotRefresh, tt.wantRefresh) + } + raw, hasOverwrite := decompressBody["overwrite"] + if hasOverwrite != tt.wantOverwriteKey { + t.Fatalf("overwrite presence = %v, want %v", hasOverwrite, tt.wantOverwriteKey) + } + if hasOverwrite { + var gotOverwrite bool + if err := json.Unmarshal(raw, &gotOverwrite); err != nil { + t.Fatal(err) + } + if gotOverwrite != tt.wantOverwrite { + t.Fatalf("overwrite = %v, want %v", gotOverwrite, tt.wantOverwrite) + } + } + }) + } +} + +func TestRoleDialectDecoding(t *testing.T) { + var legacy MeResp + if err := json.Unmarshal([]byte(`{"role":[2]}`), &legacy); err != nil { + t.Fatalf("AList V3 array role: %v", err) + } + if len(legacy.Role) != 1 || legacy.Role[0] != 2 { + t.Fatalf("AList V3 role = %v, want [2]", legacy.Role) + } + if err := json.Unmarshal([]byte(`{"role":2}`), &legacy); err != nil { + t.Fatalf("AList V3 scalar role: %v", err) + } + + var current openlistdriver.MeResp + if err := json.Unmarshal([]byte(`{"role":2}`), ¤t); err != nil { + t.Fatalf("OpenList scalar role: %v", err) + } + if err := json.Unmarshal([]byte(`{"role":[2]}`), ¤t); err == nil { + t.Fatal("OpenList unexpectedly accepted an array role") + } +} + +func TestFamilyLinkPreservesForwardedContext(t *testing.T) { + type linkDriver interface { + Link(context.Context, model.Obj, model.LinkArgs) (*model.Link, error) + ResolveLinkCacheMode(string) driver.LinkCacheMode + } + for _, tt := range []struct { + name string + new func(string) linkDriver + }{ + {"alist-v3", func(address string) linkDriver { + return &AListV3{Addition: Addition{ + Address: address, MetaPassword: "secret", PassIPToUpsteam: true, PassUAToUpsteam: true, + }} + }}, + {"openlist", func(address string) linkDriver { + return &openlistdriver.OpenList{Addition: openlistdriver.Addition{ + Address: address, MetaPassword: "secret", PassIPToUpsteam: true, PassUAToUpsteam: true, + }} + }}, + } { + t.Run(tt.name, func(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path != "/api/fs/get" || r.Method != http.MethodPost { + t.Errorf("request = %s %s", r.Method, r.URL.Path) + } + if r.Header.Get("User-Agent") != "client" || r.Header.Get("X-Forwarded-For") != "192.0.2.1" || r.Header.Get("X-Real-Ip") != "192.0.2.1" { + t.Errorf("forwarded headers = %v", r.Header) + } + var body FsGetReq + if err := json.NewDecoder(r.Body).Decode(&body); err != nil || body.Path != "/movie" || body.Password != "secret" { + t.Errorf("link request = %+v, err = %v", body, err) + } + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(`{"code":200,"message":"success","data":{"raw_url":"https://example.invalid/movie"}}`)) + })) + t.Cleanup(srv.Close) + useTestClient(t) + d := tt.new(srv.URL) + link, err := d.Link(context.Background(), &model.Object{Path: "/movie"}, model.LinkArgs{ + IP: "192.0.2.1", Header: http.Header{"User-Agent": []string{"client"}}, + }) + if err != nil || link == nil || link.URL != "https://example.invalid/movie" { + t.Fatalf("Link = %+v, err = %v", link, err) + } + if got, want := d.ResolveLinkCacheMode("/movie"), driver.LinkCacheIP|driver.LinkCacheUA; got != want { + t.Fatalf("cache mode = %v, want %v", got, want) + } + }) } } diff --git a/drivers/alist_v3/meta.go b/drivers/alist_v3/meta.go index 2e5b83f8ea..44f54ba5ed 100644 --- a/drivers/alist_v3/meta.go +++ b/drivers/alist_v3/meta.go @@ -2,7 +2,6 @@ package alist_v3 import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -25,8 +24,6 @@ var config = driver.Config{ LinkCacheMode: driver.LinkCacheAuto, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &AListV3{} - }) +func New() driver.Driver { + return &AListV3{} } diff --git a/drivers/alist_v3/types.go b/drivers/alist_v3/types.go index 527de77993..dc93752190 100644 --- a/drivers/alist_v3/types.go +++ b/drivers/alist_v3/types.go @@ -2,75 +2,26 @@ package alist_v3 import ( "encoding/json" - "time" - "github.com/OpenListTeam/OpenList/v4/internal/model" - "github.com/OpenListTeam/OpenList/v4/pkg/utils" + family "github.com/OpenListTeam/OpenList/v4/drivers/internal/openlist" ) -type ListReq struct { - model.PageReq - Path string `json:"path" form:"path"` - Password string `json:"password" form:"password"` - Refresh bool `json:"refresh"` -} - -type ObjResp struct { - Name string `json:"name"` - Size int64 `json:"size"` - IsDir bool `json:"is_dir"` - Modified time.Time `json:"modified"` - Created time.Time `json:"created"` - Sign string `json:"sign"` - Thumb string `json:"thumb"` - Type int `json:"type"` - HashInfo string `json:"hashinfo"` -} - -type FsListResp struct { - Content []ObjResp `json:"content"` - Total int64 `json:"total"` - Readme string `json:"readme"` - Write bool `json:"write"` - Provider string `json:"provider"` -} - -type FsGetReq struct { - Path string `json:"path" form:"path"` - Password string `json:"password" form:"password"` -} - -type FsGetResp struct { - ObjResp - RawURL string `json:"raw_url"` - Readme string `json:"readme"` - Provider string `json:"provider"` - Related []ObjResp `json:"related"` -} - -type MkdirOrLinkReq struct { - Path string `json:"path" form:"path"` -} - -type MoveCopyReq struct { - SrcDir string `json:"src_dir"` - DstDir string `json:"dst_dir"` - Names []string `json:"names"` -} - -type RenameReq struct { - Path string `json:"path"` - Name string `json:"name"` -} - -type RemoveReq struct { - Dir string `json:"dir"` - Names []string `json:"names"` -} - -type LoginResp struct { - Token string `json:"token"` -} +type ListReq = family.ListReq +type ObjResp = family.ObjResp +type FsListResp = family.FsListResp +type FsGetReq = family.FsGetReq +type FsGetResp = family.FsGetResp +type MkdirOrLinkReq = family.MkdirOrLinkReq +type MoveCopyReq = family.MoveCopyReq +type RenameReq = family.RenameReq +type RemoveReq = family.RemoveReq +type LoginResp = family.LoginResp +type ArchiveMetaReq = family.ArchiveMetaReq +type TreeResp = family.TreeResp +type ArchiveMetaResp = family.ArchiveMetaResp +type ArchiveListReq = family.ArchiveListReq +type ArchiveListResp = family.ArchiveListResp +type DecompressReq = family.DecompressReq type MeResp struct { Id int `json:"id"` @@ -94,89 +45,3 @@ func (s *IntSlice) UnmarshalJSON(b []byte) error { } return json.Unmarshal(b, (*[]int)(s)) } - -type ArchiveMetaReq struct { - ArchivePass string `json:"archive_pass"` - Password string `json:"password"` - Path string `json:"path"` - Refresh bool `json:"refresh"` -} - -type TreeResp struct { - ObjResp - Children []TreeResp `json:"children"` - hashCache *utils.HashInfo -} - -func (t *TreeResp) GetSize() int64 { - return t.Size -} - -func (t *TreeResp) GetName() string { - return t.Name -} - -func (t *TreeResp) ModTime() time.Time { - return t.Modified -} - -func (t *TreeResp) CreateTime() time.Time { - return t.Created -} - -func (t *TreeResp) IsDir() bool { - return t.ObjResp.IsDir -} - -func (t *TreeResp) GetHash() utils.HashInfo { - return utils.FromString(t.HashInfo) -} - -func (t *TreeResp) GetID() string { - return "" -} - -func (t *TreeResp) GetPath() string { - return "" -} - -func (t *TreeResp) GetChildren() []model.ObjTree { - ret := make([]model.ObjTree, 0, len(t.Children)) - for _, child := range t.Children { - ret = append(ret, &child) - } - return ret -} - -func (t *TreeResp) Thumb() string { - return t.ObjResp.Thumb -} - -type ArchiveMetaResp struct { - Comment string `json:"comment"` - Encrypted bool `json:"encrypted"` - Content []TreeResp `json:"content"` - RawURL string `json:"raw_url"` - Sign string `json:"sign"` -} - -type ArchiveListReq struct { - model.PageReq - ArchiveMetaReq - InnerPath string `json:"inner_path"` -} - -type ArchiveListResp struct { - Content []ObjResp `json:"content"` - Total int64 `json:"total"` -} - -type DecompressReq struct { - ArchivePass string `json:"archive_pass"` - CacheFull bool `json:"cache_full"` - DstDir string `json:"dst_dir"` - InnerPath string `json:"inner_path"` - Name []string `json:"name"` - PutIntoNewDir bool `json:"put_into_new_dir"` - SrcDir string `json:"src_dir"` -} diff --git a/drivers/alist_v3/util.go b/drivers/alist_v3/util.go deleted file mode 100644 index 821fe5465c..0000000000 --- a/drivers/alist_v3/util.go +++ /dev/null @@ -1,65 +0,0 @@ -package alist_v3 - -import ( - "fmt" - "net/http" - - "github.com/OpenListTeam/OpenList/v4/drivers/base" - "github.com/OpenListTeam/OpenList/v4/internal/op" - "github.com/OpenListTeam/OpenList/v4/pkg/utils" - "github.com/OpenListTeam/OpenList/v4/server/common" - "github.com/go-resty/resty/v2" - log "github.com/sirupsen/logrus" -) - -func (d *AListV3) login() error { - if d.Username == "" { - return nil - } - var resp common.Resp[LoginResp] - _, _, err := d.request("/auth/login", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(base.Json{ - "username": d.Username, - "password": d.Password, - }) - }) - if err != nil { - return err - } - d.Token = resp.Data.Token - op.MustSaveDriverStorage(d) - return nil -} - -func (d *AListV3) request(api, method string, callback base.ReqCallback, retry ...bool) ([]byte, int, error) { - url := d.Address + "/api" + api - req := base.RestyClient.R() - req.SetHeader("Authorization", d.Token) - if callback != nil { - callback(req) - } - res, err := req.Execute(method, url) - if err != nil { - code := 0 - if res != nil { - code = res.StatusCode() - } - return nil, code, err - } - log.Debugf("[openlist] response body: %s", res.String()) - if res.StatusCode() >= 400 { - return nil, res.StatusCode(), fmt.Errorf("request failed, status: %s", res.Status()) - } - code := utils.Json.Get(res.Body(), "code").ToInt() - if code != 200 { - if (code == 401 || code == 403) && !utils.IsBool(retry...) { - err = d.login() - if err != nil { - return nil, code, err - } - return d.request(api, method, callback, true) - } - return nil, code, fmt.Errorf("request failed,code: %d, message: %s", code, utils.Json.Get(res.Body(), "message").ToString()) - } - return res.Body(), 200, nil -} diff --git a/drivers/aliyundrive/meta.go b/drivers/aliyundrive/meta.go index e3241bcc71..1347ba201c 100644 --- a/drivers/aliyundrive/meta.go +++ b/drivers/aliyundrive/meta.go @@ -2,7 +2,6 @@ package aliyundrive import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -23,8 +22,6 @@ Deprecated, no longer maintained and will be removed in a future version. We recommend using the official driver AliyundriveOpen.`, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &AliDrive{} - }) +func New() driver.Driver { + return &AliDrive{} } diff --git a/drivers/aliyundrive_open/meta.go b/drivers/aliyundrive_open/meta.go index becfef09b0..0f0cad145e 100644 --- a/drivers/aliyundrive_open/meta.go +++ b/drivers/aliyundrive_open/meta.go @@ -2,7 +2,6 @@ package aliyundrive_open import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -31,8 +30,6 @@ var config = driver.Config{ } var API_URL = "https://openapi.alipan.com" -func init() { - op.RegisterDriver(func() driver.Driver { - return &AliyundriveOpen{} - }) +func New() driver.Driver { + return &AliyundriveOpen{} } diff --git a/drivers/aliyundrive_share/meta.go b/drivers/aliyundrive_share/meta.go index 0227c2d471..f84cd443ef 100644 --- a/drivers/aliyundrive_share/meta.go +++ b/drivers/aliyundrive_share/meta.go @@ -2,7 +2,6 @@ package aliyundrive_share import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -16,14 +15,10 @@ type Addition struct { var config = driver.Config{ Name: "AliyundriveShare", - LocalSort: false, - OnlyProxy: false, NoUpload: true, DefaultRoot: "root", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &AliyundriveShare{} - }) +func New() driver.Driver { + return &AliyundriveShare{} } diff --git a/drivers/all.go b/drivers/all.go index 601c7bfc5c..c8498a7663 100644 --- a/drivers/all.go +++ b/drivers/all.go @@ -1,95 +1,189 @@ package drivers import ( - _ "github.com/OpenListTeam/OpenList/v4/drivers/115" - _ "github.com/OpenListTeam/OpenList/v4/drivers/115_open" - _ "github.com/OpenListTeam/OpenList/v4/drivers/115_share" - _ "github.com/OpenListTeam/OpenList/v4/drivers/123" - _ "github.com/OpenListTeam/OpenList/v4/drivers/123_link" - _ "github.com/OpenListTeam/OpenList/v4/drivers/123_open" - _ "github.com/OpenListTeam/OpenList/v4/drivers/123_share" - _ "github.com/OpenListTeam/OpenList/v4/drivers/139" - _ "github.com/OpenListTeam/OpenList/v4/drivers/189" - _ "github.com/OpenListTeam/OpenList/v4/drivers/189_tv" - _ "github.com/OpenListTeam/OpenList/v4/drivers/189pc" - _ "github.com/OpenListTeam/OpenList/v4/drivers/alias" - _ "github.com/OpenListTeam/OpenList/v4/drivers/alidoc" - _ "github.com/OpenListTeam/OpenList/v4/drivers/alist_v3" - _ "github.com/OpenListTeam/OpenList/v4/drivers/aliyundrive" - _ "github.com/OpenListTeam/OpenList/v4/drivers/aliyundrive_open" - _ "github.com/OpenListTeam/OpenList/v4/drivers/aliyundrive_share" - _ "github.com/OpenListTeam/OpenList/v4/drivers/autoindex" - _ "github.com/OpenListTeam/OpenList/v4/drivers/azure_blob" - _ "github.com/OpenListTeam/OpenList/v4/drivers/baidu_netdisk" - _ "github.com/OpenListTeam/OpenList/v4/drivers/baidu_photo" - _ "github.com/OpenListTeam/OpenList/v4/drivers/bunny_storage" - _ "github.com/OpenListTeam/OpenList/v4/drivers/chaoxing" - _ "github.com/OpenListTeam/OpenList/v4/drivers/chunk" - _ "github.com/OpenListTeam/OpenList/v4/drivers/cloudflare_imgbed" - _ "github.com/OpenListTeam/OpenList/v4/drivers/cloudreve" - _ "github.com/OpenListTeam/OpenList/v4/drivers/cloudreve_v4" - _ "github.com/OpenListTeam/OpenList/v4/drivers/cnb_releases" - _ "github.com/OpenListTeam/OpenList/v4/drivers/crypt" - _ "github.com/OpenListTeam/OpenList/v4/drivers/degoo" - _ "github.com/OpenListTeam/OpenList/v4/drivers/doubao" - _ "github.com/OpenListTeam/OpenList/v4/drivers/doubao_new" - _ "github.com/OpenListTeam/OpenList/v4/drivers/doubao_share" - _ "github.com/OpenListTeam/OpenList/v4/drivers/dropbox" - _ "github.com/OpenListTeam/OpenList/v4/drivers/emby" - _ "github.com/OpenListTeam/OpenList/v4/drivers/febbox" - _ "github.com/OpenListTeam/OpenList/v4/drivers/ftp" - _ "github.com/OpenListTeam/OpenList/v4/drivers/github" - _ "github.com/OpenListTeam/OpenList/v4/drivers/github_releases" - _ "github.com/OpenListTeam/OpenList/v4/drivers/google_drive" - _ "github.com/OpenListTeam/OpenList/v4/drivers/google_photo" - _ "github.com/OpenListTeam/OpenList/v4/drivers/guangyapan" - _ "github.com/OpenListTeam/OpenList/v4/drivers/halalcloud" - _ "github.com/OpenListTeam/OpenList/v4/drivers/halalcloud_open" - _ "github.com/OpenListTeam/OpenList/v4/drivers/ilanzou" - _ "github.com/OpenListTeam/OpenList/v4/drivers/ipfs_api" - _ "github.com/OpenListTeam/OpenList/v4/drivers/kodbox" - _ "github.com/OpenListTeam/OpenList/v4/drivers/lanzou" - _ "github.com/OpenListTeam/OpenList/v4/drivers/lenovonas_share" - _ "github.com/OpenListTeam/OpenList/v4/drivers/local" - _ "github.com/OpenListTeam/OpenList/v4/drivers/mediafire" - _ "github.com/OpenListTeam/OpenList/v4/drivers/mediatrack" - _ "github.com/OpenListTeam/OpenList/v4/drivers/mega" - _ "github.com/OpenListTeam/OpenList/v4/drivers/misskey" - _ "github.com/OpenListTeam/OpenList/v4/drivers/mopan" - _ "github.com/OpenListTeam/OpenList/v4/drivers/netease_music" - _ "github.com/OpenListTeam/OpenList/v4/drivers/onedrive" - _ "github.com/OpenListTeam/OpenList/v4/drivers/onedrive_app" - _ "github.com/OpenListTeam/OpenList/v4/drivers/onedrive_sharelink" - _ "github.com/OpenListTeam/OpenList/v4/drivers/openlist" - _ "github.com/OpenListTeam/OpenList/v4/drivers/openlist_share" - _ "github.com/OpenListTeam/OpenList/v4/drivers/pikpak" - _ "github.com/OpenListTeam/OpenList/v4/drivers/pikpak_share" - _ "github.com/OpenListTeam/OpenList/v4/drivers/proton_drive" - _ "github.com/OpenListTeam/OpenList/v4/drivers/quark_open" - _ "github.com/OpenListTeam/OpenList/v4/drivers/quark_uc" - _ "github.com/OpenListTeam/OpenList/v4/drivers/quark_uc_tv" - _ "github.com/OpenListTeam/OpenList/v4/drivers/s3" - _ "github.com/OpenListTeam/OpenList/v4/drivers/seafile" - _ "github.com/OpenListTeam/OpenList/v4/drivers/sftp" - _ "github.com/OpenListTeam/OpenList/v4/drivers/smb" - _ "github.com/OpenListTeam/OpenList/v4/drivers/strm" - _ "github.com/OpenListTeam/OpenList/v4/drivers/teambition" - _ "github.com/OpenListTeam/OpenList/v4/drivers/teldrive" - _ "github.com/OpenListTeam/OpenList/v4/drivers/terabox" - _ "github.com/OpenListTeam/OpenList/v4/drivers/thunder" - _ "github.com/OpenListTeam/OpenList/v4/drivers/thunder_browser" - _ "github.com/OpenListTeam/OpenList/v4/drivers/thunderx" - _ "github.com/OpenListTeam/OpenList/v4/drivers/url_tree" - _ "github.com/OpenListTeam/OpenList/v4/drivers/uss" - _ "github.com/OpenListTeam/OpenList/v4/drivers/virtual" - _ "github.com/OpenListTeam/OpenList/v4/drivers/webdav" - _ "github.com/OpenListTeam/OpenList/v4/drivers/weiyun" - _ "github.com/OpenListTeam/OpenList/v4/drivers/wopan" - _ "github.com/OpenListTeam/OpenList/v4/drivers/wps" - _ "github.com/OpenListTeam/OpenList/v4/drivers/yandex_disk" + d115 "github.com/OpenListTeam/OpenList/v4/drivers/115" + d115_open "github.com/OpenListTeam/OpenList/v4/drivers/115_open" + d115_share "github.com/OpenListTeam/OpenList/v4/drivers/115_share" + d123 "github.com/OpenListTeam/OpenList/v4/drivers/123" + d123_link "github.com/OpenListTeam/OpenList/v4/drivers/123_link" + d123_open "github.com/OpenListTeam/OpenList/v4/drivers/123_open" + d123_share "github.com/OpenListTeam/OpenList/v4/drivers/123_share" + d139 "github.com/OpenListTeam/OpenList/v4/drivers/139" + d189 "github.com/OpenListTeam/OpenList/v4/drivers/189" + d189_tv "github.com/OpenListTeam/OpenList/v4/drivers/189_tv" + d189pc "github.com/OpenListTeam/OpenList/v4/drivers/189pc" + alias "github.com/OpenListTeam/OpenList/v4/drivers/alias" + alidoc "github.com/OpenListTeam/OpenList/v4/drivers/alidoc" + alist_v3 "github.com/OpenListTeam/OpenList/v4/drivers/alist_v3" + aliyundrive "github.com/OpenListTeam/OpenList/v4/drivers/aliyundrive" + aliyundrive_open "github.com/OpenListTeam/OpenList/v4/drivers/aliyundrive_open" + aliyundrive_share "github.com/OpenListTeam/OpenList/v4/drivers/aliyundrive_share" + autoindex "github.com/OpenListTeam/OpenList/v4/drivers/autoindex" + azure_blob "github.com/OpenListTeam/OpenList/v4/drivers/azure_blob" + baidu_netdisk "github.com/OpenListTeam/OpenList/v4/drivers/baidu_netdisk" + baidu_photo "github.com/OpenListTeam/OpenList/v4/drivers/baidu_photo" + bunny_storage "github.com/OpenListTeam/OpenList/v4/drivers/bunny_storage" + chaoxing "github.com/OpenListTeam/OpenList/v4/drivers/chaoxing" + chunk "github.com/OpenListTeam/OpenList/v4/drivers/chunk" + cloudflare_imgbed "github.com/OpenListTeam/OpenList/v4/drivers/cloudflare_imgbed" + cloudreve "github.com/OpenListTeam/OpenList/v4/drivers/cloudreve" + cloudreve_v4 "github.com/OpenListTeam/OpenList/v4/drivers/cloudreve_v4" + cnb_releases "github.com/OpenListTeam/OpenList/v4/drivers/cnb_releases" + crypt "github.com/OpenListTeam/OpenList/v4/drivers/crypt" + degoo "github.com/OpenListTeam/OpenList/v4/drivers/degoo" + doubao "github.com/OpenListTeam/OpenList/v4/drivers/doubao" + doubao_new "github.com/OpenListTeam/OpenList/v4/drivers/doubao_new" + doubao_share "github.com/OpenListTeam/OpenList/v4/drivers/doubao_share" + dropbox "github.com/OpenListTeam/OpenList/v4/drivers/dropbox" + emby "github.com/OpenListTeam/OpenList/v4/drivers/emby" + febbox "github.com/OpenListTeam/OpenList/v4/drivers/febbox" + ftp "github.com/OpenListTeam/OpenList/v4/drivers/ftp" + github "github.com/OpenListTeam/OpenList/v4/drivers/github" + github_releases "github.com/OpenListTeam/OpenList/v4/drivers/github_releases" + google_drive "github.com/OpenListTeam/OpenList/v4/drivers/google_drive" + google_photo "github.com/OpenListTeam/OpenList/v4/drivers/google_photo" + guangyapan "github.com/OpenListTeam/OpenList/v4/drivers/guangyapan" + halalcloud "github.com/OpenListTeam/OpenList/v4/drivers/halalcloud" + halalcloud_open "github.com/OpenListTeam/OpenList/v4/drivers/halalcloud_open" + ilanzou "github.com/OpenListTeam/OpenList/v4/drivers/ilanzou" + ipfs_api "github.com/OpenListTeam/OpenList/v4/drivers/ipfs_api" + kodbox "github.com/OpenListTeam/OpenList/v4/drivers/kodbox" + lanzou "github.com/OpenListTeam/OpenList/v4/drivers/lanzou" + lenovonas_share "github.com/OpenListTeam/OpenList/v4/drivers/lenovonas_share" + local "github.com/OpenListTeam/OpenList/v4/drivers/local" + mediafire "github.com/OpenListTeam/OpenList/v4/drivers/mediafire" + mediatrack "github.com/OpenListTeam/OpenList/v4/drivers/mediatrack" + mega "github.com/OpenListTeam/OpenList/v4/drivers/mega" + misskey "github.com/OpenListTeam/OpenList/v4/drivers/misskey" + mopan "github.com/OpenListTeam/OpenList/v4/drivers/mopan" + netease_music "github.com/OpenListTeam/OpenList/v4/drivers/netease_music" + onedrive "github.com/OpenListTeam/OpenList/v4/drivers/onedrive" + onedrive_app "github.com/OpenListTeam/OpenList/v4/drivers/onedrive_app" + onedrive_sharelink "github.com/OpenListTeam/OpenList/v4/drivers/onedrive_sharelink" + openlist "github.com/OpenListTeam/OpenList/v4/drivers/openlist" + openlist_share "github.com/OpenListTeam/OpenList/v4/drivers/openlist_share" + pikpak "github.com/OpenListTeam/OpenList/v4/drivers/pikpak" + pikpak_share "github.com/OpenListTeam/OpenList/v4/drivers/pikpak_share" + proton_drive "github.com/OpenListTeam/OpenList/v4/drivers/proton_drive" + quark_open "github.com/OpenListTeam/OpenList/v4/drivers/quark_open" + quark_uc "github.com/OpenListTeam/OpenList/v4/drivers/quark_uc" + quark_uc_tv "github.com/OpenListTeam/OpenList/v4/drivers/quark_uc_tv" + s3 "github.com/OpenListTeam/OpenList/v4/drivers/s3" + seafile "github.com/OpenListTeam/OpenList/v4/drivers/seafile" + sftp "github.com/OpenListTeam/OpenList/v4/drivers/sftp" + smb "github.com/OpenListTeam/OpenList/v4/drivers/smb" + strm "github.com/OpenListTeam/OpenList/v4/drivers/strm" + teambition "github.com/OpenListTeam/OpenList/v4/drivers/teambition" + teldrive "github.com/OpenListTeam/OpenList/v4/drivers/teldrive" + terabox "github.com/OpenListTeam/OpenList/v4/drivers/terabox" + thunder "github.com/OpenListTeam/OpenList/v4/drivers/thunder" + thunder_browser "github.com/OpenListTeam/OpenList/v4/drivers/thunder_browser" + thunderx "github.com/OpenListTeam/OpenList/v4/drivers/thunderx" + url_tree "github.com/OpenListTeam/OpenList/v4/drivers/url_tree" + uss "github.com/OpenListTeam/OpenList/v4/drivers/uss" + virtual "github.com/OpenListTeam/OpenList/v4/drivers/virtual" + webdav "github.com/OpenListTeam/OpenList/v4/drivers/webdav" + weiyun "github.com/OpenListTeam/OpenList/v4/drivers/weiyun" + wopan "github.com/OpenListTeam/OpenList/v4/drivers/wopan" + wps "github.com/OpenListTeam/OpenList/v4/drivers/wps" + yandex_disk "github.com/OpenListTeam/OpenList/v4/drivers/yandex_disk" + "github.com/OpenListTeam/OpenList/v4/internal/driver" ) -// All do nothing,just for import -// same as _ import -func All() { +func All() []driver.Constructor { + return []driver.Constructor{ + d115.New, + d115_open.New, + d115_share.New, + d123.New, + d123_link.New, + d123_open.New, + d123_share.New, + d139.New, + d189.New, + d189_tv.New, + d189pc.New, + alias.New, + alidoc.New, + alist_v3.New, + aliyundrive.New, + aliyundrive_open.New, + aliyundrive_share.New, + autoindex.New, + azure_blob.New, + baidu_netdisk.New, + baidu_photo.New, + bunny_storage.New, + chaoxing.New, + chunk.New, + cloudflare_imgbed.New, + cloudreve.New, + cloudreve_v4.New, + cnb_releases.New, + crypt.New, + degoo.New, + doubao.New, + doubao_new.New, + doubao_share.New, + dropbox.New, + emby.New, + febbox.New, + ftp.New, + github.New, + github_releases.New, + google_drive.New, + google_photo.New, + guangyapan.New, + halalcloud.New, + halalcloud_open.New, + ilanzou.New, + ilanzou.New2, + ipfs_api.New, + kodbox.New, + lanzou.New, + lenovonas_share.New, + local.New, + mediafire.New, + mediatrack.New, + mega.New, + misskey.New, + mopan.New, + netease_music.New, + onedrive.New, + onedrive_app.New, + onedrive_sharelink.New, + openlist.New, + openlist_share.New, + pikpak.New, + pikpak_share.New, + proton_drive.New, + quark_open.New, + quark_uc.New, + quark_uc.New2, + quark_uc_tv.New, + quark_uc_tv.New2, + s3.New, + s3.New2, + seafile.New, + sftp.New, + smb.New, + strm.New, + teambition.New, + teldrive.New, + terabox.New, + thunder.New, + thunder.New2, + thunder_browser.New, + thunder_browser.New2, + thunderx.New, + thunderx.New2, + url_tree.New, + uss.New, + virtual.New, + webdav.New, + weiyun.New, + wopan.New, + wps.New, + yandex_disk.New, + } } diff --git a/drivers/autoindex/meta.go b/drivers/autoindex/meta.go index 8ebae59244..40f567d3a8 100644 --- a/drivers/autoindex/meta.go +++ b/drivers/autoindex/meta.go @@ -2,7 +2,6 @@ package autoindex import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,8 +21,6 @@ var config = driver.Config{ NoUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &AutoIndex{} - }) +func New() driver.Driver { + return &AutoIndex{} } diff --git a/drivers/azure_blob/meta.go b/drivers/azure_blob/meta.go index d675d40835..581cc523d5 100644 --- a/drivers/azure_blob/meta.go +++ b/drivers/azure_blob/meta.go @@ -2,7 +2,6 @@ package azure_blob import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -19,8 +18,6 @@ var config = driver.Config{ CheckStatus: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &AzureBlob{} - }) +func New() driver.Driver { + return &AzureBlob{} } diff --git a/drivers/baidu_netdisk/meta.go b/drivers/baidu_netdisk/meta.go index 3f3bed0229..00ff5c8e34 100644 --- a/drivers/baidu_netdisk/meta.go +++ b/drivers/baidu_netdisk/meta.go @@ -4,7 +4,6 @@ import ( "time" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -43,8 +42,6 @@ var config = driver.Config{ PreferProxy: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &BaiduNetdisk{} - }) +func New() driver.Driver { + return &BaiduNetdisk{} } diff --git a/drivers/baidu_photo/meta.go b/drivers/baidu_photo/meta.go index 6c6ca5c3af..b719fd57fa 100644 --- a/drivers/baidu_photo/meta.go +++ b/drivers/baidu_photo/meta.go @@ -2,7 +2,6 @@ package baiduphoto import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -23,8 +22,6 @@ var config = driver.Config{ LinkCacheMode: driver.LinkCacheUA, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &BaiduPhoto{} - }) +func New() driver.Driver { + return &BaiduPhoto{} } diff --git a/drivers/bunny_storage/meta.go b/drivers/bunny_storage/meta.go index 46e1359032..aa6e2258eb 100644 --- a/drivers/bunny_storage/meta.go +++ b/drivers/bunny_storage/meta.go @@ -2,7 +2,6 @@ package bunny_storage import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -25,8 +24,6 @@ var config = driver.Config{ CheckStatus: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &BunnyStorage{} - }) +func New() driver.Driver { + return &BunnyStorage{} } diff --git a/drivers/chaoxing/driver.go b/drivers/chaoxing/driver.go index dfd25d1957..52f4293e81 100644 --- a/drivers/chaoxing/driver.go +++ b/drivers/chaoxing/driver.go @@ -15,7 +15,6 @@ import ( "time" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/errs" "github.com/OpenListTeam/OpenList/v4/internal/model" "github.com/OpenListTeam/OpenList/v4/internal/op" "github.com/OpenListTeam/OpenList/v4/pkg/cron" @@ -184,11 +183,6 @@ func (d *ChaoXing) Rename(ctx context.Context, srcObj model.Obj, newName string) return nil } -func (d *ChaoXing) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { - // TODO copy obj, optional - return errs.NotImplement -} - func (d *ChaoXing) Remove(ctx context.Context, obj model.Obj) error { query := map[string]string{ "bbsid": d.Addition.Bbsid, diff --git a/drivers/chaoxing/meta.go b/drivers/chaoxing/meta.go index 86177dafad..e1c83df909 100644 --- a/drivers/chaoxing/meta.go +++ b/drivers/chaoxing/meta.go @@ -2,7 +2,6 @@ package chaoxing import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) // 此程序挂载的是超星小组网盘,需要代理才能使用; @@ -26,21 +25,19 @@ type Conf struct { DowloadApi string } -func init() { - op.RegisterDriver(func() driver.Driver { - return &ChaoXing{ - config: driver.Config{ - Name: "ChaoXingGroupDrive", - OnlyProxy: true, - DefaultRoot: "-1", - NoOverwriteUpload: true, - }, - conf: Conf{ - ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch", - referer: "https://chaoxing.com/", - api: "https://groupweb.chaoxing.com", - DowloadApi: "https://noteyd.chaoxing.com", - }, - } - }) +func New() driver.Driver { + return &ChaoXing{ + config: driver.Config{ + Name: "ChaoXingGroupDrive", + OnlyProxy: true, + DefaultRoot: "-1", + NoOverwriteUpload: true, + }, + conf: Conf{ + ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch", + referer: "https://chaoxing.com/", + api: "https://groupweb.chaoxing.com", + DowloadApi: "https://noteyd.chaoxing.com", + }, + } } diff --git a/drivers/chunk/meta.go b/drivers/chunk/meta.go index 43e24c8969..e82a0fbb0b 100644 --- a/drivers/chunk/meta.go +++ b/drivers/chunk/meta.go @@ -2,7 +2,6 @@ package chunk import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -27,13 +26,11 @@ var config = driver.Config{ NoLinkURL: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Chunk{ - Addition: Addition{ - ChunkPrefix: "[openlist_chunk]", - NumListWorkers: 5, - }, - } - }) +func New() driver.Driver { + return &Chunk{ + Addition: Addition{ + ChunkPrefix: "[openlist_chunk]", + NumListWorkers: 5, + }, + } } diff --git a/drivers/cloudflare_imgbed/meta.go b/drivers/cloudflare_imgbed/meta.go index 73ba965406..4528a3d9c8 100644 --- a/drivers/cloudflare_imgbed/meta.go +++ b/drivers/cloudflare_imgbed/meta.go @@ -2,7 +2,6 @@ package cloudflare_imgbed import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -18,10 +17,9 @@ type Addition struct { var config = driver.Config{ Name: "cloudflare_imgbed", LocalSort: true, - NoUpload: false, DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { return &CFImgBed{} }) +func New() driver.Driver { + return &CFImgBed{} } diff --git a/drivers/cloudreve/meta.go b/drivers/cloudreve/meta.go index efcf726276..9cff3c73c2 100644 --- a/drivers/cloudreve/meta.go +++ b/drivers/cloudreve/meta.go @@ -2,7 +2,6 @@ package cloudreve import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -23,8 +22,6 @@ var config = driver.Config{ LocalSort: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Cloudreve{} - }) +func New() driver.Driver { + return &Cloudreve{} } diff --git a/drivers/cloudreve_v4/driver.go b/drivers/cloudreve_v4/driver.go index afd64d3d5e..4d253bbfe3 100644 --- a/drivers/cloudreve_v4/driver.go +++ b/drivers/cloudreve_v4/driver.go @@ -344,13 +344,6 @@ func (d *CloudreveV4) Extract(ctx context.Context, obj model.Obj, args model.Arc return nil, errs.NotImplement } -func (d *CloudreveV4) ArchiveDecompress(ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) ([]model.Obj, error) { - // TODO extract args.InnerPath path in the archive srcObj to the dstDir location, optional - // a folder with the same name as the archive file needs to be created to store the extracted results if args.PutIntoNewDir - // return errs.NotImplement to use an internal archive tool - return nil, errs.NotImplement -} - func (d *CloudreveV4) GetDetails(ctx context.Context) (*model.StorageDetails, error) { // TODO return storage details (total space, free space, etc.) var r CapacityResp diff --git a/drivers/cloudreve_v4/meta.go b/drivers/cloudreve_v4/meta.go index 304af598bc..682b95d8a5 100644 --- a/drivers/cloudreve_v4/meta.go +++ b/drivers/cloudreve_v4/meta.go @@ -2,7 +2,6 @@ package cloudreve_v4 import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -31,8 +30,6 @@ var config = driver.Config{ NoOverwriteUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &CloudreveV4{} - }) +func New() driver.Driver { + return &CloudreveV4{} } diff --git a/drivers/cnb_releases/driver.go b/drivers/cnb_releases/driver.go index 09ec153c8c..7464e44199 100644 --- a/drivers/cnb_releases/driver.go +++ b/drivers/cnb_releases/driver.go @@ -129,10 +129,6 @@ func (d *CnbReleases) MakeDir(ctx context.Context, parentDir model.Obj, dirName return errs.NotImplement } -func (d *CnbReleases) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - return nil, errs.NotImplement -} - func (d *CnbReleases) Rename(ctx context.Context, srcObj model.Obj, newName string) error { if srcObj.IsDir() && !d.UseTagName { return d.Request(http.MethodPatch, "/{repo}/-/releases/{release_id}", func(req *resty.Request) { @@ -146,10 +142,6 @@ func (d *CnbReleases) Rename(ctx context.Context, srcObj model.Obj, newName stri return errs.NotImplement } -func (d *CnbReleases) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - return nil, errs.NotImplement -} - func (d *CnbReleases) Remove(ctx context.Context, obj model.Obj) error { if obj.IsDir() { return d.Request(http.MethodDelete, "/{repo}/-/releases/{release_id}", func(req *resty.Request) { diff --git a/drivers/cnb_releases/meta.go b/drivers/cnb_releases/meta.go index 7301861d3c..662bfbd875 100644 --- a/drivers/cnb_releases/meta.go +++ b/drivers/cnb_releases/meta.go @@ -2,7 +2,6 @@ package cnb_releases import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -18,8 +17,6 @@ var config = driver.Config{ LocalSort: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &CnbReleases{} - }) +func New() driver.Driver { + return &CnbReleases{} } diff --git a/drivers/crypt/meta.go b/drivers/crypt/meta.go index 6a4659910d..52ac632674 100644 --- a/drivers/crypt/meta.go +++ b/drivers/crypt/meta.go @@ -2,7 +2,6 @@ package crypt import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -30,8 +29,6 @@ var config = driver.Config{ CheckStatus: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Crypt{} - }) +func New() driver.Driver { + return &Crypt{} } diff --git a/drivers/degoo/driver.go b/drivers/degoo/driver.go index 4cbc8be63c..a88ec7e923 100644 --- a/drivers/degoo/driver.go +++ b/drivers/degoo/driver.go @@ -9,7 +9,6 @@ import ( "github.com/OpenListTeam/OpenList/v4/drivers/base" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/errs" "github.com/OpenListTeam/OpenList/v4/internal/model" "github.com/OpenListTeam/OpenList/v4/pkg/utils" ) @@ -143,11 +142,6 @@ func (d *Degoo) Rename(ctx context.Context, srcObj model.Obj, newName string) er return nil } -func (d *Degoo) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - // Copy is not implemented, Degoo API does not support direct copy. - return nil, errs.NotImplement -} - func (d *Degoo) Remove(ctx context.Context, obj model.Obj) error { // Remove deletes a file or folder (moves to trash). const query = `mutation SetDeleteFile5($Token: String!, $IsInRecycleBin: Boolean!, $IDs: [IDType]!) { setDeleteFile5(Token: $Token, IsInRecycleBin: $IsInRecycleBin, IDs: $IDs) }` diff --git a/drivers/degoo/meta.go b/drivers/degoo/meta.go index 113d2082fa..469565fc13 100644 --- a/drivers/degoo/meta.go +++ b/drivers/degoo/meta.go @@ -2,7 +2,6 @@ package degoo import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -20,8 +19,6 @@ var config = driver.Config{ NoOverwriteUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Degoo{} - }) +func New() driver.Driver { + return &Degoo{} } diff --git a/drivers/doubao/driver.go b/drivers/doubao/driver.go index 6d4a4fc6e0..2acde7ceea 100644 --- a/drivers/doubao/driver.go +++ b/drivers/doubao/driver.go @@ -234,11 +234,6 @@ func (d *Doubao) Rename(ctx context.Context, srcObj model.Obj, newName string) e return err } -func (d *Doubao) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - // TODO copy obj, optional - return nil, errs.NotImplement -} - func (d *Doubao) Remove(ctx context.Context, obj model.Obj) error { if err := d.WaitLimit(ctx); err != nil { return err @@ -298,13 +293,6 @@ func (d *Doubao) Extract(ctx context.Context, obj model.Obj, args model.ArchiveI return nil, errs.NotImplement } -func (d *Doubao) ArchiveDecompress(ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) ([]model.Obj, error) { - // TODO extract args.InnerPath path in the archive srcObj to the dstDir location, optional - // a folder with the same name as the archive file needs to be created to store the extracted results if args.PutIntoNewDir - // return errs.NotImplement to use an internal archive tool - return nil, errs.NotImplement -} - //func (d *Doubao) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) { // return nil, errs.NotSupport //} diff --git a/drivers/doubao/meta.go b/drivers/doubao/meta.go index 83dade919a..55fc49c268 100644 --- a/drivers/doubao/meta.go +++ b/drivers/doubao/meta.go @@ -2,7 +2,6 @@ package doubao import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,12 +21,10 @@ var config = driver.Config{ DefaultRoot: "0", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Doubao{ - Addition: Addition{ - LimitRate: 2, - }, - } - }) +func New() driver.Driver { + return &Doubao{ + Addition: Addition{ + LimitRate: 2, + }, + } } diff --git a/drivers/doubao_new/driver.go b/drivers/doubao_new/driver.go index f84828f0e1..3cbfbd74f1 100644 --- a/drivers/doubao_new/driver.go +++ b/drivers/doubao_new/driver.go @@ -260,11 +260,6 @@ func (d *DoubaoNew) Rename(ctx context.Context, srcObj model.Obj, newName string return srcObj, nil } -func (d *DoubaoNew) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - // TODO copy obj, optional - return nil, errs.NotImplement -} - func (d *DoubaoNew) Remove(ctx context.Context, obj model.Obj) error { if obj == nil { return errors.New("nil object") diff --git a/drivers/doubao_new/meta.go b/drivers/doubao_new/meta.go index 2345357bf3..d3d2e44227 100644 --- a/drivers/doubao_new/meta.go +++ b/drivers/doubao_new/meta.go @@ -2,7 +2,6 @@ package doubao_new import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,18 +21,14 @@ type Addition struct { } var config = driver.Config{ - Name: "DoubaoNew", - LocalSort: true, - DefaultRoot: "", + Name: "DoubaoNew", + LocalSort: true, Alert: `danger|Do not use 302 if the storage is public accessible. Otherwise, the download link may leak sensitive information such as access token or signature. Others may use the leaked link to access all your files.`, - NoOverwriteUpload: false, - PreferProxy: true, + PreferProxy: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &DoubaoNew{} - }) +func New() driver.Driver { + return &DoubaoNew{} } diff --git a/drivers/doubao_share/driver.go b/drivers/doubao_share/driver.go index 4d23d7022b..3c9054dabf 100644 --- a/drivers/doubao_share/driver.go +++ b/drivers/doubao_share/driver.go @@ -120,36 +120,6 @@ func (d *DoubaoShare) Link(ctx context.Context, file model.Obj, args model.LinkA return nil, errors.New("can't convert obj to URL") } -func (d *DoubaoShare) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) { - // TODO create folder, optional - return nil, errs.NotImplement -} - -func (d *DoubaoShare) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - // TODO move obj, optional - return nil, errs.NotImplement -} - -func (d *DoubaoShare) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) { - // TODO rename obj, optional - return nil, errs.NotImplement -} - -func (d *DoubaoShare) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - // TODO copy obj, optional - return nil, errs.NotImplement -} - -func (d *DoubaoShare) Remove(ctx context.Context, obj model.Obj) error { - // TODO remove obj, optional - return errs.NotImplement -} - -func (d *DoubaoShare) Put(ctx context.Context, dstDir model.Obj, file model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) { - // TODO upload file, optional - return nil, errs.NotImplement -} - func (d *DoubaoShare) GetArchiveMeta(ctx context.Context, obj model.Obj, args model.ArchiveArgs) (model.ArchiveMeta, error) { // TODO get archive file meta-info, return errs.NotImplement to use an internal archive tool, optional return nil, errs.NotImplement @@ -165,13 +135,6 @@ func (d *DoubaoShare) Extract(ctx context.Context, obj model.Obj, args model.Arc return nil, errs.NotImplement } -func (d *DoubaoShare) ArchiveDecompress(ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) ([]model.Obj, error) { - // TODO extract args.InnerPath path in the archive srcObj to the dstDir location, optional - // a folder with the same name as the archive file needs to be created to store the extracted results if args.PutIntoNewDir - // return errs.NotImplement to use an internal archive tool - return nil, errs.NotImplement -} - //func (d *DoubaoShare) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) { // return nil, errs.NotSupport //} diff --git a/drivers/doubao_share/meta.go b/drivers/doubao_share/meta.go index a79c9e19f8..5f02bac68c 100644 --- a/drivers/doubao_share/meta.go +++ b/drivers/doubao_share/meta.go @@ -2,7 +2,6 @@ package doubao_share import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -18,8 +17,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &DoubaoShare{} - }) +func New() driver.Driver { + return &DoubaoShare{} } diff --git a/drivers/dropbox/meta.go b/drivers/dropbox/meta.go index a1032d97a3..973004266b 100644 --- a/drivers/dropbox/meta.go +++ b/drivers/dropbox/meta.go @@ -2,7 +2,6 @@ package dropbox import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -21,11 +20,9 @@ var config = driver.Config{ NoOverwriteUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Dropbox{ - base: "https://api.dropboxapi.com", - contentBase: "https://content.dropboxapi.com", - } - }) +func New() driver.Driver { + return &Dropbox{ + base: "https://api.dropboxapi.com", + contentBase: "https://content.dropboxapi.com", + } } diff --git a/drivers/emby/meta.go b/drivers/emby/meta.go index 632c98b7a9..ee147f5d54 100644 --- a/drivers/emby/meta.go +++ b/drivers/emby/meta.go @@ -2,7 +2,6 @@ package emby import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -23,8 +22,6 @@ var config = driver.Config{ CheckStatus: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Emby{} - }) +func New() driver.Driver { + return &Emby{} } diff --git a/drivers/febbox/driver.go b/drivers/febbox/driver.go index 2089cb05d7..7cecb891d1 100644 --- a/drivers/febbox/driver.go +++ b/drivers/febbox/driver.go @@ -9,7 +9,6 @@ import ( "golang.org/x/oauth2/clientcredentials" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/errs" "github.com/OpenListTeam/OpenList/v4/internal/model" ) @@ -126,8 +125,4 @@ func (d *FebBox) Remove(ctx context.Context, obj model.Obj) error { return nil } -func (d *FebBox) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) { - return nil, errs.NotImplement -} - var _ driver.Driver = (*FebBox)(nil) diff --git a/drivers/febbox/meta.go b/drivers/febbox/meta.go index cb6ff8fb17..ba1f58945f 100644 --- a/drivers/febbox/meta.go +++ b/drivers/febbox/meta.go @@ -2,7 +2,6 @@ package febbox import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,8 +21,6 @@ var config = driver.Config{ LinkCacheMode: driver.LinkCacheIP, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &FebBox{} - }) +func New() driver.Driver { + return &FebBox{} } diff --git a/drivers/ftp/meta.go b/drivers/ftp/meta.go index 6dc0d2cb61..11a0c4a069 100644 --- a/drivers/ftp/meta.go +++ b/drivers/ftp/meta.go @@ -2,7 +2,7 @@ package ftp import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" + "github.com/axgle/mahonia" ) @@ -39,8 +39,6 @@ var config = driver.Config{ NoLinkURL: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &FTP{} - }) +func New() driver.Driver { + return &FTP{} } diff --git a/drivers/github/meta.go b/drivers/github/meta.go index 366d3850f8..50f907b070 100644 --- a/drivers/github/meta.go +++ b/drivers/github/meta.go @@ -2,7 +2,6 @@ package github import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -33,8 +32,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Github{} - }) +func New() driver.Driver { + return &Github{} } diff --git a/drivers/github/mtime_test.go b/drivers/github/mtime_test.go index a6b2bdc686..dd729ac56a 100644 --- a/drivers/github/mtime_test.go +++ b/drivers/github/mtime_test.go @@ -17,6 +17,9 @@ import ( ) func TestDriverInfoIncludesAccurateModifiedTimeDefault(t *testing.T) { + if err := op.InstallDrivers([]odriver.Constructor{New}); err != nil { + t.Fatal(err) + } info := op.GetDriverInfoMap()["GitHub API"] for _, item := range info.Additional { if item.Name != "accurate_modified_time" { diff --git a/drivers/github_releases/driver.go b/drivers/github_releases/driver.go index e19f7998ae..49fd4d2b04 100644 --- a/drivers/github_releases/driver.go +++ b/drivers/github_releases/driver.go @@ -8,7 +8,6 @@ import ( "strings" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/errs" "github.com/OpenListTeam/OpenList/v4/internal/model" "github.com/OpenListTeam/OpenList/v4/pkg/utils" log "github.com/sirupsen/logrus" @@ -189,28 +188,3 @@ func (d *GithubReleases) Link(ctx context.Context, file model.Obj, args model.Li } return &link, nil } - -func (d *GithubReleases) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) { - // TODO create folder, optional - return nil, errs.NotImplement -} - -func (d *GithubReleases) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - // TODO move obj, optional - return nil, errs.NotImplement -} - -func (d *GithubReleases) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) { - // TODO rename obj, optional - return nil, errs.NotImplement -} - -func (d *GithubReleases) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - // TODO copy obj, optional - return nil, errs.NotImplement -} - -func (d *GithubReleases) Remove(ctx context.Context, obj model.Obj) error { - // TODO remove obj, optional - return errs.NotImplement -} diff --git a/drivers/github_releases/meta.go b/drivers/github_releases/meta.go index 36f8b3cf80..bd3663c2d5 100644 --- a/drivers/github_releases/meta.go +++ b/drivers/github_releases/meta.go @@ -2,7 +2,6 @@ package github_releases import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,8 +21,6 @@ var config = driver.Config{ NoUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &GithubReleases{} - }) +func New() driver.Driver { + return &GithubReleases{} } diff --git a/drivers/google_drive/meta.go b/drivers/google_drive/meta.go index 75263a12c2..4972770f8a 100644 --- a/drivers/google_drive/meta.go +++ b/drivers/google_drive/meta.go @@ -2,7 +2,6 @@ package google_drive import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -24,8 +23,6 @@ var config = driver.Config{ DefaultRoot: "root", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &GoogleDrive{} - }) +func New() driver.Driver { + return &GoogleDrive{} } diff --git a/drivers/google_photo/meta.go b/drivers/google_photo/meta.go index b8f7a76e4d..d22c881cd9 100644 --- a/drivers/google_photo/meta.go +++ b/drivers/google_photo/meta.go @@ -2,7 +2,6 @@ package google_photo import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -21,8 +20,6 @@ var config = driver.Config{ LocalSort: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &GooglePhoto{} - }) +func New() driver.Driver { + return &GooglePhoto{} } diff --git a/drivers/guangyapan/meta.go b/drivers/guangyapan/meta.go index 2cd7f8be9c..a635ac5d81 100644 --- a/drivers/guangyapan/meta.go +++ b/drivers/guangyapan/meta.go @@ -2,7 +2,6 @@ package guangyapan import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -24,14 +23,11 @@ type Addition struct { var config = driver.Config{ Name: "GuangYaPan", - DefaultRoot: "", CheckStatus: true, Alert: "info|Two-stage SMS login: (1) fill phone_number (+ captcha_token if needed), set send_code=true and save; (2) fill verify_code and save to finish login and auto-save access_token/refresh_token.", NoOverwriteUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &GuangYaPan{} - }) +func New() driver.Driver { + return &GuangYaPan{} } diff --git a/drivers/halalcloud/meta.go b/drivers/halalcloud/meta.go index 17e4d04bb0..41562a8ca7 100644 --- a/drivers/halalcloud/meta.go +++ b/drivers/halalcloud/meta.go @@ -2,7 +2,6 @@ package halalcloud import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -24,8 +23,6 @@ var config = driver.Config{ NoLinkURL: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &HalalCloud{} - }) +func New() driver.Driver { + return &HalalCloud{} } diff --git a/drivers/halalcloud_open/meta.go b/drivers/halalcloud_open/meta.go index 62f280b4ed..57ff129736 100644 --- a/drivers/halalcloud_open/meta.go +++ b/drivers/halalcloud_open/meta.go @@ -2,7 +2,6 @@ package halalcloudopen import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -20,15 +19,11 @@ type Addition struct { var config = driver.Config{ Name: "HalalCloudOpen", - OnlyProxy: false, DefaultRoot: "/", - NoLinkURL: false, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &HalalCloudOpen{} - }) +func New() driver.Driver { + return &HalalCloudOpen{} } type UploadedFile struct { diff --git a/drivers/ilanzou/driver.go b/drivers/ilanzou/driver.go index a640d8669a..80acbe7923 100644 --- a/drivers/ilanzou/driver.go +++ b/drivers/ilanzou/driver.go @@ -15,7 +15,6 @@ import ( "github.com/OpenListTeam/OpenList/v4/drivers/base" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/errs" "github.com/OpenListTeam/OpenList/v4/internal/model" "github.com/OpenListTeam/OpenList/v4/internal/stream" "github.com/OpenListTeam/OpenList/v4/pkg/utils" @@ -248,12 +247,6 @@ func (d *ILanZou) Rename(ctx context.Context, srcObj model.Obj, newName string) return &model.Object{ID: srcObj.GetID(), Name: newName, Size: srcObj.GetSize(), Modified: time.Now(), Ctime: srcObj.CreateTime(), IsFolder: srcObj.IsDir()}, nil } -// iLanzou has no server-side copy primitive. Returning NotImplement delegates -// to OpenList's persistent CopyTaskManager instead of blocking the HTTP request. -func (d *ILanZou) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - return nil, errs.NotImplement -} - func (d *ILanZou) Remove(ctx context.Context, obj model.Obj) error { var fileIDs, folderIDs []string if obj.IsDir() { diff --git a/drivers/ilanzou/meta.go b/drivers/ilanzou/meta.go index b20146b14f..bd6d1845d8 100644 --- a/drivers/ilanzou/meta.go +++ b/drivers/ilanzou/meta.go @@ -2,7 +2,6 @@ package ilanzou import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -25,43 +24,41 @@ type Conf struct { site string } -func init() { - op.RegisterDriver(func() driver.Driver { - return &ILanZou{ - config: driver.Config{ - Name: "ILanZou", - DefaultRoot: "0", - LocalSort: true, - NoOverwriteUpload: true, - }, - conf: Conf{ - base: "https://apis.ilanzou.com", - secret: []byte("lanZouY-disk-app"), - bucket: "wpanstore-lanzou", - unproved: "unproved", - proved: "proved", - devVersion: "125", - site: "https://www.ilanzou.com", - }, - } - }) - op.RegisterDriver(func() driver.Driver { - return &ILanZou{ - config: driver.Config{ - Name: "FeijiPan", - DefaultRoot: "0", - LocalSort: true, - NoOverwriteUpload: true, - }, - conf: Conf{ - base: "https://api.feijipan.com", - secret: []byte("dingHao-disk-app"), - bucket: "wpanstore", - unproved: "ws", - proved: "app", - devVersion: "125", - site: "https://www.feijipan.com", - }, - } - }) +func New() driver.Driver { + return &ILanZou{ + config: driver.Config{ + Name: "ILanZou", + DefaultRoot: "0", + LocalSort: true, + NoOverwriteUpload: true, + }, + conf: Conf{ + base: "https://apis.ilanzou.com", + secret: []byte("lanZouY-disk-app"), + bucket: "wpanstore-lanzou", + unproved: "unproved", + proved: "proved", + devVersion: "125", + site: "https://www.ilanzou.com", + }, + } +} +func New2() driver.Driver { + return &ILanZou{ + config: driver.Config{ + Name: "FeijiPan", + DefaultRoot: "0", + LocalSort: true, + NoOverwriteUpload: true, + }, + conf: Conf{ + base: "https://api.feijipan.com", + secret: []byte("dingHao-disk-app"), + bucket: "wpanstore", + unproved: "ws", + proved: "app", + devVersion: "125", + site: "https://www.feijipan.com", + }, + } } diff --git a/drivers/internal/openlist/driver.go b/drivers/internal/openlist/driver.go new file mode 100644 index 0000000000..bb1a02d085 --- /dev/null +++ b/drivers/internal/openlist/driver.go @@ -0,0 +1,330 @@ +package openlist + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" + "path" + + "github.com/OpenListTeam/OpenList/v4/drivers/base" + "github.com/OpenListTeam/OpenList/v4/internal/driver" + "github.com/OpenListTeam/OpenList/v4/internal/errs" + "github.com/OpenListTeam/OpenList/v4/internal/model" + "github.com/OpenListTeam/OpenList/v4/pkg/utils" + "github.com/OpenListTeam/OpenList/v4/server/common" + "github.com/go-resty/resty/v2" + log "github.com/sirupsen/logrus" +) + +func List(d State, ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { + var resp common.Resp[FsListResp] + _, _, err := d.Request("/fs/list", http.MethodPost, func(req *resty.Request) { + req.SetResult(&resp).SetBody(ListReq{ + PageReq: model.PageReq{ + Page: 1, + PerPage: 0, + }, + Path: dir.GetPath(), + Password: *d.MetaPassword, + Refresh: d.ForwardRefresh && args.Refresh, + }) + }) + if err != nil { + return nil, err + } + var files []model.Obj + for _, f := range resp.Data.Content { + file := model.ObjThumb{ + Object: model.Object{ + Name: f.Name, + Path: path.Join(dir.GetPath(), f.Name), + Modified: f.Modified, + Ctime: f.Created, + Size: f.Size, + IsFolder: f.IsDir, + HashInfo: utils.FromString(f.HashInfo), + }, + Thumbnail: model.Thumbnail{Thumbnail: f.Thumb}, + } + files = append(files, &file) + } + return files, nil +} + +func Link(d State, ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { + var resp common.Resp[FsGetResp] + headers := map[string]string{ + "User-Agent": base.UserAgent, + } + // if PassUAToUpsteam is true, then pass the user-agent to the upstream + if d.PassUserAgent { + userAgent := args.Header.Get("user-agent") + if userAgent != "" { + headers["User-Agent"] = userAgent + } + } + // if PassIPToUpsteam is true, then pass the ip address to the upstream + if d.PassIP { + ip := args.IP + if ip != "" { + headers["X-Forwarded-For"] = ip + headers["X-Real-Ip"] = ip + } + } + _, _, err := d.Request("/fs/get", http.MethodPost, func(req *resty.Request) { + req.SetResult(&resp).SetBody(FsGetReq{ + Path: file.GetPath(), + Password: *d.MetaPassword, + }).SetHeaders(headers) + }) + if err != nil { + return nil, err + } + return &model.Link{ + URL: resp.Data.RawURL, + }, nil +} + +func MakeDir(d State, ctx context.Context, parentDir model.Obj, dirName string) error { + _, _, err := d.Request("/fs/mkdir", http.MethodPost, func(req *resty.Request) { + req.SetBody(MkdirOrLinkReq{ + Path: path.Join(parentDir.GetPath(), dirName), + }) + }) + return err +} + +func Move(d State, ctx context.Context, srcObj, dstDir model.Obj) error { + _, _, err := d.Request("/fs/move", http.MethodPost, func(req *resty.Request) { + req.SetBody(MoveCopyReq{ + SrcDir: path.Dir(srcObj.GetPath()), + DstDir: dstDir.GetPath(), + Names: []string{srcObj.GetName()}, + }) + }) + return err +} + +func Rename(d State, ctx context.Context, srcObj model.Obj, newName string) error { + _, _, err := d.Request("/fs/rename", http.MethodPost, func(req *resty.Request) { + req.SetBody(RenameReq{ + Path: srcObj.GetPath(), + Name: newName, + }) + }) + return err +} + +func Copy(d State, ctx context.Context, srcObj, dstDir model.Obj) error { + _, _, err := d.Request("/fs/copy", http.MethodPost, func(req *resty.Request) { + req.SetBody(MoveCopyReq{ + SrcDir: path.Dir(srcObj.GetPath()), + DstDir: dstDir.GetPath(), + Names: []string{srcObj.GetName()}, + }) + }) + return err +} + +func Remove(d State, ctx context.Context, obj model.Obj) error { + _, _, err := d.Request("/fs/remove", http.MethodPost, func(req *resty.Request) { + req.SetBody(RemoveReq{ + Dir: path.Dir(obj.GetPath()), + Names: []string{obj.GetName()}, + }) + }) + return err +} + +func Put(d State, ctx context.Context, dstDir model.Obj, s model.FileStreamer, up driver.UpdateProgress) error { + reader := driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{ + Reader: s, + UpdateProgress: up, + }) + req, err := http.NewRequestWithContext(ctx, http.MethodPut, *d.Address+"/api/fs/put", reader) + if err != nil { + return err + } + req.Header.Set("Authorization", *d.Token) + req.Header.Set("File-Path", path.Join(dstDir.GetPath(), s.GetName())) + req.Header.Set("Password", *d.MetaPassword) + if md5 := s.GetHash().GetHash(utils.MD5); len(md5) > 0 { + req.Header.Set("X-File-Md5", md5) + } + if sha1 := s.GetHash().GetHash(utils.SHA1); len(sha1) > 0 { + req.Header.Set("X-File-Sha1", sha1) + } + if sha256 := s.GetHash().GetHash(utils.SHA256); len(sha256) > 0 { + req.Header.Set("X-File-Sha256", sha256) + } + + req.ContentLength = s.GetSize() + // client := base.NewHttpClient() + // client.Timeout = time.Hour * 6 + res, err := base.HttpClient.Do(req) + if err != nil { + return err + } + + bytes, err := io.ReadAll(res.Body) + if err != nil { + return err + } + log.Debugf("[openlist] response body: %s", string(bytes)) + if res.StatusCode >= 400 { + return fmt.Errorf("request failed, status: %s", res.Status) + } + code := utils.Json.Get(bytes, "code").ToInt() + if code != 200 { + if code == 401 || code == 403 { + err = d.Login() + if err != nil { + return err + } + } + return fmt.Errorf("request failed,code: %d, message: %s", code, utils.Json.Get(bytes, "message").ToString()) + } + return nil +} + +func GetArchiveMeta(d State, ctx context.Context, obj model.Obj, args model.ArchiveArgs) (model.ArchiveMeta, error) { + if !d.ForwardArchives { + return nil, errs.NotImplement + } + var resp common.Resp[ArchiveMetaResp] + _, code, err := d.Request("/fs/archive/meta", http.MethodPost, func(req *resty.Request) { + req.SetResult(&resp).SetBody(ArchiveMetaReq{ + ArchivePass: args.Password, + Password: *d.MetaPassword, + Path: obj.GetPath(), + Refresh: false, + }) + }) + if code == 202 { + return nil, errs.WrongArchivePassword + } + if err != nil { + return nil, err + } + var tree []model.ObjTree + if resp.Data.Content != nil { + tree = make([]model.ObjTree, 0, len(resp.Data.Content)) + for _, content := range resp.Data.Content { + tree = append(tree, &content) + } + } + return &model.ArchiveMetaInfo{ + Comment: resp.Data.Comment, + Encrypted: resp.Data.Encrypted, + Tree: tree, + }, nil +} + +func ListArchive(d State, ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) ([]model.Obj, error) { + if !d.ForwardArchives { + return nil, errs.NotImplement + } + var resp common.Resp[ArchiveListResp] + _, code, err := d.Request("/fs/archive/list", http.MethodPost, func(req *resty.Request) { + req.SetResult(&resp).SetBody(ArchiveListReq{ + ArchiveMetaReq: ArchiveMetaReq{ + ArchivePass: args.Password, + Password: *d.MetaPassword, + Path: obj.GetPath(), + Refresh: false, + }, + PageReq: model.PageReq{ + Page: 1, + PerPage: 0, + }, + InnerPath: args.InnerPath, + }) + }) + if code == 202 { + return nil, errs.WrongArchivePassword + } + if err != nil { + return nil, err + } + var files []model.Obj + for _, f := range resp.Data.Content { + file := model.ObjThumb{ + Object: model.Object{ + Name: f.Name, + Modified: f.Modified, + Ctime: f.Created, + Size: f.Size, + IsFolder: f.IsDir, + HashInfo: utils.FromString(f.HashInfo), + }, + Thumbnail: model.Thumbnail{Thumbnail: f.Thumb}, + } + files = append(files, &file) + } + return files, nil +} + +func Extract(d State, ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) (*model.Link, error) { + if !d.ForwardArchives { + return nil, errs.NotSupport + } + var resp common.Resp[ArchiveMetaResp] + _, _, err := d.Request("/fs/archive/meta", http.MethodPost, func(req *resty.Request) { + req.SetResult(&resp).SetBody(ArchiveMetaReq{ + ArchivePass: args.Password, + Password: *d.MetaPassword, + Path: obj.GetPath(), + Refresh: false, + }) + }) + if err != nil { + return nil, err + } + return &model.Link{ + URL: fmt.Sprintf("%s?inner=%s&pass=%s&sign=%s", + resp.Data.RawURL, + utils.EncodePath(args.InnerPath, true), + url.QueryEscape(args.Password), + resp.Data.Sign), + }, nil +} + +func ArchiveDecompress(d State, ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) error { + if !d.ForwardArchives { + return errs.NotImplement + } + dir, name := path.Split(srcObj.GetPath()) + _, _, err := d.Request("/fs/archive/decompress", http.MethodPost, func(req *resty.Request) { + body := DecompressReq{ + ArchivePass: args.Password, + CacheFull: args.CacheFull, + DstDir: dstDir.GetPath(), + InnerPath: args.InnerPath, + Name: []string{name}, + PutIntoNewDir: args.PutIntoNewDir, + SrcDir: dir, + } + if d.SendOverwrite { + req.SetBody(struct { + DecompressReq + Overwrite bool `json:"overwrite"` + }{body, args.Overwrite}) + return + } + req.SetBody(body) + }) + return err +} + +func ResolveLinkCacheMode(d State, _ string) driver.LinkCacheMode { + var mode driver.LinkCacheMode + if d.PassIP { + mode |= driver.LinkCacheIP + } + if d.PassUserAgent { + mode |= driver.LinkCacheUA + } + return mode +} diff --git a/drivers/internal/openlist/state.go b/drivers/internal/openlist/state.go new file mode 100644 index 0000000000..301407f4b7 --- /dev/null +++ b/drivers/internal/openlist/state.go @@ -0,0 +1,24 @@ +package openlist + +import ( + "github.com/OpenListTeam/OpenList/v4/internal/driver" +) + +// State is the product-specific configuration used by the shared AList/OpenList +// protocol implementation. Pointers keep login and address normalization updates +// on the registered driver value rather than on a copied adapter. +type State struct { + Driver driver.Driver + + Address *string + MetaPassword *string + Username *string + Password *string + Token *string + + PassIP bool + PassUserAgent bool + ForwardArchives bool + ForwardRefresh bool + SendOverwrite bool +} diff --git a/drivers/internal/openlist/types.go b/drivers/internal/openlist/types.go new file mode 100644 index 0000000000..f5c6a2ff53 --- /dev/null +++ b/drivers/internal/openlist/types.go @@ -0,0 +1,158 @@ +package openlist + +import ( + "time" + + "github.com/OpenListTeam/OpenList/v4/internal/model" + "github.com/OpenListTeam/OpenList/v4/pkg/utils" +) + +type ListReq struct { + model.PageReq + Path string `json:"path" form:"path"` + Password string `json:"password" form:"password"` + Refresh bool `json:"refresh"` +} + +type ObjResp struct { + Name string `json:"name"` + Size int64 `json:"size"` + IsDir bool `json:"is_dir"` + Modified time.Time `json:"modified"` + Created time.Time `json:"created"` + Sign string `json:"sign"` + Thumb string `json:"thumb"` + Type int `json:"type"` + HashInfo string `json:"hashinfo"` +} + +type FsListResp struct { + Content []ObjResp `json:"content"` + Total int64 `json:"total"` + Readme string `json:"readme"` + Write bool `json:"write"` + Provider string `json:"provider"` +} + +type FsGetReq struct { + Path string `json:"path" form:"path"` + Password string `json:"password" form:"password"` +} + +type FsGetResp struct { + ObjResp + RawURL string `json:"raw_url"` + Readme string `json:"readme"` + Provider string `json:"provider"` + Related []ObjResp `json:"related"` +} + +type MkdirOrLinkReq struct { + Path string `json:"path" form:"path"` +} + +type MoveCopyReq struct { + SrcDir string `json:"src_dir"` + DstDir string `json:"dst_dir"` + Names []string `json:"names"` +} + +type RenameReq struct { + Path string `json:"path"` + Name string `json:"name"` +} + +type RemoveReq struct { + Dir string `json:"dir"` + Names []string `json:"names"` +} + +type LoginResp struct { + Token string `json:"token"` +} + +type ArchiveMetaReq struct { + ArchivePass string `json:"archive_pass"` + Password string `json:"password"` + Path string `json:"path"` + Refresh bool `json:"refresh"` +} + +type TreeResp struct { + ObjResp + Children []TreeResp `json:"children"` + hashCache *utils.HashInfo +} + +func (t *TreeResp) GetSize() int64 { + return t.Size +} + +func (t *TreeResp) GetName() string { + return t.Name +} + +func (t *TreeResp) ModTime() time.Time { + return t.Modified +} + +func (t *TreeResp) CreateTime() time.Time { + return t.Created +} + +func (t *TreeResp) IsDir() bool { + return t.ObjResp.IsDir +} + +func (t *TreeResp) GetHash() utils.HashInfo { + return utils.FromString(t.HashInfo) +} + +func (t *TreeResp) GetID() string { + return "" +} + +func (t *TreeResp) GetPath() string { + return "" +} + +func (t *TreeResp) GetChildren() []model.ObjTree { + ret := make([]model.ObjTree, 0, len(t.Children)) + for _, child := range t.Children { + ret = append(ret, &child) + } + return ret +} + +func (t *TreeResp) Thumb() string { + return t.ObjResp.Thumb +} + +type ArchiveMetaResp struct { + Comment string `json:"comment"` + Encrypted bool `json:"encrypted"` + Content []TreeResp `json:"content"` + RawURL string `json:"raw_url"` + Sign string `json:"sign"` +} + +type ArchiveListReq struct { + model.PageReq + ArchiveMetaReq + InnerPath string `json:"inner_path"` +} + +type ArchiveListResp struct { + Content []ObjResp `json:"content"` + Total int64 `json:"total"` +} + +type DecompressReq struct { + ArchivePass string `json:"archive_pass"` + CacheFull bool `json:"cache_full"` + DstDir string `json:"dst_dir"` + InnerPath string `json:"inner_path"` + Name []string `json:"name"` + PutIntoNewDir bool `json:"put_into_new_dir"` + SrcDir string `json:"src_dir"` +} diff --git a/drivers/internal/openlist/util.go b/drivers/internal/openlist/util.go new file mode 100644 index 0000000000..3649713179 --- /dev/null +++ b/drivers/internal/openlist/util.go @@ -0,0 +1,97 @@ +package openlist + +import ( + "fmt" + "net/http" + "strings" + + "github.com/OpenListTeam/OpenList/v4/drivers/base" + "github.com/OpenListTeam/OpenList/v4/internal/conf" + "github.com/OpenListTeam/OpenList/v4/internal/op" + "github.com/OpenListTeam/OpenList/v4/pkg/utils" + "github.com/OpenListTeam/OpenList/v4/server/common" + "github.com/go-resty/resty/v2" + log "github.com/sirupsen/logrus" +) + +type Identity struct { + Username string + Guest bool +} + +func Init(d State, getIdentity func(State) (Identity, error)) error { + *d.Address = strings.TrimSuffix(*d.Address, "/") + identity, err := getIdentity(d) + if err != nil { + return err + } + if *d.Username != identity.Username { + if err := d.Login(); err != nil { + return err + } + } + identity, err = getIdentity(d) + if err != nil || !identity.Guest { + return err + } + res, err := base.RestyClient.R().Get(*d.Address + "/api/public/settings") + if err != nil { + return err + } + if utils.Json.Get(res.Body(), "data", conf.AllowMounted).ToString() != "true" { + return fmt.Errorf("the site does not allow mounted") + } + return nil +} + +func (d State) Login() error { + if *d.Username == "" { + return nil + } + var resp common.Resp[LoginResp] + _, _, err := d.Request("/auth/login", http.MethodPost, func(req *resty.Request) { + req.SetResult(&resp).SetBody(base.Json{ + "username": *d.Username, + "password": *d.Password, + }) + }) + if err != nil { + return err + } + *d.Token = resp.Data.Token + op.MustSaveDriverStorage(d.Driver) + return nil +} + +func (d State) Request(api, method string, callback base.ReqCallback, retry ...bool) ([]byte, int, error) { + url := *d.Address + "/api" + api + req := base.RestyClient.R() + req.SetHeader("Authorization", *d.Token) + if callback != nil { + callback(req) + } + res, err := req.Execute(method, url) + if err != nil { + code := 0 + if res != nil { + code = res.StatusCode() + } + return nil, code, err + } + log.Debugf("[openlist] response body: %s", res.String()) + if res.StatusCode() >= 400 { + return nil, res.StatusCode(), fmt.Errorf("request failed, status: %s", res.Status()) + } + code := utils.Json.Get(res.Body(), "code").ToInt() + if code != 200 { + if (code == 401 || code == 403) && !utils.IsBool(retry...) { + err = d.Login() + if err != nil { + return nil, code, err + } + return d.Request(api, method, callback, true) + } + return nil, code, fmt.Errorf("request failed,code: %d, message: %s", code, utils.Json.Get(res.Body(), "message").ToString()) + } + return res.Body(), 200, nil +} diff --git a/drivers/ipfs_api/meta.go b/drivers/ipfs_api/meta.go index 8293932bd6..63c1106646 100644 --- a/drivers/ipfs_api/meta.go +++ b/drivers/ipfs_api/meta.go @@ -2,7 +2,6 @@ package ipfs import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -19,8 +18,6 @@ var config = driver.Config{ LocalSort: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &IPFS{} - }) +func New() driver.Driver { + return &IPFS{} } diff --git a/drivers/kodbox/meta.go b/drivers/kodbox/meta.go index 0b8948069a..7aa04594be 100644 --- a/drivers/kodbox/meta.go +++ b/drivers/kodbox/meta.go @@ -2,7 +2,6 @@ package kodbox import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -17,8 +16,6 @@ var config = driver.Config{ Name: "KodBox", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &KodBox{} - }) +func New() driver.Driver { + return &KodBox{} } diff --git a/drivers/lanzou/meta.go b/drivers/lanzou/meta.go index fca9b88f51..6a733fc22c 100644 --- a/drivers/lanzou/meta.go +++ b/drivers/lanzou/meta.go @@ -2,7 +2,6 @@ package lanzou import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -35,8 +34,6 @@ var config = driver.Config{ DefaultRoot: "-1", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &LanZou{} - }) +func New() driver.Driver { + return &LanZou{} } diff --git a/drivers/lenovonas_share/driver.go b/drivers/lenovonas_share/driver.go index 526eb1f4e6..618df80070 100644 --- a/drivers/lenovonas_share/driver.go +++ b/drivers/lenovonas_share/driver.go @@ -12,7 +12,6 @@ import ( "github.com/go-resty/resty/v2" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/errs" "github.com/OpenListTeam/OpenList/v4/internal/model" "github.com/OpenListTeam/OpenList/v4/pkg/utils" ) @@ -139,28 +138,4 @@ func (d *LenovoNasShare) Link(ctx context.Context, file model.Obj, args model.Li return &link, nil } -func (d *LenovoNasShare) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) { - return nil, errs.NotImplement -} - -func (d *LenovoNasShare) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - return nil, errs.NotImplement -} - -func (d *LenovoNasShare) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) { - return nil, errs.NotImplement -} - -func (d *LenovoNasShare) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - return nil, errs.NotImplement -} - -func (d *LenovoNasShare) Remove(ctx context.Context, obj model.Obj) error { - return errs.NotImplement -} - -func (d *LenovoNasShare) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) { - return nil, errs.NotImplement -} - var _ driver.Driver = (*LenovoNasShare)(nil) diff --git a/drivers/lenovonas_share/meta.go b/drivers/lenovonas_share/meta.go index 456b749912..063e20e70f 100644 --- a/drivers/lenovonas_share/meta.go +++ b/drivers/lenovonas_share/meta.go @@ -2,7 +2,6 @@ package LenovoNasShare import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -19,8 +18,6 @@ var config = driver.Config{ NoUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &LenovoNasShare{} - }) +func New() driver.Driver { + return &LenovoNasShare{} } diff --git a/drivers/local/meta.go b/drivers/local/meta.go index f4536bd2f7..ab5e473dc6 100644 --- a/drivers/local/meta.go +++ b/drivers/local/meta.go @@ -2,7 +2,6 @@ package local import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -27,10 +26,8 @@ var config = driver.Config{ NoLinkURL: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Local{ - directoryMap: DirectoryMap{}, - } - }) +func New() driver.Driver { + return &Local{ + directoryMap: DirectoryMap{}, + } } diff --git a/drivers/mediafire/meta.go b/drivers/mediafire/meta.go index f5b420a252..86e9328fb6 100644 --- a/drivers/mediafire/meta.go +++ b/drivers/mediafire/meta.go @@ -17,7 +17,6 @@ Final opts by @Suyunjing @j2rong4cn @KirCute @Da3zKi7 import ( "github.com/OpenListTeam/OpenList/v4/drivers/base" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -36,25 +35,16 @@ type Addition struct { var config = driver.Config{ Name: "MediaFire", - LocalSort: false, - OnlyProxy: false, - NoCache: false, - NoUpload: false, - NeedMs: false, DefaultRoot: "/", - CheckStatus: false, - Alert: "", NoOverwriteUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Mediafire{ - appBase: "https://app.mediafire.com", - apiBase: "https://www.mediafire.com/api/1.5", - hostBase: "https://www.mediafire.com", - maxRetries: 3, - userAgent: base.UserAgent, - } - }) +func New() driver.Driver { + return &Mediafire{ + appBase: "https://app.mediafire.com", + apiBase: "https://www.mediafire.com/api/1.5", + hostBase: "https://www.mediafire.com", + maxRetries: 3, + userAgent: base.UserAgent, + } } diff --git a/drivers/mediatrack/meta.go b/drivers/mediatrack/meta.go index 8e099e4c5a..c3f0a03916 100644 --- a/drivers/mediatrack/meta.go +++ b/drivers/mediatrack/meta.go @@ -2,7 +2,6 @@ package mediatrack import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -17,8 +16,6 @@ var config = driver.Config{ Name: "MediaTrack", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &MediaTrack{} - }) +func New() driver.Driver { + return &MediaTrack{} } diff --git a/drivers/mega/driver.go b/drivers/mega/driver.go index f06b3fa98a..246896e696 100644 --- a/drivers/mega/driver.go +++ b/drivers/mega/driver.go @@ -12,7 +12,6 @@ import ( "github.com/rclone/rclone/lib/readers" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/errs" "github.com/OpenListTeam/OpenList/v4/internal/model" "github.com/OpenListTeam/OpenList/v4/internal/stream" "github.com/OpenListTeam/OpenList/v4/pkg/utils" @@ -146,10 +145,6 @@ func (d *Mega) Rename(ctx context.Context, srcObj model.Obj, newName string) err return fmt.Errorf("unable to convert dir to mega n") } -func (d *Mega) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { - return errs.NotImplement -} - func (d *Mega) Remove(ctx context.Context, obj model.Obj) error { if node, ok := obj.(*MegaNode); ok { return d.c.Delete(node.n, !d.MoveToTrash) diff --git a/drivers/mega/meta.go b/drivers/mega/meta.go index 17db29d758..effe2d22ff 100644 --- a/drivers/mega/meta.go +++ b/drivers/mega/meta.go @@ -2,7 +2,6 @@ package mega import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -23,8 +22,6 @@ var config = driver.Config{ NoLinkURL: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Mega{} - }) +func New() driver.Driver { + return &Mega{} } diff --git a/drivers/misskey/meta.go b/drivers/misskey/meta.go index 8fbb49d95a..2c8239295b 100644 --- a/drivers/misskey/meta.go +++ b/drivers/misskey/meta.go @@ -2,7 +2,6 @@ package misskey import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -19,8 +18,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Misskey{} - }) +func New() driver.Driver { + return &Misskey{} } diff --git a/drivers/mopan/meta.go b/drivers/mopan/meta.go index dd5c289cb0..c95f99f018 100644 --- a/drivers/mopan/meta.go +++ b/drivers/mopan/meta.go @@ -2,7 +2,6 @@ package mopan import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -32,8 +31,6 @@ var config = driver.Config{ Alert: "warning|This network disk may store your password in clear text. Please set your password carefully", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &MoPan{} - }) +func New() driver.Driver { + return &MoPan{} } diff --git a/drivers/netease_music/meta.go b/drivers/netease_music/meta.go index 10d32922f2..af83b4e0f2 100644 --- a/drivers/netease_music/meta.go +++ b/drivers/netease_music/meta.go @@ -4,7 +4,6 @@ import ( "regexp" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -25,8 +24,6 @@ var config = driver.Config{ Name: "NeteaseMusic", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &NeteaseMusic{} - }) +func New() driver.Driver { + return &NeteaseMusic{} } diff --git a/drivers/onedrive/meta.go b/drivers/onedrive/meta.go index 4fd505b9c5..7298beb268 100644 --- a/drivers/onedrive/meta.go +++ b/drivers/onedrive/meta.go @@ -2,7 +2,6 @@ package onedrive import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -28,8 +27,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Onedrive{} - }) +func New() driver.Driver { + return &Onedrive{} } diff --git a/drivers/onedrive_app/meta.go b/drivers/onedrive_app/meta.go index c3f0c02ecd..3440c6c499 100644 --- a/drivers/onedrive_app/meta.go +++ b/drivers/onedrive_app/meta.go @@ -2,7 +2,6 @@ package onedrive_app import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -24,8 +23,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &OnedriveAPP{} - }) +func New() driver.Driver { + return &OnedriveAPP{} } diff --git a/drivers/onedrive_sharelink/driver.go b/drivers/onedrive_sharelink/driver.go index a975772ac0..fa939bbef7 100644 --- a/drivers/onedrive_sharelink/driver.go +++ b/drivers/onedrive_sharelink/driver.go @@ -168,26 +168,6 @@ func (d *OnedriveSharelink) MakeDir(ctx context.Context, parentDir model.Obj, di } } -func (d *OnedriveSharelink) Move(ctx context.Context, srcObj, dstDir model.Obj) error { - // TODO move obj, optional - return errs.NotImplement -} - -func (d *OnedriveSharelink) Rename(ctx context.Context, srcObj model.Obj, newName string) error { - // TODO rename obj, optional - return errs.NotImplement -} - -func (d *OnedriveSharelink) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { - // TODO copy obj, optional - return errs.NotImplement -} - -func (d *OnedriveSharelink) Remove(ctx context.Context, obj model.Obj) error { - // TODO remove obj, optional - return errs.NotImplement -} - func (d *OnedriveSharelink) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error { info, err := d.createUploadInfo(ctx, stdpath.Join(dstDir.GetPath(), stream.GetName()), stream.GetSize()) if err != nil { diff --git a/drivers/onedrive_sharelink/meta.go b/drivers/onedrive_sharelink/meta.go index 1aed1b0bad..fd38bfcdba 100644 --- a/drivers/onedrive_sharelink/meta.go +++ b/drivers/onedrive_sharelink/meta.go @@ -4,7 +4,6 @@ import ( "net/http" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -29,8 +28,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &OnedriveSharelink{} - }) +func New() driver.Driver { + return &OnedriveSharelink{} } diff --git a/drivers/openlist/driver.go b/drivers/openlist/driver.go index 79fc511854..20833688ee 100644 --- a/drivers/openlist/driver.go +++ b/drivers/openlist/driver.go @@ -2,22 +2,13 @@ package openlist import ( "context" - "fmt" - "io" "net/http" - "net/url" - "path" - "strings" - "github.com/OpenListTeam/OpenList/v4/drivers/base" - "github.com/OpenListTeam/OpenList/v4/internal/conf" + family "github.com/OpenListTeam/OpenList/v4/drivers/internal/openlist" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/errs" "github.com/OpenListTeam/OpenList/v4/internal/model" - "github.com/OpenListTeam/OpenList/v4/pkg/utils" "github.com/OpenListTeam/OpenList/v4/server/common" "github.com/go-resty/resty/v2" - log "github.com/sirupsen/logrus" ) type OpenList struct { @@ -25,357 +16,83 @@ type OpenList struct { Addition } -func (d *OpenList) Config() driver.Config { - return config -} +func (d *OpenList) Config() driver.Config { return config } -func (d *OpenList) GetAddition() driver.Additional { - return &d.Addition -} +func (d *OpenList) GetAddition() driver.Additional { return &d.Addition } -func (d *OpenList) Init(ctx context.Context) error { - d.Addition.Address = strings.TrimSuffix(d.Addition.Address, "/") - var resp common.Resp[MeResp] - _, _, err := d.request("/me", http.MethodGet, func(req *resty.Request) { - req.SetResult(&resp) - }) - if err != nil { - return err - } - // if the username is not empty and the username is not the same as the current username, then login again - if d.Username != resp.Data.Username { - err = d.login() - if err != nil { - return err - } - } - // re-get the user info - _, _, err = d.request("/me", http.MethodGet, func(req *resty.Request) { - req.SetResult(&resp) - }) - if err != nil { - return err - } - if resp.Data.Role == model.GUEST { - u := d.Address + "/api/public/settings" - res, err := base.RestyClient.R().Get(u) - if err != nil { - return err - } - allowMounted := utils.Json.Get(res.Body(), "data", conf.AllowMounted).ToString() == "true" - if !allowMounted { - return fmt.Errorf("the site does not allow mounted") - } +func (d *OpenList) state() family.State { + return family.State{ + Driver: d, Address: &d.Address, MetaPassword: &d.MetaPassword, + Username: &d.Username, Password: &d.Password, Token: &d.Token, + PassIP: d.PassIPToUpsteam, PassUserAgent: d.PassUAToUpsteam, + ForwardArchives: d.ForwardArchiveReq, + ForwardRefresh: d.PassRefreshFlagToUpsteam, SendOverwrite: true, } - return err } -func (d *OpenList) Drop(ctx context.Context) error { - return nil +func (d *OpenList) Init(context.Context) error { + return family.Init(d.state(), func(s family.State) (family.Identity, error) { + var resp common.Resp[MeResp] + _, _, err := s.Request("/me", http.MethodGet, func(req *resty.Request) { req.SetResult(&resp) }) + return family.Identity{ + Username: resp.Data.Username, + Guest: resp.Data.Role == model.GUEST, + }, err + }) } +func (d *OpenList) Drop(context.Context) error { return nil } + func (d *OpenList) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { - var resp common.Resp[FsListResp] - _, _, err := d.request("/fs/list", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(ListReq{ - PageReq: model.PageReq{ - Page: 1, - PerPage: 0, - }, - Path: dir.GetPath(), - Password: d.MetaPassword, - Refresh: d.PassRefreshFlagToUpsteam && args.Refresh, - }) - }) - if err != nil { - return nil, err - } - var files []model.Obj - for _, f := range resp.Data.Content { - file := model.ObjThumb{ - Object: model.Object{ - Name: f.Name, - Path: path.Join(dir.GetPath(), f.Name), - Modified: f.Modified, - Ctime: f.Created, - Size: f.Size, - IsFolder: f.IsDir, - HashInfo: utils.FromString(f.HashInfo), - }, - Thumbnail: model.Thumbnail{Thumbnail: f.Thumb}, - } - files = append(files, &file) - } - return files, nil + return family.List(d.state(), ctx, dir, args) } func (d *OpenList) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { - var resp common.Resp[FsGetResp] - headers := map[string]string{ - "User-Agent": base.UserAgent, - } - // if PassUAToUpsteam is true, then pass the user-agent to the upstream - if d.PassUAToUpsteam { - userAgent := args.Header.Get("user-agent") - if userAgent != "" { - headers["User-Agent"] = userAgent - } - } - // if PassIPToUpsteam is true, then pass the ip address to the upstream - if d.PassIPToUpsteam { - ip := args.IP - if ip != "" { - headers["X-Forwarded-For"] = ip - headers["X-Real-Ip"] = ip - } - } - _, _, err := d.request("/fs/get", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(FsGetReq{ - Path: file.GetPath(), - Password: d.MetaPassword, - }).SetHeaders(headers) - }) - if err != nil { - return nil, err - } - return &model.Link{ - URL: resp.Data.RawURL, - }, nil + return family.Link(d.state(), ctx, file, args) } -func (d *OpenList) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error { - _, _, err := d.request("/fs/mkdir", http.MethodPost, func(req *resty.Request) { - req.SetBody(MkdirOrLinkReq{ - Path: path.Join(parentDir.GetPath(), dirName), - }) - }) - return err +func (d *OpenList) MakeDir(ctx context.Context, parent model.Obj, name string) error { + return family.MakeDir(d.state(), ctx, parent, name) } -func (d *OpenList) Move(ctx context.Context, srcObj, dstDir model.Obj) error { - _, _, err := d.request("/fs/move", http.MethodPost, func(req *resty.Request) { - req.SetBody(MoveCopyReq{ - SrcDir: path.Dir(srcObj.GetPath()), - DstDir: dstDir.GetPath(), - Names: []string{srcObj.GetName()}, - }) - }) - return err +func (d *OpenList) Move(ctx context.Context, src, dst model.Obj) error { + return family.Move(d.state(), ctx, src, dst) } -func (d *OpenList) Rename(ctx context.Context, srcObj model.Obj, newName string) error { - _, _, err := d.request("/fs/rename", http.MethodPost, func(req *resty.Request) { - req.SetBody(RenameReq{ - Path: srcObj.GetPath(), - Name: newName, - }) - }) - return err +func (d *OpenList) Rename(ctx context.Context, src model.Obj, name string) error { + return family.Rename(d.state(), ctx, src, name) } -func (d *OpenList) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { - _, _, err := d.request("/fs/copy", http.MethodPost, func(req *resty.Request) { - req.SetBody(MoveCopyReq{ - SrcDir: path.Dir(srcObj.GetPath()), - DstDir: dstDir.GetPath(), - Names: []string{srcObj.GetName()}, - }) - }) - return err +func (d *OpenList) Copy(ctx context.Context, src, dst model.Obj) error { + return family.Copy(d.state(), ctx, src, dst) } func (d *OpenList) Remove(ctx context.Context, obj model.Obj) error { - _, _, err := d.request("/fs/remove", http.MethodPost, func(req *resty.Request) { - req.SetBody(RemoveReq{ - Dir: path.Dir(obj.GetPath()), - Names: []string{obj.GetName()}, - }) - }) - return err + return family.Remove(d.state(), ctx, obj) } -func (d *OpenList) Put(ctx context.Context, dstDir model.Obj, s model.FileStreamer, up driver.UpdateProgress) error { - reader := driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{ - Reader: s, - UpdateProgress: up, - }) - req, err := http.NewRequestWithContext(ctx, http.MethodPut, d.Address+"/api/fs/put", reader) - if err != nil { - return err - } - req.Header.Set("Authorization", d.Token) - req.Header.Set("File-Path", path.Join(dstDir.GetPath(), s.GetName())) - req.Header.Set("Password", d.MetaPassword) - if md5 := s.GetHash().GetHash(utils.MD5); len(md5) > 0 { - req.Header.Set("X-File-Md5", md5) - } - if sha1 := s.GetHash().GetHash(utils.SHA1); len(sha1) > 0 { - req.Header.Set("X-File-Sha1", sha1) - } - if sha256 := s.GetHash().GetHash(utils.SHA256); len(sha256) > 0 { - req.Header.Set("X-File-Sha256", sha256) - } - - req.ContentLength = s.GetSize() - // client := base.NewHttpClient() - // client.Timeout = time.Hour * 6 - res, err := base.HttpClient.Do(req) - if err != nil { - return err - } - - bytes, err := io.ReadAll(res.Body) - if err != nil { - return err - } - log.Debugf("[openlist] response body: %s", string(bytes)) - if res.StatusCode >= 400 { - return fmt.Errorf("request failed, status: %s", res.Status) - } - code := utils.Json.Get(bytes, "code").ToInt() - if code != 200 { - if code == 401 || code == 403 { - err = d.login() - if err != nil { - return err - } - } - return fmt.Errorf("request failed,code: %d, message: %s", code, utils.Json.Get(bytes, "message").ToString()) - } - return nil +func (d *OpenList) Put(ctx context.Context, dst model.Obj, src model.FileStreamer, up driver.UpdateProgress) error { + return family.Put(d.state(), ctx, dst, src, up) } func (d *OpenList) GetArchiveMeta(ctx context.Context, obj model.Obj, args model.ArchiveArgs) (model.ArchiveMeta, error) { - if !d.ForwardArchiveReq { - return nil, errs.NotImplement - } - var resp common.Resp[ArchiveMetaResp] - _, code, err := d.request("/fs/archive/meta", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(ArchiveMetaReq{ - ArchivePass: args.Password, - Password: d.MetaPassword, - Path: obj.GetPath(), - Refresh: false, - }) - }) - if code == 202 { - return nil, errs.WrongArchivePassword - } - if err != nil { - return nil, err - } - var tree []model.ObjTree - if resp.Data.Content != nil { - tree = make([]model.ObjTree, 0, len(resp.Data.Content)) - for _, content := range resp.Data.Content { - tree = append(tree, &content) - } - } - return &model.ArchiveMetaInfo{ - Comment: resp.Data.Comment, - Encrypted: resp.Data.Encrypted, - Tree: tree, - }, nil + return family.GetArchiveMeta(d.state(), ctx, obj, args) } func (d *OpenList) ListArchive(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) ([]model.Obj, error) { - if !d.ForwardArchiveReq { - return nil, errs.NotImplement - } - var resp common.Resp[ArchiveListResp] - _, code, err := d.request("/fs/archive/list", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(ArchiveListReq{ - ArchiveMetaReq: ArchiveMetaReq{ - ArchivePass: args.Password, - Password: d.MetaPassword, - Path: obj.GetPath(), - Refresh: false, - }, - PageReq: model.PageReq{ - Page: 1, - PerPage: 0, - }, - InnerPath: args.InnerPath, - }) - }) - if code == 202 { - return nil, errs.WrongArchivePassword - } - if err != nil { - return nil, err - } - var files []model.Obj - for _, f := range resp.Data.Content { - file := model.ObjThumb{ - Object: model.Object{ - Name: f.Name, - Modified: f.Modified, - Ctime: f.Created, - Size: f.Size, - IsFolder: f.IsDir, - HashInfo: utils.FromString(f.HashInfo), - }, - Thumbnail: model.Thumbnail{Thumbnail: f.Thumb}, - } - files = append(files, &file) - } - return files, nil + return family.ListArchive(d.state(), ctx, obj, args) } func (d *OpenList) Extract(ctx context.Context, obj model.Obj, args model.ArchiveInnerArgs) (*model.Link, error) { - if !d.ForwardArchiveReq { - return nil, errs.NotSupport - } - var resp common.Resp[ArchiveMetaResp] - _, _, err := d.request("/fs/archive/meta", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(ArchiveMetaReq{ - ArchivePass: args.Password, - Password: d.MetaPassword, - Path: obj.GetPath(), - Refresh: false, - }) - }) - if err != nil { - return nil, err - } - return &model.Link{ - URL: fmt.Sprintf("%s?inner=%s&pass=%s&sign=%s", - resp.Data.RawURL, - utils.EncodePath(args.InnerPath, true), - url.QueryEscape(args.Password), - resp.Data.Sign), - }, nil + return family.Extract(d.state(), ctx, obj, args) } -func (d *OpenList) ArchiveDecompress(ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) error { - if !d.ForwardArchiveReq { - return errs.NotImplement - } - dir, name := path.Split(srcObj.GetPath()) - _, _, err := d.request("/fs/archive/decompress", http.MethodPost, func(req *resty.Request) { - req.SetBody(DecompressReq{ - ArchivePass: args.Password, - CacheFull: args.CacheFull, - DstDir: dstDir.GetPath(), - InnerPath: args.InnerPath, - Name: []string{name}, - PutIntoNewDir: args.PutIntoNewDir, - SrcDir: dir, - Overwrite: args.Overwrite, - }) - }) - return err +func (d *OpenList) ArchiveDecompress(ctx context.Context, src, dst model.Obj, args model.ArchiveDecompressArgs) error { + return family.ArchiveDecompress(d.state(), ctx, src, dst, args) } -func (d *OpenList) ResolveLinkCacheMode(_ string) driver.LinkCacheMode { - var mode driver.LinkCacheMode - if d.PassIPToUpsteam { - mode |= driver.LinkCacheIP - } - if d.PassUAToUpsteam { - mode |= driver.LinkCacheUA - } - return mode +func (d *OpenList) ResolveLinkCacheMode(path string) driver.LinkCacheMode { + return family.ResolveLinkCacheMode(d.state(), path) } var _ driver.Driver = (*OpenList)(nil) diff --git a/drivers/openlist/meta.go b/drivers/openlist/meta.go index 3c4d0801a1..bff3236fee 100644 --- a/drivers/openlist/meta.go +++ b/drivers/openlist/meta.go @@ -2,7 +2,6 @@ package openlist import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -26,8 +25,6 @@ var config = driver.Config{ LinkCacheMode: driver.LinkCacheAuto, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &OpenList{} - }) +func New() driver.Driver { + return &OpenList{} } diff --git a/drivers/openlist/types.go b/drivers/openlist/types.go index ffc3e350a4..b3405e010c 100644 --- a/drivers/openlist/types.go +++ b/drivers/openlist/types.go @@ -1,75 +1,22 @@ package openlist -import ( - "time" - - "github.com/OpenListTeam/OpenList/v4/internal/model" - "github.com/OpenListTeam/OpenList/v4/pkg/utils" -) - -type ListReq struct { - model.PageReq - Path string `json:"path" form:"path"` - Password string `json:"password" form:"password"` - Refresh bool `json:"refresh"` -} - -type ObjResp struct { - Name string `json:"name"` - Size int64 `json:"size"` - IsDir bool `json:"is_dir"` - Modified time.Time `json:"modified"` - Created time.Time `json:"created"` - Sign string `json:"sign"` - Thumb string `json:"thumb"` - Type int `json:"type"` - HashInfo string `json:"hashinfo"` -} - -type FsListResp struct { - Content []ObjResp `json:"content"` - Total int64 `json:"total"` - Readme string `json:"readme"` - Write bool `json:"write"` - Provider string `json:"provider"` -} - -type FsGetReq struct { - Path string `json:"path" form:"path"` - Password string `json:"password" form:"password"` -} - -type FsGetResp struct { - ObjResp - RawURL string `json:"raw_url"` - Readme string `json:"readme"` - Provider string `json:"provider"` - Related []ObjResp `json:"related"` -} - -type MkdirOrLinkReq struct { - Path string `json:"path" form:"path"` -} - -type MoveCopyReq struct { - SrcDir string `json:"src_dir"` - DstDir string `json:"dst_dir"` - Names []string `json:"names"` -} - -type RenameReq struct { - Path string `json:"path"` - Name string `json:"name"` -} - -type RemoveReq struct { - Dir string `json:"dir"` - Names []string `json:"names"` -} - -type LoginResp struct { - Token string `json:"token"` -} +import family "github.com/OpenListTeam/OpenList/v4/drivers/internal/openlist" + +type ListReq = family.ListReq +type ObjResp = family.ObjResp +type FsListResp = family.FsListResp +type FsGetReq = family.FsGetReq +type FsGetResp = family.FsGetResp +type MkdirOrLinkReq = family.MkdirOrLinkReq +type MoveCopyReq = family.MoveCopyReq +type RenameReq = family.RenameReq +type RemoveReq = family.RemoveReq +type LoginResp = family.LoginResp +type ArchiveMetaReq = family.ArchiveMetaReq +type TreeResp = family.TreeResp +type ArchiveMetaResp = family.ArchiveMetaResp +type ArchiveListReq = family.ArchiveListReq +type ArchiveListResp = family.ArchiveListResp type MeResp struct { Id int `json:"id"` @@ -83,82 +30,6 @@ type MeResp struct { Otp bool `json:"otp"` } -type ArchiveMetaReq struct { - ArchivePass string `json:"archive_pass"` - Password string `json:"password"` - Path string `json:"path"` - Refresh bool `json:"refresh"` -} - -type TreeResp struct { - ObjResp - Children []TreeResp `json:"children"` - hashCache *utils.HashInfo -} - -func (t *TreeResp) GetSize() int64 { - return t.Size -} - -func (t *TreeResp) GetName() string { - return t.Name -} - -func (t *TreeResp) ModTime() time.Time { - return t.Modified -} - -func (t *TreeResp) CreateTime() time.Time { - return t.Created -} - -func (t *TreeResp) IsDir() bool { - return t.ObjResp.IsDir -} - -func (t *TreeResp) GetHash() utils.HashInfo { - return utils.FromString(t.HashInfo) -} - -func (t *TreeResp) GetID() string { - return "" -} - -func (t *TreeResp) GetPath() string { - return "" -} - -func (t *TreeResp) GetChildren() []model.ObjTree { - ret := make([]model.ObjTree, 0, len(t.Children)) - for _, child := range t.Children { - ret = append(ret, &child) - } - return ret -} - -func (t *TreeResp) Thumb() string { - return t.ObjResp.Thumb -} - -type ArchiveMetaResp struct { - Comment string `json:"comment"` - Encrypted bool `json:"encrypted"` - Content []TreeResp `json:"content"` - RawURL string `json:"raw_url"` - Sign string `json:"sign"` -} - -type ArchiveListReq struct { - model.PageReq - ArchiveMetaReq - InnerPath string `json:"inner_path"` -} - -type ArchiveListResp struct { - Content []ObjResp `json:"content"` - Total int64 `json:"total"` -} - type DecompressReq struct { ArchivePass string `json:"archive_pass"` CacheFull bool `json:"cache_full"` diff --git a/drivers/openlist/util.go b/drivers/openlist/util.go deleted file mode 100644 index 743ba266be..0000000000 --- a/drivers/openlist/util.go +++ /dev/null @@ -1,65 +0,0 @@ -package openlist - -import ( - "fmt" - "net/http" - - "github.com/OpenListTeam/OpenList/v4/drivers/base" - "github.com/OpenListTeam/OpenList/v4/internal/op" - "github.com/OpenListTeam/OpenList/v4/pkg/utils" - "github.com/OpenListTeam/OpenList/v4/server/common" - "github.com/go-resty/resty/v2" - log "github.com/sirupsen/logrus" -) - -func (d *OpenList) login() error { - if d.Username == "" { - return nil - } - var resp common.Resp[LoginResp] - _, _, err := d.request("/auth/login", http.MethodPost, func(req *resty.Request) { - req.SetResult(&resp).SetBody(base.Json{ - "username": d.Username, - "password": d.Password, - }) - }) - if err != nil { - return err - } - d.Token = resp.Data.Token - op.MustSaveDriverStorage(d) - return nil -} - -func (d *OpenList) request(api, method string, callback base.ReqCallback, retry ...bool) ([]byte, int, error) { - url := d.Address + "/api" + api - req := base.RestyClient.R() - req.SetHeader("Authorization", d.Token) - if callback != nil { - callback(req) - } - res, err := req.Execute(method, url) - if err != nil { - code := 0 - if res != nil { - code = res.StatusCode() - } - return nil, code, err - } - log.Debugf("[openlist] response body: %s", res.String()) - if res.StatusCode() >= 400 { - return nil, res.StatusCode(), fmt.Errorf("request failed, status: %s", res.Status()) - } - code := utils.Json.Get(res.Body(), "code").ToInt() - if code != 200 { - if (code == 401 || code == 403) && !utils.IsBool(retry...) { - err = d.login() - if err != nil { - return nil, code, err - } - return d.request(api, method, callback, true) - } - return nil, code, fmt.Errorf("request failed,code: %d, message: %s", code, utils.Json.Get(res.Body(), "message").ToString()) - } - return res.Body(), 200, nil -} diff --git a/drivers/openlist_share/meta.go b/drivers/openlist_share/meta.go index cad4903acc..420ec51493 100644 --- a/drivers/openlist_share/meta.go +++ b/drivers/openlist_share/meta.go @@ -2,7 +2,6 @@ package openlist_share import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -20,8 +19,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &OpenListShare{} - }) +func New() driver.Driver { + return &OpenListShare{} } diff --git a/drivers/pikpak/meta.go b/drivers/pikpak/meta.go index da3da551d2..3564b3212e 100644 --- a/drivers/pikpak/meta.go +++ b/drivers/pikpak/meta.go @@ -2,7 +2,6 @@ package pikpak import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,8 +21,6 @@ var config = driver.Config{ LocalSort: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &PikPak{} - }) +func New() driver.Driver { + return &PikPak{} } diff --git a/drivers/pikpak_share/meta.go b/drivers/pikpak_share/meta.go index 18842de23c..6038517af4 100644 --- a/drivers/pikpak_share/meta.go +++ b/drivers/pikpak_share/meta.go @@ -2,7 +2,6 @@ package pikpak_share import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -20,8 +19,6 @@ var config = driver.Config{ NoUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &PikPakShare{} - }) +func New() driver.Driver { + return &PikPakShare{} } diff --git a/drivers/proton_drive/meta.go b/drivers/proton_drive/meta.go index acf6567794..d6d4cf949d 100644 --- a/drivers/proton_drive/meta.go +++ b/drivers/proton_drive/meta.go @@ -17,7 +17,7 @@ D@' 3z K!7 - The King Of Cracking import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" + "github.com/henrybear327/Proton-API-Bridge/common" ) @@ -39,18 +39,16 @@ var config = driver.Config{ NoLinkURL: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &ProtonDrive{ - Addition: Addition{ - UseReusableLogin: true, - }, - apiBase: "https://drive.proton.me/api", - appVersion: "windows-drive@1.11.3+rclone+proton", - protonJson: "application/vnd.protonmail.v1+json", - sdkVersion: "js@0.3.0", - userAgent: "ProtonDrive/v1.70.0 (Windows NT 10.0.22000; Win64; x64)", - webDriveAV: "web-drive@5.2.0+0f69f7a8", - } - }) +func New() driver.Driver { + return &ProtonDrive{ + Addition: Addition{ + UseReusableLogin: true, + }, + apiBase: "https://drive.proton.me/api", + appVersion: "windows-drive@1.11.3+rclone+proton", + protonJson: "application/vnd.protonmail.v1+json", + sdkVersion: "js@0.3.0", + userAgent: "ProtonDrive/v1.70.0 (Windows NT 10.0.22000; Win64; x64)", + webDriveAV: "web-drive@5.2.0+0f69f7a8", + } } diff --git a/drivers/quark_open/meta.go b/drivers/quark_open/meta.go index 3527b52e9c..ca4371f56e 100644 --- a/drivers/quark_open/meta.go +++ b/drivers/quark_open/meta.go @@ -2,7 +2,6 @@ package quark_open import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -23,19 +22,17 @@ type Conf struct { userId string } -func init() { - op.RegisterDriver(func() driver.Driver { - return &QuarkOpen{ - config: driver.Config{ - Name: "QuarkOpen", - OnlyProxy: true, - DefaultRoot: "0", - NoOverwriteUpload: true, - }, - conf: Conf{ - ua: "go-resty/3.0.0-beta.1 (https://resty.dev)", - api: "https://open-api-drive.quark.cn", - }, - } - }) +func New() driver.Driver { + return &QuarkOpen{ + config: driver.Config{ + Name: "QuarkOpen", + OnlyProxy: true, + DefaultRoot: "0", + NoOverwriteUpload: true, + }, + conf: Conf{ + ua: "go-resty/3.0.0-beta.1 (https://resty.dev)", + api: "https://open-api-drive.quark.cn", + }, + } } diff --git a/drivers/quark_uc/meta.go b/drivers/quark_uc/meta.go index a3694e4e5e..36b369d28b 100644 --- a/drivers/quark_uc/meta.go +++ b/drivers/quark_uc/meta.go @@ -2,7 +2,6 @@ package quark import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,36 +21,34 @@ type Conf struct { pr string } -func init() { - op.RegisterDriver(func() driver.Driver { - return &QuarkOrUC{ - config: driver.Config{ - Name: "Quark", - DefaultRoot: "0", - NoOverwriteUpload: true, - }, - conf: Conf{ - ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch", - referer: "https://pan.quark.cn", - api: "https://drive.quark.cn/1/clouddrive", - pr: "ucpro", - }, - } - }) - op.RegisterDriver(func() driver.Driver { - return &QuarkOrUC{ - config: driver.Config{ - Name: "UC", - OnlyProxy: true, - DefaultRoot: "0", - NoOverwriteUpload: true, - }, - conf: Conf{ - ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) uc-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch", - referer: "https://drive.uc.cn", - api: "https://pc-api.uc.cn/1/clouddrive", - pr: "UCBrowser", - }, - } - }) +func New() driver.Driver { + return &QuarkOrUC{ + config: driver.Config{ + Name: "Quark", + DefaultRoot: "0", + NoOverwriteUpload: true, + }, + conf: Conf{ + ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) quark-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch", + referer: "https://pan.quark.cn", + api: "https://drive.quark.cn/1/clouddrive", + pr: "ucpro", + }, + } +} +func New2() driver.Driver { + return &QuarkOrUC{ + config: driver.Config{ + Name: "UC", + OnlyProxy: true, + DefaultRoot: "0", + NoOverwriteUpload: true, + }, + conf: Conf{ + ua: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) uc-cloud-drive/2.5.20 Chrome/100.0.4896.160 Electron/18.3.5.4-b478491100 Safari/537.36 Channel/pckk_other_ch", + referer: "https://drive.uc.cn", + api: "https://pc-api.uc.cn/1/clouddrive", + pr: "UCBrowser", + }, + } } diff --git a/drivers/quark_uc_tv/driver.go b/drivers/quark_uc_tv/driver.go index dc062d9ffb..9f64a90634 100644 --- a/drivers/quark_uc_tv/driver.go +++ b/drivers/quark_uc_tv/driver.go @@ -12,7 +12,6 @@ import ( "github.com/go-resty/resty/v2" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/errs" "github.com/OpenListTeam/OpenList/v4/internal/model" ) @@ -144,30 +143,6 @@ func (d *QuarkUCTV) Link(ctx context.Context, file model.Obj, args model.LinkArg return d.getDownloadLink(ctx, file) } -func (d *QuarkUCTV) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) { - return nil, errs.NotImplement -} - -func (d *QuarkUCTV) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - return nil, errs.NotImplement -} - -func (d *QuarkUCTV) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) { - return nil, errs.NotImplement -} - -func (d *QuarkUCTV) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { - return nil, errs.NotImplement -} - -func (d *QuarkUCTV) Remove(ctx context.Context, obj model.Obj) error { - return errs.NotImplement -} - -func (d *QuarkUCTV) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) { - return nil, errs.NotImplement -} - type QuarkUCTVCommon struct { AccessToken string } diff --git a/drivers/quark_uc_tv/meta.go b/drivers/quark_uc_tv/meta.go index c1e871dd85..d1f0823409 100644 --- a/drivers/quark_uc_tv/meta.go +++ b/drivers/quark_uc_tv/meta.go @@ -2,7 +2,6 @@ package quark_uc_tv import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -29,41 +28,39 @@ type Conf struct { codeApi string } -func init() { - op.RegisterDriver(func() driver.Driver { - return &QuarkUCTV{ - config: driver.Config{ - Name: "QuarkTV", - DefaultRoot: "0", - NoOverwriteUpload: true, - NoUpload: true, - }, - conf: Conf{ - api: "https://open-api-drive.quark.cn", - clientID: "d3194e61504e493eb6222857bccfed94", - signKey: "kw2dvtd7p4t3pjl2d9ed9yc8yej8kw2d", - appVer: "1.8.2.2", - channel: "GENERAL", - codeApi: "http://api.extscreen.com/quarkdrive", - }, - } - }) - op.RegisterDriver(func() driver.Driver { - return &QuarkUCTV{ - config: driver.Config{ - Name: "UCTV", - DefaultRoot: "0", - NoOverwriteUpload: true, - NoUpload: true, - }, - conf: Conf{ - api: "https://open-api-drive.uc.cn", - clientID: "5acf882d27b74502b7040b0c65519aa7", - signKey: "l3srvtd7p42l0d0x1u8d7yc8ye9kki4d", - appVer: "1.7.2.2", - channel: "UCTVOFFICIALWEB", - codeApi: "http://api.extscreen.com/ucdrive", - }, - } - }) +func New() driver.Driver { + return &QuarkUCTV{ + config: driver.Config{ + Name: "QuarkTV", + DefaultRoot: "0", + NoOverwriteUpload: true, + NoUpload: true, + }, + conf: Conf{ + api: "https://open-api-drive.quark.cn", + clientID: "d3194e61504e493eb6222857bccfed94", + signKey: "kw2dvtd7p4t3pjl2d9ed9yc8yej8kw2d", + appVer: "1.8.2.2", + channel: "GENERAL", + codeApi: "http://api.extscreen.com/quarkdrive", + }, + } +} +func New2() driver.Driver { + return &QuarkUCTV{ + config: driver.Config{ + Name: "UCTV", + DefaultRoot: "0", + NoOverwriteUpload: true, + NoUpload: true, + }, + conf: Conf{ + api: "https://open-api-drive.uc.cn", + clientID: "5acf882d27b74502b7040b0c65519aa7", + signKey: "l3srvtd7p42l0d0x1u8d7yc8ye9kki4d", + appVer: "1.7.2.2", + channel: "UCTVOFFICIALWEB", + codeApi: "http://api.extscreen.com/ucdrive", + }, + } } diff --git a/drivers/s3/meta.go b/drivers/s3/meta.go index 4243f12d56..dcf3fdcb39 100644 --- a/drivers/s3/meta.go +++ b/drivers/s3/meta.go @@ -2,7 +2,6 @@ package s3 import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -26,25 +25,23 @@ type Addition struct { UserAgent string `json:"user_agent" required:"false" default:"" help:"Custom User-Agent for S3 requests."` } -func init() { - op.RegisterDriver(func() driver.Driver { - return &S3{ - config: driver.Config{ - Name: "S3", - DefaultRoot: "/", - LocalSort: true, - CheckStatus: true, - }, - } - }) - op.RegisterDriver(func() driver.Driver { - return &S3{ - config: driver.Config{ - Name: "Doge", - DefaultRoot: "/", - LocalSort: true, - CheckStatus: true, - }, - } - }) +func New() driver.Driver { + return &S3{ + config: driver.Config{ + Name: "S3", + DefaultRoot: "/", + LocalSort: true, + CheckStatus: true, + }, + } +} +func New2() driver.Driver { + return &S3{ + config: driver.Config{ + Name: "Doge", + DefaultRoot: "/", + LocalSort: true, + CheckStatus: true, + }, + } } diff --git a/drivers/seafile/meta.go b/drivers/seafile/meta.go index 7077f290d3..5f52118934 100644 --- a/drivers/seafile/meta.go +++ b/drivers/seafile/meta.go @@ -2,7 +2,6 @@ package seafile import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -21,8 +20,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Seafile{} - }) +func New() driver.Driver { + return &Seafile{} } diff --git a/drivers/sftp/meta.go b/drivers/sftp/meta.go index 1c9bd3e331..52c356e240 100644 --- a/drivers/sftp/meta.go +++ b/drivers/sftp/meta.go @@ -2,7 +2,6 @@ package sftp import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -24,8 +23,6 @@ var config = driver.Config{ NoLinkURL: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &SFTP{} - }) +func New() driver.Driver { + return &SFTP{} } diff --git a/drivers/smb/meta.go b/drivers/smb/meta.go index ce0e5d3b75..8c10b2fd75 100644 --- a/drivers/smb/meta.go +++ b/drivers/smb/meta.go @@ -2,7 +2,6 @@ package smb import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,8 +21,6 @@ var config = driver.Config{ NoLinkURL: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &SMB{} - }) +func New() driver.Driver { + return &SMB{} } diff --git a/drivers/strm/meta.go b/drivers/strm/meta.go index 2e2e8a08e2..28f56ba79d 100644 --- a/drivers/strm/meta.go +++ b/drivers/strm/meta.go @@ -2,7 +2,6 @@ package strm import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) const ( @@ -37,12 +36,10 @@ var config = driver.Config{ NoLinkURL: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Strm{ - Addition: Addition{ - EncodePath: true, - }, - } - }) +func New() driver.Driver { + return &Strm{ + Addition: Addition{ + EncodePath: true, + }, + } } diff --git a/drivers/teambition/meta.go b/drivers/teambition/meta.go index 2c72c9978d..6b06fe3069 100644 --- a/drivers/teambition/meta.go +++ b/drivers/teambition/meta.go @@ -2,7 +2,6 @@ package teambition import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -19,8 +18,6 @@ var config = driver.Config{ Name: "Teambition", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Teambition{} - }) +func New() driver.Driver { + return &Teambition{} } diff --git a/drivers/teldrive/driver.go b/drivers/teldrive/driver.go index 849d9170e2..eefae6967e 100644 --- a/drivers/teldrive/driver.go +++ b/drivers/teldrive/driver.go @@ -261,13 +261,6 @@ func (d *Teldrive) Extract(ctx context.Context, obj model.Obj, args model.Archiv return nil, errs.NotImplement } -func (d *Teldrive) ArchiveDecompress(ctx context.Context, srcObj, dstDir model.Obj, args model.ArchiveDecompressArgs) ([]model.Obj, error) { - // TODO extract args.InnerPath path in the archive srcObj to the dstDir location, optional - // a folder with the same name as the archive file needs to be created to store the extracted results if args.PutIntoNewDir - // return errs.NotImplement to use an internal archive tool - return nil, errs.NotImplement -} - //func (d *Teldrive) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) { // return nil, errs.NotSupport //} diff --git a/drivers/teldrive/meta.go b/drivers/teldrive/meta.go index cc7a5dbf75..a6723d243e 100644 --- a/drivers/teldrive/meta.go +++ b/drivers/teldrive/meta.go @@ -2,7 +2,6 @@ package teldrive import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -20,8 +19,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Teldrive{} - }) +func New() driver.Driver { + return &Teldrive{} } diff --git a/drivers/template/meta.go b/drivers/template/meta.go index f525b5a953..020f99903b 100644 --- a/drivers/template/meta.go +++ b/drivers/template/meta.go @@ -2,7 +2,6 @@ package template import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -27,8 +26,6 @@ var config = driver.Config{ NoLinkURL: false, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Template{} - }) +func New() driver.Driver { + return &Template{} } diff --git a/drivers/terabox/meta.go b/drivers/terabox/meta.go index 4cbb76faf4..d8fe7d5e55 100644 --- a/drivers/terabox/meta.go +++ b/drivers/terabox/meta.go @@ -2,7 +2,6 @@ package terabox import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -19,8 +18,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Terabox{} - }) +func New() driver.Driver { + return &Terabox{} } diff --git a/drivers/thunder/meta.go b/drivers/thunder/meta.go index be9c712fd9..65012124e5 100644 --- a/drivers/thunder/meta.go +++ b/drivers/thunder/meta.go @@ -5,7 +5,7 @@ import ( "encoding/hex" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" + "github.com/OpenListTeam/OpenList/v4/pkg/utils" ) @@ -101,11 +101,9 @@ var configExpert = driver.Config{ LocalSort: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Thunder{} - }) - op.RegisterDriver(func() driver.Driver { - return &ThunderExpert{} - }) +func New() driver.Driver { + return &Thunder{} +} +func New2() driver.Driver { + return &ThunderExpert{} } diff --git a/drivers/thunder_browser/meta.go b/drivers/thunder_browser/meta.go index 6e3eb189c1..5f5ab64a7c 100644 --- a/drivers/thunder_browser/meta.go +++ b/drivers/thunder_browser/meta.go @@ -5,7 +5,7 @@ import ( "encoding/hex" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" + "github.com/OpenListTeam/OpenList/v4/pkg/utils" ) @@ -106,11 +106,9 @@ var configExpert = driver.Config{ LocalSort: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &ThunderBrowser{} - }) - op.RegisterDriver(func() driver.Driver { - return &ThunderBrowserExpert{} - }) +func New() driver.Driver { + return &ThunderBrowser{} +} +func New2() driver.Driver { + return &ThunderBrowserExpert{} } diff --git a/drivers/thunderx/meta.go b/drivers/thunderx/meta.go index 15f75f7366..f0b1ad28c2 100644 --- a/drivers/thunderx/meta.go +++ b/drivers/thunderx/meta.go @@ -5,7 +5,7 @@ import ( "encoding/hex" "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" + "github.com/OpenListTeam/OpenList/v4/pkg/utils" ) @@ -92,11 +92,9 @@ var configExpert = driver.Config{ LocalSort: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &ThunderX{} - }) - op.RegisterDriver(func() driver.Driver { - return &ThunderXExpert{} - }) +func New() driver.Driver { + return &ThunderX{} +} +func New2() driver.Driver { + return &ThunderXExpert{} } diff --git a/drivers/url_tree/meta.go b/drivers/url_tree/meta.go index e2d0e4fe9d..2e7dd7a7f3 100644 --- a/drivers/url_tree/meta.go +++ b/drivers/url_tree/meta.go @@ -2,7 +2,6 @@ package url_tree import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -19,8 +18,6 @@ var config = driver.Config{ OnlyIndices: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Urls{} - }) +func New() driver.Driver { + return &Urls{} } diff --git a/drivers/uss/meta.go b/drivers/uss/meta.go index c00103454b..50f443c50a 100644 --- a/drivers/uss/meta.go +++ b/drivers/uss/meta.go @@ -2,7 +2,6 @@ package uss import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,8 +21,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &USS{} - }) +func New() driver.Driver { + return &USS{} } diff --git a/drivers/virtual/meta.go b/drivers/virtual/meta.go index c270ec12bc..8ca6ce0de9 100644 --- a/drivers/virtual/meta.go +++ b/drivers/virtual/meta.go @@ -2,7 +2,6 @@ package virtual import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -21,8 +20,6 @@ var config = driver.Config{ NoLinkURL: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Virtual{} - }) +func New() driver.Driver { + return &Virtual{} } diff --git a/drivers/webdav/meta.go b/drivers/webdav/meta.go index 6e7c277721..885c573538 100644 --- a/drivers/webdav/meta.go +++ b/drivers/webdav/meta.go @@ -2,7 +2,6 @@ package webdav import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -21,8 +20,6 @@ var config = driver.Config{ PreferProxy: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &WebDav{} - }) +func New() driver.Driver { + return &WebDav{} } diff --git a/drivers/weiyun/driver.go b/drivers/weiyun/driver.go index 5178c95290..21d880e670 100644 --- a/drivers/weiyun/driver.go +++ b/drivers/weiyun/driver.go @@ -285,10 +285,6 @@ func (d *WeiYun) Rename(ctx context.Context, srcObj model.Obj, newName string) ( return nil, errs.NotSupport } -func (d *WeiYun) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { - return errs.NotImplement -} - func (d *WeiYun) Remove(ctx context.Context, obj model.Obj) error { switch obj := obj.(type) { case *File: diff --git a/drivers/weiyun/meta.go b/drivers/weiyun/meta.go index 2f51be6824..42f20cd8cc 100644 --- a/drivers/weiyun/meta.go +++ b/drivers/weiyun/meta.go @@ -2,7 +2,6 @@ package weiyun import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -19,8 +18,6 @@ var config = driver.Config{ CheckStatus: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &WeiYun{} - }) +func New() driver.Driver { + return &WeiYun{} } diff --git a/drivers/wopan/meta.go b/drivers/wopan/meta.go index 55dade1cad..72e9076267 100644 --- a/drivers/wopan/meta.go +++ b/drivers/wopan/meta.go @@ -2,7 +2,6 @@ package template import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -22,8 +21,6 @@ var config = driver.Config{ NoOverwriteUpload: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Wopan{} - }) +func New() driver.Driver { + return &Wopan{} } diff --git a/drivers/wps/meta.go b/drivers/wps/meta.go index 1befb7cd0f..fd411a164d 100644 --- a/drivers/wps/meta.go +++ b/drivers/wps/meta.go @@ -2,7 +2,6 @@ package wps import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -19,8 +18,6 @@ var config = driver.Config{ CheckStatus: true, } -func init() { - op.RegisterDriver(func() driver.Driver { - return &Wps{} - }) +func New() driver.Driver { + return &Wps{} } diff --git a/drivers/yandex_disk/meta.go b/drivers/yandex_disk/meta.go index 8cc8c9f409..88a1c1d12a 100644 --- a/drivers/yandex_disk/meta.go +++ b/drivers/yandex_disk/meta.go @@ -2,7 +2,6 @@ package yandex_disk import ( "github.com/OpenListTeam/OpenList/v4/internal/driver" - "github.com/OpenListTeam/OpenList/v4/internal/op" ) type Addition struct { @@ -21,8 +20,6 @@ var config = driver.Config{ DefaultRoot: "/", } -func init() { - op.RegisterDriver(func() driver.Driver { - return &YandexDisk{} - }) +func New() driver.Driver { + return &YandexDisk{} } diff --git a/internal/driver/driver.go b/internal/driver/driver.go index 373bb56534..7904a62c2e 100644 --- a/internal/driver/driver.go +++ b/internal/driver/driver.go @@ -13,6 +13,8 @@ type Driver interface { // Other } +type Constructor func() Driver + type Meta interface { Config() Config // GetStorage just get raw storage, no need to implement, because model.Storage have implemented diff --git a/internal/op/capability_test.go b/internal/op/capability_test.go new file mode 100644 index 0000000000..4827bcf82e --- /dev/null +++ b/internal/op/capability_test.go @@ -0,0 +1,58 @@ +package op_test + +import ( + "context" + "errors" + "testing" + + "github.com/OpenListTeam/OpenList/v4/internal/driver" + "github.com/OpenListTeam/OpenList/v4/internal/errs" + "github.com/OpenListTeam/OpenList/v4/internal/model" + "github.com/OpenListTeam/OpenList/v4/internal/op" +) + +// A driver with only the required read behavior has no mutation or archive +// capability. The operation boundary must retain the old NotImplement result. +type readOnlyCapabilityDriver struct{ model.Storage } + +func (*readOnlyCapabilityDriver) Config() driver.Config { return driver.Config{NoCache: true} } +func (*readOnlyCapabilityDriver) GetAddition() driver.Additional { return nil } +func (*readOnlyCapabilityDriver) Init(context.Context) error { return nil } +func (*readOnlyCapabilityDriver) Drop(context.Context) error { return nil } +func (*readOnlyCapabilityDriver) List(context.Context, model.Obj, model.ListArgs) ([]model.Obj, error) { + return nil, nil +} +func (*readOnlyCapabilityDriver) Link(context.Context, model.Obj, model.LinkArgs) (*model.Link, error) { + return nil, nil +} +func (*readOnlyCapabilityDriver) Get(_ context.Context, path string) (model.Obj, error) { + switch path { + case "/src": + return &model.Object{Name: "src", Path: path}, nil + case "/dst": + return &model.Object{Name: "dst", Path: path, IsFolder: true}, nil + default: + return nil, errs.ObjectNotFound + } +} + +func TestAbsentDriverCapabilitiesReturnNotImplement(t *testing.T) { + storage := &readOnlyCapabilityDriver{Storage: model.Storage{MountPath: "/capability-test"}} + ctx := context.Background() + tests := []struct { + name string + run func() error + }{ + {"copy", func() error { return op.Copy(ctx, storage, "/src", "/dst") }}, + {"archive decompress", func() error { + return op.ArchiveDecompress(ctx, storage, "/src", "/dst", model.ArchiveDecompressArgs{}) + }}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := tt.run(); !errors.Is(err, errs.NotImplement) { + t.Fatalf("got %v, want NotImplement", err) + } + }) + } +} diff --git a/internal/op/driver.go b/internal/op/driver.go index 5b79b0aed6..ee9bddbf40 100644 --- a/internal/op/driver.go +++ b/internal/op/driver.go @@ -3,6 +3,7 @@ package op import ( "reflect" "strings" + "sync/atomic" "github.com/OpenListTeam/OpenList/v4/internal/conf" @@ -10,21 +11,43 @@ import ( "github.com/pkg/errors" ) -type DriverConstructor func() driver.Driver +type driverCatalog struct { + drivers map[string]driver.Constructor + info map[string]driver.Info +} -var driverMap = map[string]DriverConstructor{} -var driverInfoMap = map[string]driver.Info{} +var installedDrivers atomic.Pointer[driverCatalog] -func RegisterDriver(driver DriverConstructor) { - // log.Infof("register driver: [%s]", config.Name) - tempDriver := driver() - tempConfig := tempDriver.Config() - registerDriverItems(tempConfig, tempDriver.GetAddition()) - driverMap[tempConfig.Name] = driver +func InstallDrivers(constructors []driver.Constructor) error { + catalog := &driverCatalog{ + drivers: make(map[string]driver.Constructor, len(constructors)), + info: make(map[string]driver.Info, len(constructors)), + } + for _, constructor := range constructors { + if constructor == nil { + return errors.New("nil driver constructor") + } + instance := constructor() + if instance == nil || (reflect.ValueOf(instance).Kind() == reflect.Pointer && reflect.ValueOf(instance).IsNil()) { + return errors.New("driver constructor returned nil") + } + config := instance.Config() + if _, exists := catalog.drivers[config.Name]; exists { + return errors.Errorf("duplicate driver named: %s", config.Name) + } + catalog.drivers[config.Name] = constructor + catalog.info[config.Name] = driverInfo(config, instance.GetAddition()) + } + installedDrivers.Store(catalog) + return nil } -func GetDriver(name string) (DriverConstructor, error) { - n, ok := driverMap[name] +func GetDriver(name string) (driver.Constructor, error) { + catalog := installedDrivers.Load() + if catalog == nil { + return nil, errors.New("drivers are not installed") + } + n, ok := catalog.drivers[name] if !ok { return nil, errors.Errorf("no driver named: %s", name) } @@ -32,18 +55,26 @@ func GetDriver(name string) (DriverConstructor, error) { } func GetDriverNames() []string { + catalog := installedDrivers.Load() + if catalog == nil { + return nil + } var driverNames []string - for k := range driverInfoMap { + for k := range catalog.info { driverNames = append(driverNames, k) } return driverNames } func GetDriverInfoMap() map[string]driver.Info { - return driverInfoMap + catalog := installedDrivers.Load() + if catalog == nil { + return nil + } + return catalog.info } -func registerDriverItems(config driver.Config, addition driver.Additional) { +func driverInfo(config driver.Config, addition driver.Additional) driver.Info { // log.Debugf("addition of %s: %+v", config.Name, addition) tAddition := reflect.TypeOf(addition) for tAddition.Kind() == reflect.Pointer { @@ -51,7 +82,7 @@ func registerDriverItems(config driver.Config, addition driver.Additional) { } mainItems := getMainItems(config) additionalItems := getAdditionalItems(tAddition, config.DefaultRoot) - driverInfoMap[config.Name] = driver.Info{ + return driver.Info{ Common: mainItems, Additional: additionalItems, Config: config, diff --git a/internal/op/driver_test.go b/internal/op/driver_test.go index ae328fdde6..6e76c3ba27 100644 --- a/internal/op/driver_test.go +++ b/internal/op/driver_test.go @@ -1,17 +1,61 @@ package op_test import ( + "slices" + "sort" + "strings" "testing" - _ "github.com/OpenListTeam/OpenList/v4/drivers" + "github.com/OpenListTeam/OpenList/v4/drivers" + "github.com/OpenListTeam/OpenList/v4/drivers/local" + "github.com/OpenListTeam/OpenList/v4/internal/driver" "github.com/OpenListTeam/OpenList/v4/internal/op" ) -func TestDriverItemsMap(t *testing.T) { - itemsMap := op.GetDriverInfoMap() - if len(itemsMap) != 0 { - t.Logf("driverInfoMap: %v", itemsMap) - } else { - t.Errorf("expected driverInfoMap not empty, but got empty") +func TestProductDriverCatalogMatchesBaseline(t *testing.T) { + if err := op.InstallDrivers(drivers.All()); err != nil { + t.Fatal(err) + } + const baseline = "115 Cloud|115 Open|115 Share|123 Open|123Pan|123PanLink|123PanShare|139Yun|" + + "189Cloud|189CloudPC|189CloudTV|AList V3|AliDoc|Alias|Aliyundrive|AliyundriveOpen|AliyundriveShare|AutoIndex|" + + "Azure Blob Storage|BaiduNetdisk|BaiduPhoto|Bunny Storage|CNB Releases|ChaoXingGroupDrive|Chunk|Cloudreve|Cloudreve V4|Crypt|Degoo|Doge|" + + "Doubao|DoubaoNew|DoubaoShare|Dropbox|Emby|FTP|FebBox|FeijiPan|GitHub API|GitHub Releases|GoogleDrive|GooglePhoto|GuangYaPan|" + + "HalalCloud|HalalCloudOpen|ILanZou|IPFS API|KodBox|Lanzou|LenovoNasShare|Local|MediaFire|MediaTrack|Mega_nz|Misskey|MoPan|NeteaseMusic|" + + "Onedrive|Onedrive Sharelink|OnedriveAPP|OpenList|OpenListShare|PikPak|PikPakShare|ProtonDrive|Quark|QuarkOpen|QuarkTV|S3|SFTP|SMB|Seafile|Strm|" + + "Teambition|Teldrive|Terabox|Thunder|ThunderBrowser|ThunderBrowserExpert|ThunderExpert|ThunderX|ThunderXExpert|UC|UCTV|USS|UrlTree|Virtual|WPS|WebDav|WeiYun|WoPan|YandexDisk|cloudflare_imgbed" + want := strings.Split(baseline, "|") + got := op.GetDriverNames() + sort.Strings(want) + sort.Strings(got) + if !slices.Equal(got, want) { + t.Fatalf("driver names = %q, want %q", got, want) + } +} + +func TestInstallDriversRejectsInvalidCatalogAtomically(t *testing.T) { + if err := op.InstallDrivers(drivers.All()); err != nil { + t.Fatal(err) + } + want := op.GetDriverNames() + sort.Strings(want) + for _, tt := range []struct { + name string + constructors []driver.Constructor + }{ + {"nil constructor", []driver.Constructor{nil}}, + {"nil instance", []driver.Constructor{func() driver.Driver { return nil }}}, + {"typed nil instance", []driver.Constructor{func() driver.Driver { return (*local.Local)(nil) }}}, + {"duplicate product", []driver.Constructor{local.New, local.New}}, + } { + t.Run(tt.name, func(t *testing.T) { + if err := op.InstallDrivers(tt.constructors); err == nil { + t.Fatal("invalid catalog was accepted") + } + got := op.GetDriverNames() + sort.Strings(got) + if !slices.Equal(got, want) { + t.Fatalf("installed products changed after refusal: got %q", got) + } + }) } } diff --git a/server/handles/offline_download_test.go b/server/handles/offline_download_test.go index 6abecbee46..b1a7b55cc2 100644 --- a/server/handles/offline_download_test.go +++ b/server/handles/offline_download_test.go @@ -9,9 +9,10 @@ import ( "strings" "testing" - _ "github.com/OpenListTeam/OpenList/v4/drivers/local" + "github.com/OpenListTeam/OpenList/v4/drivers/local" "github.com/OpenListTeam/OpenList/v4/internal/conf" "github.com/OpenListTeam/OpenList/v4/internal/db" + "github.com/OpenListTeam/OpenList/v4/internal/driver" "github.com/OpenListTeam/OpenList/v4/internal/model" "github.com/OpenListTeam/OpenList/v4/internal/offline_download/tool" "github.com/OpenListTeam/OpenList/v4/internal/op" @@ -117,6 +118,9 @@ func TestOfflineDownloadSettingsPreserveSuccessPayloads(t *testing.T) { } func TestValidateOfflineDownloadStorageRejectsWrongNativeTool(t *testing.T) { + if err := op.InstallDrivers([]driver.Constructor{local.New}); err != nil { + t.Fatal(err) + } root := t.TempDir() addition, err := json.Marshal(struct { RootFolderPath string `json:"root_folder_path"` diff --git a/server/s3/get_object_close_test.go b/server/s3/get_object_close_test.go index 00ef34208e..29398c13db 100644 --- a/server/s3/get_object_close_test.go +++ b/server/s3/get_object_close_test.go @@ -57,9 +57,11 @@ func (d *closeTrackingDriver) Link(context.Context, model.Obj, model.LinkArgs) ( func TestGetObjectClosesRangeBodyBeforeLink(t *testing.T) { ctx := context.Background() var closed []string - op.RegisterDriver(func() driver.Driver { + if err := op.InstallDrivers([]driver.Constructor{local.New, func() driver.Driver { return &closeTrackingDriver{closed: &closed} - }) + }}); err != nil { + t.Fatal(err) + } root := t.TempDir() if err := os.WriteFile(filepath.Join(root, "fixture.txt"), []byte("body"), 0o600); err != nil { diff --git a/server/s3/multipart_test.go b/server/s3/multipart_test.go index a7349583d1..6a432c7529 100644 --- a/server/s3/multipart_test.go +++ b/server/s3/multipart_test.go @@ -11,9 +11,10 @@ import ( "testing" "time" - _ "github.com/OpenListTeam/OpenList/v4/drivers/local" + "github.com/OpenListTeam/OpenList/v4/drivers/local" "github.com/OpenListTeam/OpenList/v4/internal/conf" "github.com/OpenListTeam/OpenList/v4/internal/db" + "github.com/OpenListTeam/OpenList/v4/internal/driver" "github.com/OpenListTeam/OpenList/v4/internal/model" "github.com/OpenListTeam/OpenList/v4/internal/op" @@ -23,6 +24,9 @@ import ( ) func init() { + if err := op.InstallDrivers([]driver.Constructor{local.New}); err != nil { + panic(err) + } dataDir, err := os.MkdirTemp("", "openlist-s3-mp-*") if err != nil { panic(err)