mirror of https://github.com/Xhofe/alist
fix(onedrive): fix Ctime/Mtime (#6397)
parent
0e246a7b0c
commit
eecea3febd
|
@ -118,6 +118,7 @@ func (d *Onedrive) MakeDir(ctx context.Context, parentDir model.Obj, dirName str
|
||||||
"folder": base.Json{},
|
"folder": base.Json{},
|
||||||
"@microsoft.graph.conflictBehavior": "rename",
|
"@microsoft.graph.conflictBehavior": "rename",
|
||||||
}
|
}
|
||||||
|
// todo 修复文件夹 ctime/mtime, onedrive 可在 data 里设置 fileSystemInfo 字段, 但是此接口未提供 ctime/mtime
|
||||||
_, err := d.Request(url, http.MethodPost, func(req *resty.Request) {
|
_, err := d.Request(url, http.MethodPost, func(req *resty.Request) {
|
||||||
req.SetBody(data)
|
req.SetBody(data)
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|
|
@ -27,7 +27,7 @@ type File struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Size int64 `json:"size"`
|
Size int64 `json:"size"`
|
||||||
LastModifiedDateTime time.Time `json:"lastModifiedDateTime"`
|
FileSystemInfo *FileSystemInfoFacet `json:"fileSystemInfo"`
|
||||||
Url string `json:"@microsoft.graph.downloadUrl"`
|
Url string `json:"@microsoft.graph.downloadUrl"`
|
||||||
File *struct {
|
File *struct {
|
||||||
MimeType string `json:"mimeType"`
|
MimeType string `json:"mimeType"`
|
||||||
|
@ -58,7 +58,7 @@ func fileToObj(f File, parentID string) *Object {
|
||||||
ID: f.Id,
|
ID: f.Id,
|
||||||
Name: f.Name,
|
Name: f.Name,
|
||||||
Size: f.Size,
|
Size: f.Size,
|
||||||
Modified: f.LastModifiedDateTime,
|
Modified: f.FileSystemInfo.LastModifiedDateTime,
|
||||||
IsFolder: f.File == nil,
|
IsFolder: f.File == nil,
|
||||||
},
|
},
|
||||||
Thumbnail: model.Thumbnail{Thumbnail: thumb},
|
Thumbnail: model.Thumbnail{Thumbnail: thumb},
|
||||||
|
@ -72,3 +72,20 @@ type Files struct {
|
||||||
Value []File `json:"value"`
|
Value []File `json:"value"`
|
||||||
NextLink string `json:"@odata.nextLink"`
|
NextLink string `json:"@odata.nextLink"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Metadata represents a request to update Metadata.
|
||||||
|
// It includes only the writeable properties.
|
||||||
|
// omitempty is intentionally included for all, per https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_update?view=odsp-graph-online#request-body
|
||||||
|
type Metadata struct {
|
||||||
|
Description string `json:"description,omitempty"` // Provides a user-visible description of the item. Read-write. Only on OneDrive Personal. Undocumented limit of 1024 characters.
|
||||||
|
FileSystemInfo *FileSystemInfoFacet `json:"fileSystemInfo,omitempty"` // File system information on client. Read-write.
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileSystemInfoFacet contains properties that are reported by the
|
||||||
|
// device's local file system for the local version of an item. This
|
||||||
|
// facet can be used to specify the last modified date or created date
|
||||||
|
// of the item as it was on the local device.
|
||||||
|
type FileSystemInfoFacet struct {
|
||||||
|
CreatedDateTime time.Time `json:"createdDateTime,omitempty"` // The UTC date and time the file was created on a client.
|
||||||
|
LastModifiedDateTime time.Time `json:"lastModifiedDateTime,omitempty"` // The UTC date and time the file was last modified on a client.
|
||||||
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ func (d *Onedrive) Request(url string, method string, callback base.ReqCallback,
|
||||||
|
|
||||||
func (d *Onedrive) getFiles(path string) ([]File, error) {
|
func (d *Onedrive) getFiles(path string) ([]File, error) {
|
||||||
var res []File
|
var res []File
|
||||||
nextLink := d.GetMetaUrl(false, path) + "/children?$top=5000&$expand=thumbnails($select=medium)&$select=id,name,size,lastModifiedDateTime,content.downloadUrl,file,parentReference"
|
nextLink := d.GetMetaUrl(false, path) + "/children?$top=5000&$expand=thumbnails($select=medium)&$select=id,name,size,fileSystemInfo,content.downloadUrl,file,parentReference"
|
||||||
for nextLink != "" {
|
for nextLink != "" {
|
||||||
var files Files
|
var files Files
|
||||||
_, err := d.Request(nextLink, http.MethodGet, nil, &files)
|
_, err := d.Request(nextLink, http.MethodGet, nil, &files)
|
||||||
|
@ -148,7 +148,10 @@ func (d *Onedrive) GetFile(path string) (*File, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Onedrive) upSmall(ctx context.Context, dstDir model.Obj, stream model.FileStreamer) error {
|
func (d *Onedrive) upSmall(ctx context.Context, dstDir model.Obj, stream model.FileStreamer) error {
|
||||||
url := d.GetMetaUrl(false, stdpath.Join(dstDir.GetPath(), stream.GetName())) + "/content"
|
filepath := stdpath.Join(dstDir.GetPath(), stream.GetName())
|
||||||
|
// 1. upload new file
|
||||||
|
// ApiDoc: https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content?view=odsp-graph-online
|
||||||
|
url := d.GetMetaUrl(false, filepath) + "/content"
|
||||||
data, err := io.ReadAll(stream)
|
data, err := io.ReadAll(stream)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -156,12 +159,50 @@ func (d *Onedrive) upSmall(ctx context.Context, dstDir model.Obj, stream model.F
|
||||||
_, err = d.Request(url, http.MethodPut, func(req *resty.Request) {
|
_, err = d.Request(url, http.MethodPut, func(req *resty.Request) {
|
||||||
req.SetBody(data).SetContext(ctx)
|
req.SetBody(data).SetContext(ctx)
|
||||||
}, nil)
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("onedrive: Failed to upload new file(path=%v): %w", filepath, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. update metadata
|
||||||
|
err = d.updateMetadata(ctx, stream, filepath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("onedrive: Failed to update file(path=%v) metadata: %w", filepath, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) updateMetadata(ctx context.Context, stream model.FileStreamer, filepath string) error {
|
||||||
|
url := d.GetMetaUrl(false, filepath)
|
||||||
|
metadata := toAPIMetadata(stream)
|
||||||
|
// ApiDoc: https://learn.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_update?view=odsp-graph-online
|
||||||
|
_, err := d.Request(url, http.MethodPatch, func(req *resty.Request) {
|
||||||
|
req.SetBody(metadata).SetContext(ctx)
|
||||||
|
}, nil)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toAPIMetadata(stream model.FileStreamer) Metadata {
|
||||||
|
metadata := Metadata{
|
||||||
|
FileSystemInfo: &FileSystemInfoFacet{},
|
||||||
|
}
|
||||||
|
if !stream.ModTime().IsZero() {
|
||||||
|
metadata.FileSystemInfo.LastModifiedDateTime = stream.ModTime()
|
||||||
|
}
|
||||||
|
if !stream.CreateTime().IsZero() {
|
||||||
|
metadata.FileSystemInfo.CreatedDateTime = stream.CreateTime()
|
||||||
|
}
|
||||||
|
if stream.CreateTime().IsZero() && !stream.ModTime().IsZero() {
|
||||||
|
metadata.FileSystemInfo.CreatedDateTime = stream.CreateTime()
|
||||||
|
}
|
||||||
|
return metadata
|
||||||
|
}
|
||||||
|
|
||||||
func (d *Onedrive) upBig(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
func (d *Onedrive) upBig(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||||
url := d.GetMetaUrl(false, stdpath.Join(dstDir.GetPath(), stream.GetName())) + "/createUploadSession"
|
url := d.GetMetaUrl(false, stdpath.Join(dstDir.GetPath(), stream.GetName())) + "/createUploadSession"
|
||||||
res, err := d.Request(url, http.MethodPost, nil, nil)
|
metadata := map[string]interface{}{"item": toAPIMetadata(stream)}
|
||||||
|
res, err := d.Request(url, http.MethodPost, func(req *resty.Request) {
|
||||||
|
req.SetBody(metadata).SetContext(ctx)
|
||||||
|
}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue