mirror of
https://github.com/abraunegg/onedrive
synced 2024-05-04 06:53:23 +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
|
||||
--create-directory ARG
|
||||
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 OneDrive HTTPS communication.
|
||||
--destination-directory ARG
|
||||
|
|
|
@ -44,6 +44,9 @@ Set the directory used to store the configuration files
|
|||
\fB\-\-create\-directory\fP ARG
|
||||
Create a directory on OneDrive \- no sync will be performed.
|
||||
.TP
|
||||
\fB\-\-create\-share\-link\fP ARG
|
||||
Create a shareable link for an existing file on OneDrive
|
||||
.TP
|
||||
\fB\-\-debug\-https\fP
|
||||
Debug OneDrive HTTPS communication.
|
||||
.br
|
||||
|
|
|
@ -249,6 +249,7 @@ final class Config
|
|||
{
|
||||
// Add additional options that are NOT configurable via config file
|
||||
stringValues["create_directory"] = "";
|
||||
stringValues["create_share_link"] = "";
|
||||
stringValues["destination_directory"] = "";
|
||||
stringValues["get_file_link"] = "";
|
||||
stringValues["get_o365_drive_id"] = "";
|
||||
|
@ -293,6 +294,9 @@ final class Config
|
|||
"create-directory",
|
||||
"Create a directory on OneDrive - no sync will be performed.",
|
||||
&stringValues["create_directory"],
|
||||
"create-share-link",
|
||||
"Create a shareable link for an existing file on OneDrive",
|
||||
&stringValues["create_share_link"],
|
||||
"debug-https",
|
||||
"Debug OneDrive HTTPS communication.",
|
||||
&boolValues["debug_https"],
|
||||
|
@ -591,7 +595,9 @@ void outputLongHelp(Option[] opt)
|
|||
auto argsNeedingOptions = [
|
||||
"--confdir",
|
||||
"--create-directory",
|
||||
"--create-share-link",
|
||||
"--destination-directory",
|
||||
"--get-file-link",
|
||||
"--get-O365-drive-id",
|
||||
"--log-dir",
|
||||
"--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
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
@ -700,8 +700,8 @@ int main(string[] args)
|
|||
// Use exit scopes to shutdown API
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
if (cfg.getValueString("get_file_link") == "") {
|
||||
// Print out that we are initializing the engine only if we are not grabbing the 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 or creating a shareable link
|
||||
log.logAndNotify("Initializing the Synchronization Engine ...");
|
||||
}
|
||||
}
|
||||
|
@ -790,8 +790,18 @@ int main(string[] args)
|
|||
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?
|
||||
if (cfg.getValueString("get_file_link") != "") {
|
||||
// Query OneDrive for the file link
|
||||
sync.queryOneDriveForFileURL(cfg.getValueString("get_file_link"), syncDir);
|
||||
// Exit application
|
||||
// Use exit scopes to shutdown API
|
||||
|
|
|
@ -567,7 +567,6 @@ final class OneDriveApi
|
|||
return get(url);
|
||||
}
|
||||
|
||||
|
||||
// Return the requested details of the specified id
|
||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get
|
||||
JSONValue getFileDetails(const(char)[] driveId, const(char)[] id)
|
||||
|
@ -579,6 +578,17 @@ final class OneDriveApi
|
|||
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
|
||||
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
|
||||
void queryOneDriveForFileURL(string localFilePath, string syncDir)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue