mirror of
https://github.com/gilbertchen/duplicacy
synced 2025-12-06 00:03:38 +00:00
Merge pull request #633 from sevimo123/sharepoint_support
Sharepoint support
This commit is contained in:
@@ -51,7 +51,7 @@ type OneDriveClient struct {
|
|||||||
APIURL string
|
APIURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOneDriveClient(tokenFile string, isBusiness bool, client_id string, client_secret string) (*OneDriveClient, error) {
|
func NewOneDriveClient(tokenFile string, isBusiness bool, client_id string, client_secret string, drive_id string) (*OneDriveClient, error) {
|
||||||
|
|
||||||
description, err := ioutil.ReadFile(tokenFile)
|
description, err := ioutil.ReadFile(tokenFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -88,10 +88,13 @@ func NewOneDriveClient(tokenFile string, isBusiness bool, client_id string, clie
|
|||||||
|
|
||||||
if isBusiness {
|
if isBusiness {
|
||||||
client.RefreshTokenURL = "https://duplicacy.com/odb_refresh"
|
client.RefreshTokenURL = "https://duplicacy.com/odb_refresh"
|
||||||
client.APIURL = "https://graph.microsoft.com/v1.0/me"
|
client.APIURL = "https://graph.microsoft.com/v1.0/me/drive"
|
||||||
|
if drive_id != "" {
|
||||||
|
client.APIURL = "https://graph.microsoft.com/v1.0/drives/"+drive_id
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
client.RefreshTokenURL = "https://duplicacy.com/one_refresh"
|
client.RefreshTokenURL = "https://duplicacy.com/one_refresh"
|
||||||
client.APIURL = "https://api.onedrive.com/v1.0"
|
client.APIURL = "https://api.onedrive.com/v1.0/drive"
|
||||||
}
|
}
|
||||||
|
|
||||||
client.RefreshToken(false)
|
client.RefreshToken(false)
|
||||||
@@ -285,9 +288,9 @@ func (client *OneDriveClient) ListEntries(path string) ([]OneDriveEntry, error)
|
|||||||
|
|
||||||
entries := []OneDriveEntry{}
|
entries := []OneDriveEntry{}
|
||||||
|
|
||||||
url := client.APIURL + "/drive/root:/" + path + ":/children"
|
url := client.APIURL + "/root:/" + path + ":/children"
|
||||||
if path == "" {
|
if path == "" {
|
||||||
url = client.APIURL + "/drive/root/children"
|
url = client.APIURL + "/root/children"
|
||||||
}
|
}
|
||||||
if client.TestMode {
|
if client.TestMode {
|
||||||
url += "?top=8"
|
url += "?top=8"
|
||||||
@@ -323,7 +326,8 @@ func (client *OneDriveClient) ListEntries(path string) ([]OneDriveEntry, error)
|
|||||||
|
|
||||||
func (client *OneDriveClient) GetFileInfo(path string) (string, bool, int64, error) {
|
func (client *OneDriveClient) GetFileInfo(path string) (string, bool, int64, error) {
|
||||||
|
|
||||||
url := client.APIURL + "/drive/root:/" + path
|
url := client.APIURL + "/root:/" + path
|
||||||
|
if path == "" { url = client.APIURL + "/root" }
|
||||||
url += "?select=id,name,size,folder"
|
url += "?select=id,name,size,folder"
|
||||||
|
|
||||||
readCloser, _, err := client.call(url, "GET", 0, "")
|
readCloser, _, err := client.call(url, "GET", 0, "")
|
||||||
@@ -348,7 +352,7 @@ func (client *OneDriveClient) GetFileInfo(path string) (string, bool, int64, err
|
|||||||
|
|
||||||
func (client *OneDriveClient) DownloadFile(path string) (io.ReadCloser, int64, error) {
|
func (client *OneDriveClient) DownloadFile(path string) (io.ReadCloser, int64, error) {
|
||||||
|
|
||||||
url := client.APIURL + "/drive/items/root:/" + path + ":/content"
|
url := client.APIURL + "/items/root:/" + path + ":/content"
|
||||||
|
|
||||||
return client.call(url, "GET", 0, "")
|
return client.call(url, "GET", 0, "")
|
||||||
}
|
}
|
||||||
@@ -358,7 +362,7 @@ func (client *OneDriveClient) UploadFile(path string, content []byte, rateLimit
|
|||||||
// Upload file using the simple method; this is only possible for OneDrive Personal or if the file
|
// Upload file using the simple method; this is only possible for OneDrive Personal or if the file
|
||||||
// is smaller than 4MB for OneDrive Business
|
// is smaller than 4MB for OneDrive Business
|
||||||
if !client.IsBusiness || (client.TestMode && rand.Int() % 2 == 0) {
|
if !client.IsBusiness || (client.TestMode && rand.Int() % 2 == 0) {
|
||||||
url := client.APIURL + "/drive/root:/" + path + ":/content"
|
url := client.APIURL + "/root:/" + path + ":/content"
|
||||||
|
|
||||||
readCloser, _, err := client.call(url, "PUT", CreateRateLimitedReader(content, rateLimit), "application/octet-stream")
|
readCloser, _, err := client.call(url, "PUT", CreateRateLimitedReader(content, rateLimit), "application/octet-stream")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -392,7 +396,7 @@ func (client *OneDriveClient) CreateUploadSession(path string) (uploadURL string
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
readCloser, _, err := client.call(client.APIURL + "/drive/root:/" + path + ":/createUploadSession", "POST", input, "application/json")
|
readCloser, _, err := client.call(client.APIURL + "/root:/" + path + ":/createUploadSession", "POST", input, "application/json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -436,7 +440,7 @@ func (client *OneDriveClient) UploadFileSession(uploadURL string, content []byte
|
|||||||
|
|
||||||
func (client *OneDriveClient) DeleteFile(path string) error {
|
func (client *OneDriveClient) DeleteFile(path string) error {
|
||||||
|
|
||||||
url := client.APIURL + "/drive/root:/" + path
|
url := client.APIURL + "/root:/" + path
|
||||||
|
|
||||||
readCloser, _, err := client.call(url, "DELETE", 0, "")
|
readCloser, _, err := client.call(url, "DELETE", 0, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -449,10 +453,10 @@ func (client *OneDriveClient) DeleteFile(path string) error {
|
|||||||
|
|
||||||
func (client *OneDriveClient) MoveFile(path string, parent string) error {
|
func (client *OneDriveClient) MoveFile(path string, parent string) error {
|
||||||
|
|
||||||
url := client.APIURL + "/drive/root:/" + path
|
url := client.APIURL + "/root:/" + path
|
||||||
|
|
||||||
parentReference := make(map[string]string)
|
parentReference := make(map[string]string)
|
||||||
parentReference["path"] = "/drive/root:/" + parent
|
parentReference["path"] = "/root:/" + parent
|
||||||
|
|
||||||
parameters := make(map[string]interface{})
|
parameters := make(map[string]interface{})
|
||||||
parameters["parentReference"] = parentReference
|
parameters["parentReference"] = parentReference
|
||||||
@@ -504,7 +508,7 @@ func (client *OneDriveClient) CreateDirectory(path string, name string) error {
|
|||||||
return fmt.Errorf("The path '%s' is not a directory", path)
|
return fmt.Errorf("The path '%s' is not a directory", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
url = client.APIURL + "/drive/root:/" + path + ":/children"
|
url = client.APIURL + "/root:/" + path + ":/children"
|
||||||
}
|
}
|
||||||
|
|
||||||
parameters := make(map[string]interface{})
|
parameters := make(map[string]interface{})
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ type OneDriveStorage struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CreateOneDriveStorage creates an OneDrive storage object.
|
// CreateOneDriveStorage creates an OneDrive storage object.
|
||||||
func CreateOneDriveStorage(tokenFile string, isBusiness bool, storagePath string, threads int, client_id string, client_secret string) (storage *OneDriveStorage, err error) {
|
func CreateOneDriveStorage(tokenFile string, isBusiness bool, storagePath string, threads int, client_id string, client_secret string, drive_id string) (storage *OneDriveStorage, err error) {
|
||||||
|
|
||||||
for len(storagePath) > 0 && storagePath[len(storagePath)-1] == '/' {
|
for len(storagePath) > 0 && storagePath[len(storagePath)-1] == '/' {
|
||||||
storagePath = storagePath[:len(storagePath)-1]
|
storagePath = storagePath[:len(storagePath)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := NewOneDriveClient(tokenFile, isBusiness, client_id, client_secret)
|
client, err := NewOneDriveClient(tokenFile, isBusiness, client_id, client_secret, drive_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -261,7 +261,8 @@ func CreateStorage(preference Preference, resetPassword bool, threads int) (stor
|
|||||||
return fileStorage
|
return fileStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
urlRegex := regexp.MustCompile(`^([\w-]+)://([\w\-@\.]+@)?([^/]+)(/(.+))?`)
|
// Added \! to matched[2] because OneDrive drive ids contain ! (e.g. "b!xxx")
|
||||||
|
urlRegex := regexp.MustCompile(`^([\w-]+)://([\w\-@\.\!]+@)?([^/]+)(/(.+))?`)
|
||||||
|
|
||||||
matched := urlRegex.FindStringSubmatch(storageURL)
|
matched := urlRegex.FindStringSubmatch(storageURL)
|
||||||
|
|
||||||
@@ -644,6 +645,15 @@ func CreateStorage(preference Preference, resetPassword bool, threads int) (stor
|
|||||||
SavePassword(preference, "gcd_token", tokenFile)
|
SavePassword(preference, "gcd_token", tokenFile)
|
||||||
return gcdStorage
|
return gcdStorage
|
||||||
} else if matched[1] == "one" || matched[1] == "odb" {
|
} else if matched[1] == "one" || matched[1] == "odb" {
|
||||||
|
// Handle writing directly to the root of the drive
|
||||||
|
// For odb://drive_id@/, drive_id@ is match[3] not match[2]
|
||||||
|
if matched[2] == "" && strings.HasSuffix(matched[3], "@") {
|
||||||
|
matched[2], matched[3] = matched[3], matched[2]
|
||||||
|
}
|
||||||
|
drive_id := matched[2]
|
||||||
|
if len(drive_id) > 0 {
|
||||||
|
drive_id = drive_id[:len(drive_id)-1]
|
||||||
|
}
|
||||||
storagePath := matched[3] + matched[4]
|
storagePath := matched[3] + matched[4]
|
||||||
prompt := fmt.Sprintf("Enter the path of the OneDrive token file (downloadable from https://duplicacy.com/one_start):")
|
prompt := fmt.Sprintf("Enter the path of the OneDrive token file (downloadable from https://duplicacy.com/one_start):")
|
||||||
tokenFile := GetPassword(preference, matched[1] + "_token", prompt, true, resetPassword)
|
tokenFile := GetPassword(preference, matched[1] + "_token", prompt, true, resetPassword)
|
||||||
@@ -659,7 +669,7 @@ func CreateStorage(preference Preference, resetPassword bool, threads int) (stor
|
|||||||
client_secret = GetPassword(preference, matched[1] + "_client_secret", prompt, true, resetPassword)
|
client_secret = GetPassword(preference, matched[1] + "_client_secret", prompt, true, resetPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
oneDriveStorage, err := CreateOneDriveStorage(tokenFile, matched[1] == "odb", storagePath, threads, client_id, client_secret)
|
oneDriveStorage, err := CreateOneDriveStorage(tokenFile, matched[1] == "odb", storagePath, threads, client_id, client_secret, drive_id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LOG_ERROR("STORAGE_CREATE", "Failed to load the OneDrive storage at %s: %v", storageURL, err)
|
LOG_ERROR("STORAGE_CREATE", "Failed to load the OneDrive storage at %s: %v", storageURL, err)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user