Skip to content

Commit

Permalink
Strict and minimalistic API v2.0 support, speed boost
Browse files Browse the repository at this point in the history
  • Loading branch information
rootik committed Aug 31, 2016
1 parent 6a94947 commit 1efb559
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 32 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ After the initial configuration you must authorize the app to use your OneDrive
and follow the steps. You will need a web browser.

After the authorization process has successfully completed you can upload files.

If you see error `AADSTS70002: Error validating credentials. AADSTS50012: Invalid client secret is provided`, try to add a new key and use new secret.

Usage (OneDrive Personal)
-----
Expand Down
2 changes: 1 addition & 1 deletion onedriveb-authorize
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export json_parser="${script_base_folder}/libs/json/bash-json-parser"
echo "Please open the following URL in your browser and follow the steps until you see a blank page:"
echo "https://login.microsoftonline.com/common/oauth2/authorize?response_type=code&client_id=${api_client_id}&redirect_uri=${api_reply_url}"
echo ""
echo "When ready, please enter the value of the code parameter (from the URL of the blank page) and press return"
echo "When ready, please enter the value of the code parameter (from the URL you have been redirected) and press return"
read code
api_json_result=$(curl -s -d "client_id=${api_client_id}&client_secret=${api_client_secret}&code=${code}&grant_type=authorization_code&redirect_uri=${api_reply_url}&resource=https://api.office.com/discovery/" -X POST "${api_auth_url}")

