-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add support for Onedrive Sharelink driver (#6793)
* feat: add support for Onedrive Sharelink driver * fix(Onedrive Sharelink): use internal UA
- Loading branch information
1 parent
049575b
commit cee0000
Showing
5 changed files
with
604 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
package onedrive_sharelink | ||
|
||
import ( | ||
"context" | ||
"strings" | ||
"time" | ||
|
||
"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/cron" | ||
"github.com/alist-org/alist/v3/pkg/utils" | ||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
type OnedriveSharelink struct { | ||
model.Storage | ||
cron *cron.Cron | ||
Addition | ||
} | ||
|
||
func (d *OnedriveSharelink) Config() driver.Config { | ||
return config | ||
} | ||
|
||
func (d *OnedriveSharelink) GetAddition() driver.Additional { | ||
return &d.Addition | ||
} | ||
|
||
func (d *OnedriveSharelink) Init(ctx context.Context) error { | ||
// Initialize error variable | ||
var err error | ||
|
||
// If there is "-my" in the URL, it is NOT a SharePoint link | ||
d.IsSharepoint = !strings.Contains(d.ShareLinkURL, "-my") | ||
|
||
// Initialize cron job to run every hour | ||
d.cron = cron.NewCron(time.Hour * 1) | ||
d.cron.Do(func() { | ||
var err error | ||
d.Headers, err = d.getHeaders() | ||
if err != nil { | ||
log.Errorf("%+v", err) | ||
} | ||
}) | ||
|
||
// Get initial headers | ||
d.Headers, err = d.getHeaders() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (d *OnedriveSharelink) Drop(ctx context.Context) error { | ||
return nil | ||
} | ||
|
||
func (d *OnedriveSharelink) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { | ||
path := dir.GetPath() | ||
files, err := d.getFiles(path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Convert the slice of files to the required model.Obj format | ||
return utils.SliceConvert(files, func(src Item) (model.Obj, error) { | ||
return fileToObj(src), nil | ||
}) | ||
} | ||
|
||
func (d *OnedriveSharelink) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { | ||
// Get the unique ID of the file | ||
uniqueId := file.GetID() | ||
// Cut the first char and the last char | ||
uniqueId = uniqueId[1 : len(uniqueId)-1] | ||
url := d.downloadLinkPrefix + uniqueId | ||
header := d.Headers | ||
|
||
// If the headers are older than 30 minutes, get new headers | ||
if d.HeaderTime < time.Now().Unix()-1800 { | ||
var err error | ||
log.Debug("headers are older than 30 minutes, get new headers") | ||
header, err = d.getHeaders() | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
|
||
return &model.Link{ | ||
URL: url, | ||
Header: header, | ||
}, nil | ||
} | ||
|
||
func (d *OnedriveSharelink) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error { | ||
// TODO create folder, optional | ||
return errs.NotImplement | ||
} | ||
|
||
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 { | ||
// TODO upload file, optional | ||
return errs.NotImplement | ||
} | ||
|
||
//func (d *OnedriveSharelink) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) { | ||
// return nil, errs.NotSupport | ||
//} | ||
|
||
var _ driver.Driver = (*OnedriveSharelink)(nil) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package onedrive_sharelink | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/alist-org/alist/v3/internal/driver" | ||
"github.com/alist-org/alist/v3/internal/op" | ||
) | ||
|
||
type Addition struct { | ||
driver.RootPath | ||
ShareLinkURL string `json:"url" required:"true"` | ||
ShareLinkPassword string `json:"password"` | ||
IsSharepoint bool | ||
downloadLinkPrefix string | ||
Headers http.Header | ||
HeaderTime int64 | ||
} | ||
|
||
var config = driver.Config{ | ||
Name: "Onedrive Sharelink", | ||
OnlyProxy: true, | ||
NoUpload: true, | ||
DefaultRoot: "/", | ||
CheckStatus: false, | ||
} | ||
|
||
func init() { | ||
op.RegisterDriver(func() driver.Driver { | ||
return &OnedriveSharelink{} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package onedrive_sharelink | ||
|
||
import ( | ||
"strconv" | ||
"time" | ||
|
||
"github.com/alist-org/alist/v3/internal/model" | ||
) | ||
|
||
// FolderResp represents the structure of the folder response from the OneDrive API. | ||
type FolderResp struct { | ||
// Data holds the nested structure of the response. | ||
Data struct { | ||
Legacy struct { | ||
RenderListData struct { | ||
ListData struct { | ||
Items []Item `json:"Row"` // Items contains the list of items in the folder. | ||
} `json:"ListData"` | ||
} `json:"renderListDataAsStream"` | ||
} `json:"legacy"` | ||
} `json:"data"` | ||
} | ||
|
||
// Item represents an individual item in the folder. | ||
type Item struct { | ||
ObjType string `json:"FSObjType"` // ObjType indicates if the item is a file or folder. | ||
Name string `json:"FileLeafRef"` // Name is the name of the item. | ||
ModifiedTime time.Time `json:"Modified."` // ModifiedTime is the last modified time of the item. | ||
Size string `json:"File_x0020_Size"` // Size is the size of the item in string format. | ||
Id string `json:"UniqueId"` // Id is the unique identifier of the item. | ||
} | ||
|
||
// fileToObj converts an Item to an ObjThumb. | ||
func fileToObj(f Item) *model.ObjThumb { | ||
// Convert Size from string to int64. | ||
size, _ := strconv.ParseInt(f.Size, 10, 64) | ||
// Convert ObjType from string to int. | ||
objtype, _ := strconv.Atoi(f.ObjType) | ||
|
||
// Create a new ObjThumb with the converted values. | ||
file := &model.ObjThumb{ | ||
Object: model.Object{ | ||
Name: f.Name, | ||
Modified: f.ModifiedTime, | ||
Size: size, | ||
IsFolder: objtype == 1, // Check if the item is a folder. | ||
ID: f.Id, | ||
}, | ||
Thumbnail: model.Thumbnail{}, | ||
} | ||
return file | ||
} | ||
|
||
// GraphQLNEWRequest represents the structure of a new GraphQL request. | ||
type GraphQLNEWRequest struct { | ||
ListData struct { | ||
NextHref string `json:"NextHref"` // NextHref is the link to the next set of data. | ||
Row []Item `json:"Row"` // Row contains the list of items. | ||
} `json:"ListData"` | ||
} | ||
|
||
// GraphQLRequest represents the structure of a GraphQL request. | ||
type GraphQLRequest struct { | ||
Data struct { | ||
Legacy struct { | ||
RenderListDataAsStream struct { | ||
ListData struct { | ||
NextHref string `json:"NextHref"` // NextHref is the link to the next set of data. | ||
Row []Item `json:"Row"` // Row contains the list of items. | ||
} `json:"ListData"` | ||
ViewMetadata struct { | ||
ListViewXml string `json:"ListViewXml"` // ListViewXml contains the XML of the list view. | ||
} `json:"ViewMetadata"` | ||
} `json:"renderListDataAsStream"` | ||
} `json:"legacy"` | ||
} `json:"data"` | ||
} |
Oops, something went wrong.