feat(seafile): improve features, support access to encrypted library, etc (#6160)

This commit is contained in:
mlkt
2024-03-08 15:33:42 +08:00
committed by GitHub
parent 2a17d0c2cd
commit ac68079a76
4 changed files with 234 additions and 25 deletions

View File

@ -4,7 +4,6 @@ import (
"context"
"fmt"
"net/http"
"path/filepath"
"strings"
"time"
@ -19,6 +18,7 @@ type Seafile struct {
Addition
authorization string
libraryMap map[string]*LibraryInfo
}
func (d *Seafile) Config() driver.Config {
@ -31,6 +31,8 @@ func (d *Seafile) GetAddition() driver.Additional {
func (d *Seafile) Init(ctx context.Context) error {
d.Address = strings.TrimSuffix(d.Address, "/")
d.RootFolderPath = utils.FixAndCleanPath(d.RootFolderPath)
d.libraryMap = make(map[string]*LibraryInfo)
return d.getToken()
}
@ -38,10 +40,37 @@ func (d *Seafile) Drop(ctx context.Context) error {
return nil
}
func (d *Seafile) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
func (d *Seafile) List(ctx context.Context, dir model.Obj, args model.ListArgs) (result []model.Obj, err error) {
path := dir.GetPath()
if path == d.RootFolderPath {
libraries, err := d.listLibraries()
if err != nil {
return nil, err
}
if path == "/" && d.RepoId == "" {
return utils.SliceConvert(libraries, func(f LibraryItemResp) (model.Obj, error) {
return &model.Object{
Name: f.Name,
Modified: time.Unix(f.Modified, 0),
Size: f.Size,
IsFolder: true,
}, nil
})
}
}
var repo *LibraryInfo
repo, path, err = d.getRepoAndPath(path)
if err != nil {
return nil, err
}
if repo.Encrypted {
err = d.decryptLibrary(repo)
if err != nil {
return nil, err
}
}
var resp []RepoDirItemResp
_, err := d.request(http.MethodGet, fmt.Sprintf("/api2/repos/%s/dir/", d.Addition.RepoId), func(req *resty.Request) {
_, err = d.request(http.MethodGet, fmt.Sprintf("/api2/repos/%s/dir/", repo.Id), func(req *resty.Request) {
req.SetResult(&resp).SetQueryParams(map[string]string{
"p": path,
})
@ -63,9 +92,13 @@ func (d *Seafile) List(ctx context.Context, dir model.Obj, args model.ListArgs)
}
func (d *Seafile) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
res, err := d.request(http.MethodGet, fmt.Sprintf("/api2/repos/%s/file/", d.Addition.RepoId), func(req *resty.Request) {
repo, path, err := d.getRepoAndPath(file.GetPath())
if err != nil {
return nil, err
}
res, err := d.request(http.MethodGet, fmt.Sprintf("/api2/repos/%s/file/", repo.Id), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": file.GetPath(),
"p": path,
"reuse": "1",
})
})
@ -78,9 +111,14 @@ func (d *Seafile) Link(ctx context.Context, file model.Obj, args model.LinkArgs)
}
func (d *Seafile) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
_, err := d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/dir/", d.Addition.RepoId), func(req *resty.Request) {
repo, path, err := d.getRepoAndPath(parentDir.GetPath())
if err != nil {
return err
}
path, _ = utils.JoinBasePath(path, dirName)
_, err = d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/dir/", repo.Id), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": filepath.Join(parentDir.GetPath(), dirName),
"p": path,
}).SetFormData(map[string]string{
"operation": "mkdir",
})
@ -89,22 +127,34 @@ func (d *Seafile) MakeDir(ctx context.Context, parentDir model.Obj, dirName stri
}
func (d *Seafile) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
_, err := d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/file/", d.Addition.RepoId), func(req *resty.Request) {
repo, path, err := d.getRepoAndPath(srcObj.GetPath())
if err != nil {
return err
}
dstRepo, dstPath, err := d.getRepoAndPath(dstDir.GetPath())
if err != nil {
return err
}
_, err = d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/file/", repo.Id), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": srcObj.GetPath(),
"p": path,
}).SetFormData(map[string]string{
"operation": "move",
"dst_repo": d.Addition.RepoId,
"dst_dir": dstDir.GetPath(),
"dst_repo": dstRepo.Id,
"dst_dir": dstPath,
})
}, true)
return err
}
func (d *Seafile) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
_, err := d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/file/", d.Addition.RepoId), func(req *resty.Request) {
repo, path, err := d.getRepoAndPath(srcObj.GetPath())
if err != nil {
return err
}
_, err = d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/file/", repo.Id), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": srcObj.GetPath(),
"p": path,
}).SetFormData(map[string]string{
"operation": "rename",
"newname": newName,
@ -114,31 +164,47 @@ func (d *Seafile) Rename(ctx context.Context, srcObj model.Obj, newName string)
}
func (d *Seafile) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
_, err := d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/file/", d.Addition.RepoId), func(req *resty.Request) {
repo, path, err := d.getRepoAndPath(srcObj.GetPath())
if err != nil {
return err
}
dstRepo, dstPath, err := d.getRepoAndPath(dstDir.GetPath())
if err != nil {
return err
}
_, err = d.request(http.MethodPost, fmt.Sprintf("/api2/repos/%s/file/", repo.Id), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": srcObj.GetPath(),
"p": path,
}).SetFormData(map[string]string{
"operation": "copy",
"dst_repo": d.Addition.RepoId,
"dst_dir": dstDir.GetPath(),
"dst_repo": dstRepo.Id,
"dst_dir": dstPath,
})
})
return err
}
func (d *Seafile) Remove(ctx context.Context, obj model.Obj) error {
_, err := d.request(http.MethodDelete, fmt.Sprintf("/api2/repos/%s/file/", d.Addition.RepoId), func(req *resty.Request) {
repo, path, err := d.getRepoAndPath(obj.GetPath())
if err != nil {
return err
}
_, err = d.request(http.MethodDelete, fmt.Sprintf("/api2/repos/%s/file/", repo.Id), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": obj.GetPath(),
"p": path,
})
})
return err
}
func (d *Seafile) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
res, err := d.request(http.MethodGet, fmt.Sprintf("/api2/repos/%s/upload-link/", d.Addition.RepoId), func(req *resty.Request) {
repo, path, err := d.getRepoAndPath(dstDir.GetPath())
if err != nil {
return err
}
res, err := d.request(http.MethodGet, fmt.Sprintf("/api2/repos/%s/upload-link/", repo.Id), func(req *resty.Request) {
req.SetQueryParams(map[string]string{
"p": dstDir.GetPath(),
"p": path,
})
})
if err != nil {
@ -150,7 +216,7 @@ func (d *Seafile) Put(ctx context.Context, dstDir model.Obj, stream model.FileSt
_, err = d.request(http.MethodPost, u, func(req *resty.Request) {
req.SetFileReader("file", stream.GetName(), stream).
SetFormData(map[string]string{
"parent_dir": dstDir.GetPath(),
"parent_dir": path,
"replace": "1",
})
})