Expand Down
58 changes: 32 additions & 26 deletions onedriveb-base
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,20 @@ function urlencode() {
# ------------------ #
# --- cURL calls --- #
# ------------------ #
# helper function to get back 2 return values from function call
get_api() { api_uri="$1"; api_resource_id="$2"; }

# $1=helper function name
function curl_discover_uri() {
local fname="$1"

local api_access_token=$(onedrive_acquire_access_token ${api_discovery_id})
exit_on_error

local api_parsed_json_result=$(curl \
${curl_opts} \
--header "Authorization: Bearer ${api_access_token}" \
--get \
--header "Authorization: Bearer ${api_access_token}" \
--header "Accept: application/json; odata.metadata=none" \
--data-urlencode "\$select=serviceEndpointUri,serviceResourceId" \
--data-urlencode "\$filter=capability eq 'MyFiles' and serviceApiVersion eq 'v2.0'" \
"${api_discovery_url}" | "${json_parser}")
local api_version2=$(echo "${api_parsed_json_result}" | grep "serviceApiVersion=v2.0" | cut -d. -f 2)
api_uri=$(echo "${api_parsed_json_result}" | grep "value.${api_version2}.serviceEndpointUri" | ${get_json_value})
api_resource_id=$(echo "${api_parsed_json_result}" | grep "value.${api_version2}.serviceResourceId" | ${get_json_value})
"${fname}" "${api_uri}" "${api_resource_id}"
api_uri=$(echo "${api_parsed_json_result}" | grep "serviceEndpointUri" | ${get_json_value})
api_resource_id=$(echo "${api_parsed_json_result}" | grep "serviceResourceId" | ${get_json_value})
}

# $1=folder id
Expand All @@ -64,13 +61,15 @@ function curl_find_subfolder() {
else
folder_id="items/$1"
fi

local folder_name=$(urlencode "$2")
local url="${api_uri}/drive/${folder_id}:/${folder_name}?select=id&access_token=${api_access_token}"
local url="${api_uri}/drive/${folder_id}:/${folder_name}"

curl \
${curl_opts} \
--request GET \
--get \
--header "Authorization: Bearer ${api_access_token}" \
--header "Accept: application/json; odata.metadata=none" \
--data-urlencode "select=id" \
"${url}" | "${json_parser}"
}

Expand All @@ -81,16 +80,18 @@ function curl_create_folder() {
local url

if [ -z "$1" ]; then
url="${api_uri}/drive/${api_root_folder}/children?access_token=${api_access_token}"
url="${api_uri}/drive/${api_root_folder}/children?select=id"
else
local folder_id=$(urlencode "$1")
url="${api_uri}/drive/items/${folder_id}/children?access_token=${api_access_token}"
url="${api_uri}/drive/items/${folder_id}/children?select=id"
fi

curl \
${curl_opts} \
--request POST \
--header "Authorization: Bearer ${api_access_token}" \
--header "Content-Type: application/json" \
--header "Accept: application/json; odata.metadata=none" \
--data "${json_payload}" \
"${url}" | "${json_parser}"

Expand All @@ -107,6 +108,7 @@ function curl_get_access_token() {
${curl_opts} \
--request POST \
--header "Content-Type: application/x-www-form-urlencoded" \
--header "Accept: application/json; odata.metadata=none" \
--data-urlencode "client_id=${api_client_id}" \
--data-urlencode "client_secret=${api_client_secret}" \
--data-urlencode "redirect_uri=${api_reply_url}" \
Expand All @@ -123,18 +125,20 @@ function curl_upload_file() {

if [ -z "$1" ]; then
# No folder id, upload to root folder
url="${api_uri}/drive/${api_root_folder}/children/${url_filename}/content?access_token=${api_access_token}"
url="${api_uri}/drive/${api_root_folder}/children/${url_filename}/content"
debug "Uploading '${file}' as '${remote_filename}' into root folder (${api_root_folder})"
else
local folder_id=$(urlencode "$1")
url="${api_uri}/drive/items/${folder_id}/children/${url_filename}/content?access_token=${api_access_token}"
url="${api_uri}/drive/items/${folder_id}/children/${url_filename}/content"
debug "Uploading '${file}' as '${remote_filename}' into ${folder_id}"
fi

curl \
${curl_opts} \
--request PUT \
--header "Authorization: Bearer ${api_access_token}" \
--header "Content-Type: text/plain" \
--header "Accept: application/json; odata.metadata=none" \
--output /dev/null \
--write-out "%{http_code}" \
--upload-file "${file}" \
Expand All @@ -150,17 +154,19 @@ function curl_request_upload_session() {

if [ -z "$1" ]; then
# No folder id, upload to root folder
url="${api_uri}/drive/${api_root_folder}:/${url_filename}:/upload.createSession?access_token=${api_access_token}"
url="${api_uri}/drive/${api_root_folder}:/${url_filename}:/upload.createSession"
debug "Uploading '${file}' as '${remote_filename}' into root folder (${api_root_folder})"
else
url="${api_uri}/drive/items/${folder_id}:/${url_filename}:/upload.createSession?access_token=${api_access_token}"
url="${api_uri}/drive/items/${folder_id}:/${url_filename}:/upload.createSession"
debug "Uploading '${file}' as '${remote_filename}' into ${folder_id}"
fi

curl \
${curl_opts} \
--request POST \
--header "Authorization: Bearer ${api_access_token}" \
--header "Content-Type: application/json" \
--header "Accept: application/json; odata.metadata=none" \
--data "${json_payload}" \
"${url}" | "${json_parser}"

Expand Down Expand Up @@ -202,10 +208,12 @@ function curl_upload_chunk() {
--request PUT \
--output /dev/null \
--write-out "%{http_code}" \
--header "Authorization: Bearer ${api_access_token}" \
--header "Accept: application/json; odata.metadata=none" \
--header "Content-Length: ${current_range_length}" \
--header "Content-Range: bytes ${current_range_start}-${current_range_end}/${filesize}" \
--data-binary @- \
"${1}&access_token=${api_access_token}"
"${1}"
}


Expand Down Expand Up @@ -297,7 +305,6 @@ function onedrive_request_upload_session() {
function onedrive_find_folder_id() {
debug "Searching for '$2' in '$1'"
local api_parsed_json_result=$(curl_find_subfolder "$1" "$2")

echo "${api_parsed_json_result}" | grep -E "^id=" | ${get_json_value}
}

Expand All @@ -323,7 +330,7 @@ function onedrive_get_or_create_folder() {
local api_access_token
local current_folder_id="${api_folder_id}"
local next_folder_id
curl_discover_uri 'get_api'

api_access_token=$(onedrive_acquire_access_token ${api_resource_id})
exit_on_error

Expand All @@ -350,15 +357,14 @@ function onedrive_upload_file_simple() {
if [ ! -f "${file}" ]; then
error "An error has occurred while uploading '${file}' (File does not exist)"
fi
curl_discover_uri 'get_api'

api_access_token=$(onedrive_acquire_access_token ${api_resource_id})
exit_on_error

curl_upload_file "${api_folder_id}"
}

function onedrive_upload_file_chunked() {
curl_discover_uri 'get_api'
api_access_token=$(onedrive_acquire_access_token ${api_resource_id})
exit_on_error

Expand Down Expand Up @@ -391,7 +397,7 @@ function onedrive_upload_file_chunked() {
fi

status_code=$(curl_upload_chunk "${upload_url}" "${current_chunk}")

# Handle 429 Throttle Retry-After: seconds response
if [ "${status_code}" == "500" ] || \
[ "${status_code}" == "502" ] || \
[ "${status_code}" == "503" ] || \
Expand Down
10 changes: 8 additions & 2 deletions onedriveb-upload
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ while [[ $# -ge 1 ]]; do
echo "Usage: ${script_base_name} [OPTIONS] file1 [file2...]"
echo ""
echo "Options:"
echo " .d, --debug Enable debug mode"
echo " -d, --debug Enable debug mode"
echo " -f, --folder Upload files into this remote folder"
echo " Directory names are separated with a slash, e.g."
echo " rootFolder/subFolder"
Expand Down Expand Up @@ -59,13 +59,19 @@ if [ -z "$1" ]; then
exit 1
fi

curl_discover_uri
exit_on_error

export api_uri
export api_resource_id

if [ -n "${folder_name}" ]; then
# TODO Throw an error, if $2 contains illegal characters like double quotes
IFS='/' read -a folder_array <<< "${folder_name}"
api_folder_id=$(onedrive_get_or_create_folder "${folder_array[@]}")
exit_on_error

export api_folder_id
export api_folder_id
debug "api_folder_id is now '${api_folder_id}'"
fi

Expand Down
2 changes: 0 additions & 2 deletions onedriveb.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ export refresh_token_file="${script_base_folder}/.refresh_token"
export api_client_id=""
export api_client_secret=""
export api_reply_url="https://onedrive.live.com/about/business/"
# Permission to request on first authorization: One of ["onedrive.readwrite", "onedrive.appfolder"]
export api_permissions="onedrive.readwrite"

# Upload config
# API root folder: One of ["root", "special/approot", "items/FOLDERID"]
Expand Down

0 comments on commit 1efb559

Please sign in to comment.