mirror of
https://github.com/abraunegg/onedrive
synced 2024-05-16 20:56:44 +02:00
Implement Feature: Create shareable link (#1061)
* Implement feature request to create a shareable file link. Default is to create a read-only anonymous link Co-authored-by: Norbert Preining <norbert@preining.info>
This commit is contained in:
parent
4ddad0c350
commit
0c770efa96
|
@ -689,6 +689,8 @@ Options:
|
||||||
Set the directory used to store the configuration files
|
Set the directory used to store the configuration files
|
||||||
--create-directory ARG
|
--create-directory ARG
|
||||||
Create a directory on OneDrive - no sync will be performed.
|
Create a directory on OneDrive - no sync will be performed.
|
||||||
|
--create-share-link ARG
|
||||||
|
Create a shareable link for an existing file on OneDrive
|
||||||
--debug-https
|
--debug-https
|
||||||
Debug OneDrive HTTPS communication.
|
Debug OneDrive HTTPS communication.
|
||||||
--destination-directory ARG
|
--destination-directory ARG
|
||||||
|
|
|
@ -44,6 +44,9 @@ Set the directory used to store the configuration files
|
||||||
\fB\-\-create\-directory\fP ARG
|
\fB\-\-create\-directory\fP ARG
|
||||||
Create a directory on OneDrive \- no sync will be performed.
|
Create a directory on OneDrive \- no sync will be performed.
|
||||||
.TP
|
.TP
|
||||||
|
\fB\-\-create\-share\-link\fP ARG
|
||||||
|
Create a shareable link for an existing file on OneDrive
|
||||||
|
.TP
|
||||||
\fB\-\-debug\-https\fP
|
\fB\-\-debug\-https\fP
|
||||||
Debug OneDrive HTTPS communication.
|
Debug OneDrive HTTPS communication.
|
||||||
.br
|
.br
|
||||||
|
|
|
@ -249,6 +249,7 @@ final class Config
|
||||||
{
|
{
|
||||||
// Add additional options that are NOT configurable via config file
|
// Add additional options that are NOT configurable via config file
|
||||||
stringValues["create_directory"] = "";
|
stringValues["create_directory"] = "";
|
||||||
|
stringValues["create_share_link"] = "";
|
||||||
stringValues["destination_directory"] = "";
|
stringValues["destination_directory"] = "";
|
||||||
stringValues["get_file_link"] = "";
|
stringValues["get_file_link"] = "";
|
||||||
stringValues["get_o365_drive_id"] = "";
|
stringValues["get_o365_drive_id"] = "";
|
||||||
|
@ -293,6 +294,9 @@ final class Config
|
||||||
"create-directory",
|
"create-directory",
|
||||||
"Create a directory on OneDrive - no sync will be performed.",
|
"Create a directory on OneDrive - no sync will be performed.",
|
||||||
&stringValues["create_directory"],
|
&stringValues["create_directory"],
|
||||||
|
"create-share-link",
|
||||||
|
"Create a shareable link for an existing file on OneDrive",
|
||||||
|
&stringValues["create_share_link"],
|
||||||
"debug-https",
|
"debug-https",
|
||||||
"Debug OneDrive HTTPS communication.",
|
"Debug OneDrive HTTPS communication.",
|
||||||
&boolValues["debug_https"],
|
&boolValues["debug_https"],
|
||||||
|
@ -591,7 +595,9 @@ void outputLongHelp(Option[] opt)
|
||||||
auto argsNeedingOptions = [
|
auto argsNeedingOptions = [
|
||||||
"--confdir",
|
"--confdir",
|
||||||
"--create-directory",
|
"--create-directory",
|
||||||
|
"--create-share-link",
|
||||||
"--destination-directory",
|
"--destination-directory",
|
||||||
|
"--get-file-link",
|
||||||
"--get-O365-drive-id",
|
"--get-O365-drive-id",
|
||||||
"--log-dir",
|
"--log-dir",
|
||||||
"--min-notify-changes",
|
"--min-notify-changes",
|
||||||
|
|
16
src/main.d
16
src/main.d
|
@ -565,7 +565,7 @@ int main(string[] args)
|
||||||
|
|
||||||
// create-directory, remove-directory, source-directory, destination-directory
|
// create-directory, remove-directory, source-directory, destination-directory
|
||||||
// these are activities that dont perform a sync, so to not generate an error message for these items either
|
// these are activities that dont perform a sync, so to not generate an error message for these items either
|
||||||
if (((cfg.getValueString("create_directory") != "") || (cfg.getValueString("remove_directory") != "")) || ((cfg.getValueString("source_directory") != "") && (cfg.getValueString("destination_directory") != "")) || (cfg.getValueString("get_file_link") != "") || (cfg.getValueString("get_o365_drive_id") != "") || cfg.getValueBool("display_sync_status") || cfg.getValueBool("list_business_shared_folders")) {
|
if (((cfg.getValueString("create_directory") != "") || (cfg.getValueString("remove_directory") != "")) || ((cfg.getValueString("source_directory") != "") && (cfg.getValueString("destination_directory") != "")) || (cfg.getValueString("get_file_link") != "") || (cfg.getValueString("create_share_link") != "") || (cfg.getValueString("get_o365_drive_id") != "") || cfg.getValueBool("display_sync_status") || cfg.getValueBool("list_business_shared_folders")) {
|
||||||
performSyncOK = true;
|
performSyncOK = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,8 +700,8 @@ int main(string[] args)
|
||||||
// Use exit scopes to shutdown API
|
// Use exit scopes to shutdown API
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
} else {
|
} else {
|
||||||
if (cfg.getValueString("get_file_link") == "") {
|
if ((cfg.getValueString("get_file_link") == "") && (cfg.getValueString("create_share_link") == "")) {
|
||||||
// Print out that we are initializing the engine only if we are not grabbing the file link
|
// Print out that we are initializing the engine only if we are not grabbing the file link or creating a shareable link
|
||||||
log.logAndNotify("Initializing the Synchronization Engine ...");
|
log.logAndNotify("Initializing the Synchronization Engine ...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -790,8 +790,18 @@ int main(string[] args)
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Are we createing an anonymous read-only shareable link for an existing file on OneDrive?
|
||||||
|
if (cfg.getValueString("create_share_link") != "") {
|
||||||
|
// Query OneDrive for the file, and if valid, create a shareable link for the file
|
||||||
|
sync.createShareableLinkForFile(cfg.getValueString("create_share_link"));
|
||||||
|
// Exit application
|
||||||
|
// Use exit scopes to shutdown API
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
// Are we obtaining the URL path for a synced file?
|
// Are we obtaining the URL path for a synced file?
|
||||||
if (cfg.getValueString("get_file_link") != "") {
|
if (cfg.getValueString("get_file_link") != "") {
|
||||||
|
// Query OneDrive for the file link
|
||||||
sync.queryOneDriveForFileURL(cfg.getValueString("get_file_link"), syncDir);
|
sync.queryOneDriveForFileURL(cfg.getValueString("get_file_link"), syncDir);
|
||||||
// Exit application
|
// Exit application
|
||||||
// Use exit scopes to shutdown API
|
// Use exit scopes to shutdown API
|
||||||
|
|
|
@ -567,7 +567,6 @@ final class OneDriveApi
|
||||||
return get(url);
|
return get(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Return the requested details of the specified id
|
// Return the requested details of the specified id
|
||||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get
|
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get
|
||||||
JSONValue getFileDetails(const(char)[] driveId, const(char)[] id)
|
JSONValue getFileDetails(const(char)[] driveId, const(char)[] id)
|
||||||
|
@ -579,6 +578,17 @@ final class OneDriveApi
|
||||||
return get(url);
|
return get(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create an anonymous read-only shareable link for an existing file on OneDrive
|
||||||
|
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createlink
|
||||||
|
JSONValue createShareableLink(const(char)[] driveId, const(char)[] id, JSONValue accessScope)
|
||||||
|
{
|
||||||
|
checkAccessTokenExpired();
|
||||||
|
const(char)[] url;
|
||||||
|
url = driveByIdUrl ~ driveId ~ "/items/" ~ id ~ "/createLink";
|
||||||
|
http.addRequestHeader("Content-Type", "application/json");
|
||||||
|
return post(url, accessScope.toString());
|
||||||
|
}
|
||||||
|
|
||||||
// https://dev.onedrive.com/items/move.htm
|
// https://dev.onedrive.com/items/move.htm
|
||||||
JSONValue moveByPath(const(char)[] sourcePath, JSONValue moveData)
|
JSONValue moveByPath(const(char)[] sourcePath, JSONValue moveData)
|
||||||
{
|
{
|
||||||
|
|
77
src/sync.d
77
src/sync.d
|
@ -5173,6 +5173,83 @@ final class SyncEngine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create an anonymous read-only shareable link for an existing file on OneDrive
|
||||||
|
void createShareableLinkForFile(string filePath)
|
||||||
|
{
|
||||||
|
JSONValue onedrivePathDetails;
|
||||||
|
JSONValue createShareableLinkResponse;
|
||||||
|
string driveId;
|
||||||
|
string itemId;
|
||||||
|
string fileShareLink;
|
||||||
|
|
||||||
|
// Get the path details from OneDrive
|
||||||
|
try {
|
||||||
|
onedrivePathDetails = onedrive.getPathDetails(filePath); // Returns a JSON String for the OneDrive Path
|
||||||
|
} catch (OneDriveException e) {
|
||||||
|
log.vdebug("onedrivePathDetails = onedrive.getPathDetails(filePath); generated a OneDriveException");
|
||||||
|
if (e.httpStatusCode == 404) {
|
||||||
|
// Requested path could not be found
|
||||||
|
log.error("ERROR: The requested path to query was not found on OneDrive");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.httpStatusCode == 429) {
|
||||||
|
// HTTP request returned status code 429 (Too Many Requests). We need to leverage the response Retry-After HTTP header to ensure minimum delay until the throttle is removed.
|
||||||
|
handleOneDriveThrottleRequest();
|
||||||
|
// Retry original request by calling function again to avoid replicating any further error handling
|
||||||
|
log.vdebug("Retrying original request that generated the OneDrive HTTP 429 Response Code (Too Many Requests) - calling queryDriveForChanges(path);");
|
||||||
|
createShareableLinkForFile(filePath);
|
||||||
|
// return back to original call
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.httpStatusCode == 504) {
|
||||||
|
// HTTP request returned status code 504 (Gateway Timeout)
|
||||||
|
log.log("OneDrive returned a 'HTTP 504 - Gateway Timeout' - retrying request");
|
||||||
|
// Retry original request by calling function again to avoid replicating any further error handling
|
||||||
|
createShareableLinkForFile(filePath);
|
||||||
|
// return back to original call
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// display what the error is
|
||||||
|
displayOneDriveErrorMessage(e.msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Was a valid JSON response received?
|
||||||
|
if (onedrivePathDetails.type() == JSONType.object) {
|
||||||
|
// valid JSON response for the file was received
|
||||||
|
// Configure the required variables
|
||||||
|
driveId = onedrivePathDetails["parentReference"]["driveId"].str;
|
||||||
|
itemId = onedrivePathDetails["id"].str;
|
||||||
|
|
||||||
|
// configure the access scope
|
||||||
|
JSONValue accessScope = [
|
||||||
|
"type": "view",
|
||||||
|
"scope": "anonymous"
|
||||||
|
];
|
||||||
|
|
||||||
|
// Create the shareable file link
|
||||||
|
createShareableLinkResponse = onedrive.createShareableLink(driveId, itemId, accessScope);
|
||||||
|
if ((createShareableLinkResponse.type() == JSONType.object) && ("link" in createShareableLinkResponse)) {
|
||||||
|
// Extract the file share link from the JSON response
|
||||||
|
fileShareLink = createShareableLinkResponse["link"]["webUrl"].str;
|
||||||
|
writeln("File Shareable Link: ", fileShareLink);
|
||||||
|
} else {
|
||||||
|
// not a valid JSON object
|
||||||
|
log.error("ERROR: There was an error performing this operation on OneDrive");
|
||||||
|
log.error("ERROR: Increase logging verbosity to assist determining why.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// not a valid JSON object
|
||||||
|
log.error("ERROR: There was an error performing this operation on OneDrive");
|
||||||
|
log.error("ERROR: Increase logging verbosity to assist determining why.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Query OneDrive for a URL path of a file
|
// Query OneDrive for a URL path of a file
|
||||||
void queryOneDriveForFileURL(string localFilePath, string syncDir)
|
void queryOneDriveForFileURL(string localFilePath, string syncDir)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue