Spaces:
Runtime error
Runtime error
package onedrive_app | |
import ( | |
"context" | |
"fmt" | |
"net/http" | |
"net/url" | |
"path" | |
"sync" | |
"github.com/alist-org/alist/v3/drivers/base" | |
"github.com/alist-org/alist/v3/internal/driver" | |
"github.com/alist-org/alist/v3/internal/errs" | |
"github.com/alist-org/alist/v3/internal/model" | |
"github.com/alist-org/alist/v3/pkg/utils" | |
"github.com/go-resty/resty/v2" | |
) | |
type OnedriveAPP struct { | |
model.Storage | |
Addition | |
AccessToken string | |
root *Object | |
mutex sync.Mutex | |
} | |
func (d *OnedriveAPP) Config() driver.Config { | |
return config | |
} | |
func (d *OnedriveAPP) GetAddition() driver.Additional { | |
return &d.Addition | |
} | |
func (d *OnedriveAPP) Init(ctx context.Context) error { | |
if d.ChunkSize < 1 { | |
d.ChunkSize = 5 | |
} | |
return d.accessToken() | |
} | |
func (d *OnedriveAPP) Drop(ctx context.Context) error { | |
return nil | |
} | |
func (d *OnedriveAPP) GetRoot(ctx context.Context) (model.Obj, error) { | |
if d.root != nil { | |
return d.root, nil | |
} | |
d.mutex.Lock() | |
defer d.mutex.Unlock() | |
root := &Object{ | |
ObjThumb: model.ObjThumb{ | |
Object: model.Object{ | |
ID: "root", | |
Path: d.RootFolderPath, | |
Name: "root", | |
Size: 0, | |
Modified: d.Modified, | |
Ctime: d.Modified, | |
IsFolder: true, | |
}, | |
}, | |
ParentID: "", | |
} | |
if !utils.PathEqual(d.RootFolderPath, "/") { | |
// get root folder id | |
url := d.GetMetaUrl(false, d.RootFolderPath) | |
var resp struct { | |
Id string `json:"id"` | |
} | |
_, err := d.Request(url, http.MethodGet, nil, &resp) | |
if err != nil { | |
return nil, err | |
} | |
root.ID = resp.Id | |
} | |
d.root = root | |
return d.root, nil | |
} | |
func (d *OnedriveAPP) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { | |
files, err := d.getFiles(dir.GetPath()) | |
if err != nil { | |
return nil, err | |
} | |
return utils.SliceConvert(files, func(src File) (model.Obj, error) { | |
return fileToObj(src, dir.GetID()), nil | |
}) | |
} | |
func (d *OnedriveAPP) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { | |
f, err := d.GetFile(file.GetPath()) | |
if err != nil { | |
return nil, err | |
} | |
if f.File == nil { | |
return nil, errs.NotFile | |
} | |
u := f.Url | |
if d.CustomHost != "" { | |
_u, err := url.Parse(f.Url) | |
if err != nil { | |
return nil, err | |
} | |
_u.Host = d.CustomHost | |
u = _u.String() | |
} | |
return &model.Link{ | |
URL: u, | |
}, nil | |
} | |
func (d *OnedriveAPP) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error { | |
url := d.GetMetaUrl(false, parentDir.GetPath()) + "/children" | |
data := base.Json{ | |
"name": dirName, | |
"folder": base.Json{}, | |
"@microsoft.graph.conflictBehavior": "rename", | |
} | |
_, err := d.Request(url, http.MethodPost, func(req *resty.Request) { | |
req.SetBody(data) | |
}, nil) | |
return err | |
} | |
func (d *OnedriveAPP) Move(ctx context.Context, srcObj, dstDir model.Obj) error { | |
parentPath := "" | |
if dstDir.GetID() == "" { | |
parentPath = dstDir.GetPath() | |
if utils.PathEqual(parentPath, "/") { | |
parentPath = path.Join("/drive/root", parentPath) | |
} else { | |
parentPath = path.Join("/drive/root:/", parentPath) | |
} | |
} | |
data := base.Json{ | |
"parentReference": base.Json{ | |
"id": dstDir.GetID(), | |
"path": parentPath, | |
}, | |
"name": srcObj.GetName(), | |
} | |
url := d.GetMetaUrl(false, srcObj.GetPath()) | |
_, err := d.Request(url, http.MethodPatch, func(req *resty.Request) { | |
req.SetBody(data) | |
}, nil) | |
return err | |
} | |
func (d *OnedriveAPP) Rename(ctx context.Context, srcObj model.Obj, newName string) error { | |
var parentID string | |
if o, ok := srcObj.(*Object); ok { | |
parentID = o.ParentID | |
} else { | |
return fmt.Errorf("srcObj is not Object") | |
} | |
if parentID == "" { | |
parentID = "root" | |
} | |
data := base.Json{ | |
"parentReference": base.Json{ | |
"id": parentID, | |
}, | |
"name": newName, | |
} | |
url := d.GetMetaUrl(false, srcObj.GetPath()) | |
_, err := d.Request(url, http.MethodPatch, func(req *resty.Request) { | |
req.SetBody(data) | |
}, nil) | |
return err | |
} | |
func (d *OnedriveAPP) Copy(ctx context.Context, srcObj, dstDir model.Obj) error { | |
dst, err := d.GetFile(dstDir.GetPath()) | |
if err != nil { | |
return err | |
} | |
data := base.Json{ | |
"parentReference": base.Json{ | |
"driveId": dst.ParentReference.DriveId, | |
"id": dst.Id, | |
}, | |
"name": srcObj.GetName(), | |
} | |
url := d.GetMetaUrl(false, srcObj.GetPath()) + "/copy" | |
_, err = d.Request(url, http.MethodPost, func(req *resty.Request) { | |
req.SetBody(data) | |
}, nil) | |
return err | |
} | |
func (d *OnedriveAPP) Remove(ctx context.Context, obj model.Obj) error { | |
url := d.GetMetaUrl(false, obj.GetPath()) | |
_, err := d.Request(url, http.MethodDelete, nil, nil) | |
return err | |
} | |
func (d *OnedriveAPP) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error { | |
var err error | |
if stream.GetSize() <= 4*1024*1024 { | |
err = d.upSmall(ctx, dstDir, stream) | |
} else { | |
err = d.upBig(ctx, dstDir, stream, up) | |
} | |
return err | |
} | |
var _ driver.Driver = (*OnedriveAPP)(nil) | |