mirror of
https://github.com/AlistGo/alist.git
synced 2025-12-19 11:00:06 +08:00
feat(driver): Implement GetLink, CreateDir, and Move operations
- Implement `GetLink` method to retrieve download links for files. - Implement `CreateDir` method to create new directories. - Implement `Move` method to relocate files and directories. - Add new API endpoints and data structures for download and directory creation responses. - Integrate retry logic with re-authentication for API calls in implemented methods. - Update HTTP request headers to include `x-requested-with`.
This commit is contained in:
parent
6ba97213d8
commit
b0a9dd7ce9
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http/cookiejar"
|
"net/http/cookiejar"
|
||||||
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/drivers/base"
|
"github.com/alist-org/alist/v3/drivers/base"
|
||||||
@ -22,6 +23,9 @@ const (
|
|||||||
loginURL = baseURL + "/loginServer/login"
|
loginURL = baseURL + "/loginServer/login"
|
||||||
listURL = baseURL + "/apiToken/cfi/fs/resources/pages"
|
listURL = baseURL + "/apiToken/cfi/fs/resources/pages"
|
||||||
uploadInitializeURL = baseURL + "/apiToken/cfi/fs/upload/v2/initialize"
|
uploadInitializeURL = baseURL + "/apiToken/cfi/fs/upload/v2/initialize"
|
||||||
|
downloadURL = baseURL + "/download/getUrl"
|
||||||
|
createDirURL = baseURL + "/resource/create"
|
||||||
|
moveResourceURL = baseURL + "/resource/remove"
|
||||||
|
|
||||||
successCode = "10200"
|
successCode = "10200"
|
||||||
uploadSuccessCode = "30010"
|
uploadSuccessCode = "30010"
|
||||||
@ -131,15 +135,145 @@ func (d *BitQiu) List(ctx context.Context, dir model.Obj, args model.ListArgs) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *BitQiu) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
func (d *BitQiu) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
||||||
return nil, errs.NotImplement
|
if file.IsDir() {
|
||||||
|
return nil, errs.NotFile
|
||||||
|
}
|
||||||
|
if d.userID == "" {
|
||||||
|
if err := d.login(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form := map[string]string{
|
||||||
|
"fileIds": file.GetID(),
|
||||||
|
"org_channel": orgChannel,
|
||||||
|
}
|
||||||
|
for attempt := 0; attempt < 2; attempt++ {
|
||||||
|
var resp Response[DownloadData]
|
||||||
|
if err := d.postForm(ctx, downloadURL, form, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch resp.Code {
|
||||||
|
case successCode:
|
||||||
|
if resp.Data.URL == "" {
|
||||||
|
return nil, fmt.Errorf("empty download url returned")
|
||||||
|
}
|
||||||
|
return &model.Link{URL: resp.Data.URL}, nil
|
||||||
|
case "10401", "10404":
|
||||||
|
if err := d.login(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("get link failed: %s", resp.Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("get link failed: retry limit reached")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BitQiu) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {
|
func (d *BitQiu) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) {
|
||||||
return nil, errs.NotImplement
|
if d.userID == "" {
|
||||||
|
if err := d.login(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parentID := d.resolveParentID(parentDir)
|
||||||
|
parentPath := ""
|
||||||
|
if parentDir != nil {
|
||||||
|
parentPath = parentDir.GetPath()
|
||||||
|
}
|
||||||
|
form := map[string]string{
|
||||||
|
"parentId": parentID,
|
||||||
|
"name": dirName,
|
||||||
|
"org_channel": orgChannel,
|
||||||
|
}
|
||||||
|
for attempt := 0; attempt < 2; attempt++ {
|
||||||
|
var resp Response[CreateDirData]
|
||||||
|
if err := d.postForm(ctx, createDirURL, form, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch resp.Code {
|
||||||
|
case successCode:
|
||||||
|
newParentID := parentID
|
||||||
|
if resp.Data.ParentID != "" {
|
||||||
|
newParentID = resp.Data.ParentID
|
||||||
|
}
|
||||||
|
name := resp.Data.Name
|
||||||
|
if name == "" {
|
||||||
|
name = dirName
|
||||||
|
}
|
||||||
|
resource := Resource{
|
||||||
|
ResourceID: resp.Data.DirID,
|
||||||
|
ResourceType: 1,
|
||||||
|
Name: name,
|
||||||
|
ParentID: newParentID,
|
||||||
|
}
|
||||||
|
obj, err := resource.toObject(newParentID, parentPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if o, ok := obj.(*Object); ok {
|
||||||
|
o.ParentID = newParentID
|
||||||
|
}
|
||||||
|
return obj, nil
|
||||||
|
case "10401", "10404":
|
||||||
|
if err := d.login(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("create folder failed: %s", resp.Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("create folder failed: retry limit reached")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BitQiu) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
|
func (d *BitQiu) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) {
|
||||||
return nil, errs.NotImplement
|
if d.userID == "" {
|
||||||
|
if err := d.login(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
targetParentID := d.resolveParentID(dstDir)
|
||||||
|
form := map[string]string{
|
||||||
|
"dirIds": "",
|
||||||
|
"fileIds": "",
|
||||||
|
"parentId": targetParentID,
|
||||||
|
"org_channel": orgChannel,
|
||||||
|
}
|
||||||
|
if srcObj.IsDir() {
|
||||||
|
form["dirIds"] = srcObj.GetID()
|
||||||
|
} else {
|
||||||
|
form["fileIds"] = srcObj.GetID()
|
||||||
|
}
|
||||||
|
|
||||||
|
for attempt := 0; attempt < 2; attempt++ {
|
||||||
|
var resp Response[any]
|
||||||
|
if err := d.postForm(ctx, moveResourceURL, form, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
switch resp.Code {
|
||||||
|
case successCode:
|
||||||
|
dstPath := ""
|
||||||
|
if dstDir != nil {
|
||||||
|
dstPath = dstDir.GetPath()
|
||||||
|
}
|
||||||
|
if setter, ok := srcObj.(model.SetPath); ok {
|
||||||
|
setter.SetPath(path.Join(dstPath, srcObj.GetName()))
|
||||||
|
}
|
||||||
|
if o, ok := srcObj.(*Object); ok {
|
||||||
|
o.ParentID = targetParentID
|
||||||
|
}
|
||||||
|
return srcObj, nil
|
||||||
|
case "10401", "10404":
|
||||||
|
if err := d.login(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("move failed: %s", resp.Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("move failed: retry limit reached")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *BitQiu) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) {
|
func (d *BitQiu) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) {
|
||||||
@ -241,6 +375,7 @@ func (d *BitQiu) commonHeaders() map[string]string {
|
|||||||
"pragma": "no-cache",
|
"pragma": "no-cache",
|
||||||
"user-platform": d.Addition.UserPlatform,
|
"user-platform": d.Addition.UserPlatform,
|
||||||
"x-kl-saas-ajax-request": "Ajax_Request",
|
"x-kl-saas-ajax-request": "Ajax_Request",
|
||||||
|
"x-requested-with": "XMLHttpRequest",
|
||||||
"referer": baseURL + "/",
|
"referer": baseURL + "/",
|
||||||
"origin": baseURL,
|
"origin": baseURL,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,3 +33,15 @@ type Resource struct {
|
|||||||
UpdateTime *string `json:"updateTime"`
|
UpdateTime *string `json:"updateTime"`
|
||||||
FileMD5 string `json:"fileMd5"`
|
FileMD5 string `json:"fileMd5"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DownloadData struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
MD5 string `json:"md5"`
|
||||||
|
Size int64 `json:"size"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateDirData struct {
|
||||||
|
DirID string `json:"dirId"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
ParentID string `json:"parentId"`
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user