Skip to content

Commit

Permalink
drive-utils|upload: Add flag to add description to uploaded or cloned…
Browse files Browse the repository at this point in the history
… file | Resolve labbots#145

-desc | --description | --description-all - Specify description for the given file.

    To use the respective metadata of a file, below is the format:

         File name ( fullname ): %f | Size: %s | Mime Type: %m

         Now to actually use it: --description 'Filename: %f, Size: %s, Mime: %m'

         Note: For files inside folders, use --description-all flag.

* add _json_escape function to common-utils
  • Loading branch information
Akianonymus committed May 9, 2021
1 parent 3d0ba30 commit 08a8bf3
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 32 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,22 @@ These are the custom flags that are currently implemented:

---

- <strong>-desc | --description | --description-all 'description'</strong>

Specify description for the given file.

To use the respective metadata of a file, below is the format:

File name ( fullname ): %f
Size: %s
Mime Type: %m

Now to actually use it: `--description 'Filename: %f, Size: %s, Mime: %m'`

Note: For files inside folders, use `--description-all` flag.

---

- <strong>-d | --skip-duplicates</strong>

Do not upload the files with the same name, if already present in the root folder/input folder, also works with recursive folders.
Expand Down
25 changes: 25 additions & 0 deletions bash/common-utils.bash
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,30 @@ _get_latest_sha() {
printf "%b" "${LATEST_SHA:+${LATEST_SHA}\n}"
}

###################################################
# Encode the given string to parse properly as json
# Globals: None
# Arguments: 1
# ${1} = string
# Result: print encoded string
# Reference:
# https://tools.ietf.org/html/rfc7159#section-7
###################################################
_json_escape() {
declare input="${1:?Provide Input}"
: "${input//\\/\\\\}" \
: "${_//\//\\\/}" # \
# /
: "${_//\'/\\\'}" # ' (not strictly needed ?)
: "${_//\"/\\\"}" # "
: "${_//$'\t'/\\\t}" # \t (tab)
: "${_//$'\n'/\\\n}" # \n (newline)
: "${_//$'\r'/\\\r}" # \r (carriage return)
: "${_//$'\f'/\\\f}" # \f (form feed)
: "${_//$'\b'/\\\b}" # \b (backspace)
printf "%s" "${_}"
}

###################################################
# Method to extract specified field data from json
# Globals: None
Expand Down Expand Up @@ -386,6 +410,7 @@ ALL_FUNCTIONS=(_bytes_to_human
_dirname
_display_time
_get_latest_sha
_json_escape
_json_value
_print_center
_print_center_quiet
Expand Down
28 changes: 21 additions & 7 deletions bash/drive-utils.bash
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ _check_existing_file() {
###################################################
# Copy/Clone a public gdrive file/folder from another/same gdrive account
# Globals: 6 variables, 2 functions
# Variables - API_URL, API_VERSION, CURL_PROGRESS, LOG_FILE_ID, QUIET, ACCESS_TOKEN
# Variables - API_URL, API_VERSION, CURL_PROGRESS, LOG_FILE_ID, QUIET, ACCESS_TOKEN, DESCRIPTION_FILE
# Functions - _print_center, _check_existing_file, _json_value, _bytes_to_human, _clear_line
# Arguments: 5
# ${1} = update or upload ( upload type )
Expand All @@ -47,10 +47,17 @@ _check_existing_file() {
_clone_file() {
[[ $# -lt 5 ]] && printf "%s: Missing arguments\n" "${FUNCNAME[0]}" && return 1
declare job="${1}" file_id="${2}" file_root_id="${3}" name="${4}" size="${5}"
declare clone_file_post_data clone_file_response readable_size _file_id && STRING="Cloned"
clone_file_post_data="{\"parents\": [\"${file_root_id}\"]}"
declare clone_file_post_data clone_file_response readable_size _file_id description && STRING="Cloned"
readable_size="$(_bytes_to_human "${size}")"

# create description data
[[ -n ${DESCRIPTION_FILE} ]] && {
: "${DESCRIPTION_FILE//%f/${name}}" && : "${_//%s/${readable_size}}"
description="$(_json_escape "${_}")" # escape for json
}

clone_file_post_data="{\"parents\": [\"${file_root_id}\"]${description:+,\"description\":\"${description}\"}}"

_print_center "justify" "${name} " "| ${readable_size}" "="

if [[ ${job} = update ]]; then
Expand Down Expand Up @@ -181,7 +188,7 @@ _extract_id() {
# Upload ( Create/Update ) files on gdrive.
# Interrupted uploads can be resumed.
# Globals: 8 variables, 10 functions
# Variables - API_URL, API_VERSION, QUIET, VERBOSE, VERBOSE_PROGRESS, CURL_PROGRESS, LOG_FILE_ID, ACCESS_TOKEN
# Variables - API_URL, API_VERSION, QUIET, VERBOSE, VERBOSE_PROGRESS, CURL_PROGRESS, LOG_FILE_ID, ACCESS_TOKEN, DESCRIPTION_FILE
# Functions - _url_encode, _json_value, _print_center, _bytes_to_human
# _generate_upload_link, _upload_file_from_uri, _log_upload_session, _remove_upload_session
# _full_upload, _collect_file_info
Expand All @@ -200,7 +207,8 @@ _extract_id() {
_upload_file() {
[[ $# -lt 3 ]] && printf "%s: Missing arguments\n" "${FUNCNAME[0]}" && return 1
declare job="${1}" input="${2}" folder_id="${3}" \
slug inputname extension inputsize readable_size request_method url postdata uploadlink upload_body mime_type resume_args1 resume_args2 resume_args3
slug inputname extension inputsize readable_size request_method url postdata uploadlink upload_body mime_type description \
resume_args1 resume_args2 resume_args3

slug="${input##*/}"
inputname="${slug%.*}"
Expand All @@ -216,6 +224,12 @@ _upload_file() {
}
}

# create description data
[[ -n ${DESCRIPTION_FILE} ]] && {
: "${DESCRIPTION_FILE//%f/${slug}}" && : "${_//%s/${inputsize}}" && : "${_//%m/${mime_type}}"
description="$(_json_escape "${_}")" # escape for json
}

_print_center "justify" "${input##*/}" " | ${readable_size}" "="

# Set proper variables for overwriting files
Expand All @@ -234,7 +248,7 @@ _upload_file() {
{ _error_logging_upload "${slug}" "${file_check_json}" || return 1; }
url="${API_URL}/upload/drive/${API_VERSION}/files/${_file_id}?uploadType=resumable&supportsAllDrives=true&includeItemsFromAllDrives=true"
# JSON post data to specify the file name and folder under while the file to be updated
postdata="{\"mimeType\": \"${mime_type}\",\"name\": \"${slug}\",\"addParents\": [\"${folder_id}\"]}"
postdata="{\"mimeType\": \"${mime_type}\",\"name\": \"${slug}\",\"addParents\": [\"${folder_id}\"]${description:+,\"description\":\"${description}\"}}"
STRING="Updated"
fi
else
Expand All @@ -247,7 +261,7 @@ _upload_file() {
url="${API_URL}/upload/drive/${API_VERSION}/files?uploadType=resumable&supportsAllDrives=true&includeItemsFromAllDrives=true"
request_method="POST"
# JSON post data to specify the file name and folder under while the file to be created
postdata="{\"mimeType\": \"${mime_type}\",\"name\": \"${slug}\",\"parents\": [\"${folder_id}\"]}"
postdata="{\"mimeType\": \"${mime_type}\",\"name\": \"${slug}\",\"parents\": [\"${folder_id}\"]${description:+,\"description\":\"${description}\"}}"
STRING="Uploaded"
}

Expand Down
25 changes: 25 additions & 0 deletions bash/release/gsync
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,30 @@ _get_latest_sha() {
printf "%b" "${LATEST_SHA:+${LATEST_SHA}\n}"
}

###################################################
# Encode the given string to parse properly as json
# Globals: None
# Arguments: 1
# ${1} = string
# Result: print encoded string
# Reference:
# https://tools.ietf.org/html/rfc7159#section-7
###################################################
_json_escape() {
declare input="${1:?Provide Input}"
: "${input//\\/\\\\}" \
: "${_//\//\\\/}" # \
# /
: "${_//\'/\\\'}" # ' (not strictly needed ?)
: "${_//\"/\\\"}" # "
: "${_//$'\t'/\\\t}" # \t (tab)
: "${_//$'\n'/\\\n}" # \n (newline)
: "${_//$'\r'/\\\r}" # \r (carriage return)
: "${_//$'\f'/\\\f}" # \f (form feed)
: "${_//$'\b'/\\\b}" # \b (backspace)
printf "%s" "${_}"
}

###################################################
# Method to extract specified field data from json
# Globals: None
Expand Down Expand Up @@ -387,6 +411,7 @@ ALL_FUNCTIONS=(_bytes_to_human
_dirname
_display_time
_get_latest_sha
_json_escape
_json_value
_print_center
_print_center_quiet
Expand Down
76 changes: 68 additions & 8 deletions bash/release/gupload
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,30 @@ _get_latest_sha() {
printf "%b" "${LATEST_SHA:+${LATEST_SHA}\n}"
}

###################################################
# Encode the given string to parse properly as json
# Globals: None
# Arguments: 1
# ${1} = string
# Result: print encoded string
# Reference:
# https://tools.ietf.org/html/rfc7159#section-7
###################################################
_json_escape() {
declare input="${1:?Provide Input}"
: "${input//\\/\\\\}" \
: "${_//\//\\\/}" # \
# /
: "${_//\'/\\\'}" # ' (not strictly needed ?)
: "${_//\"/\\\"}" # "
: "${_//$'\t'/\\\t}" # \t (tab)
: "${_//$'\n'/\\\n}" # \n (newline)
: "${_//$'\r'/\\\r}" # \r (carriage return)
: "${_//$'\f'/\\\f}" # \f (form feed)
: "${_//$'\b'/\\\b}" # \b (backspace)
printf "%s" "${_}"
}

###################################################
# Method to extract specified field data from json
# Globals: None
Expand Down Expand Up @@ -387,6 +411,7 @@ ALL_FUNCTIONS=(_bytes_to_human
_dirname
_display_time
_get_latest_sha
_json_escape
_json_value
_print_center
_print_center_quiet
Expand Down Expand Up @@ -929,7 +954,7 @@ _check_existing_file() {
###################################################
# Copy/Clone a public gdrive file/folder from another/same gdrive account
# Globals: 6 variables, 2 functions
# Variables - API_URL, API_VERSION, CURL_PROGRESS, LOG_FILE_ID, QUIET, ACCESS_TOKEN
# Variables - API_URL, API_VERSION, CURL_PROGRESS, LOG_FILE_ID, QUIET, ACCESS_TOKEN, DESCRIPTION_FILE
# Functions - _print_center, _check_existing_file, _json_value, _bytes_to_human, _clear_line
# Arguments: 5
# ${1} = update or upload ( upload type )
Expand All @@ -946,10 +971,17 @@ _check_existing_file() {
_clone_file() {
[[ $# -lt 5 ]] && printf "%s: Missing arguments\n" "${FUNCNAME[0]}" && return 1
declare job="${1}" file_id="${2}" file_root_id="${3}" name="${4}" size="${5}"
declare clone_file_post_data clone_file_response readable_size _file_id && STRING="Cloned"
clone_file_post_data="{\"parents\": [\"${file_root_id}\"]}"
declare clone_file_post_data clone_file_response readable_size _file_id description && STRING="Cloned"
readable_size="$(_bytes_to_human "${size}")"

# create description data
[[ -n ${DESCRIPTION_FILE} ]] && {
: "${DESCRIPTION_FILE//%f/${name}}" && : "${_//%s/${readable_size}}"
description="$(_json_escape "${_}")" # escape for json
}

clone_file_post_data="{\"parents\": [\"${file_root_id}\"]${description:+,\"description\":\"${description}\"}}"

_print_center "justify" "${name} " "| ${readable_size}" "="

if [[ ${job} = update ]]; then
Expand Down Expand Up @@ -1080,7 +1112,7 @@ _extract_id() {
# Upload ( Create/Update ) files on gdrive.
# Interrupted uploads can be resumed.
# Globals: 8 variables, 10 functions
# Variables - API_URL, API_VERSION, QUIET, VERBOSE, VERBOSE_PROGRESS, CURL_PROGRESS, LOG_FILE_ID, ACCESS_TOKEN
# Variables - API_URL, API_VERSION, QUIET, VERBOSE, VERBOSE_PROGRESS, CURL_PROGRESS, LOG_FILE_ID, ACCESS_TOKEN, DESCRIPTION_FILE
# Functions - _url_encode, _json_value, _print_center, _bytes_to_human
# _generate_upload_link, _upload_file_from_uri, _log_upload_session, _remove_upload_session
# _full_upload, _collect_file_info
Expand All @@ -1099,7 +1131,8 @@ _extract_id() {
_upload_file() {
[[ $# -lt 3 ]] && printf "%s: Missing arguments\n" "${FUNCNAME[0]}" && return 1
declare job="${1}" input="${2}" folder_id="${3}" \
slug inputname extension inputsize readable_size request_method url postdata uploadlink upload_body mime_type resume_args1 resume_args2 resume_args3
slug inputname extension inputsize readable_size request_method url postdata uploadlink upload_body mime_type description \
resume_args1 resume_args2 resume_args3

slug="${input##*/}"
inputname="${slug%.*}"
Expand All @@ -1115,6 +1148,12 @@ _upload_file() {
}
}

# create description data
[[ -n ${DESCRIPTION_FILE} ]] && {
: "${DESCRIPTION_FILE//%f/${slug}}" && : "${_//%s/${inputsize}}" && : "${_//%m/${mime_type}}"
description="$(_json_escape "${_}")" # escape for json
}

_print_center "justify" "${input##*/}" " | ${readable_size}" "="

# Set proper variables for overwriting files
Expand All @@ -1133,7 +1172,7 @@ _upload_file() {
{ _error_logging_upload "${slug}" "${file_check_json}" || return 1; }
url="${API_URL}/upload/drive/${API_VERSION}/files/${_file_id}?uploadType=resumable&supportsAllDrives=true&includeItemsFromAllDrives=true"
# JSON post data to specify the file name and folder under while the file to be updated
postdata="{\"mimeType\": \"${mime_type}\",\"name\": \"${slug}\",\"addParents\": [\"${folder_id}\"]}"
postdata="{\"mimeType\": \"${mime_type}\",\"name\": \"${slug}\",\"addParents\": [\"${folder_id}\"]${description:+,\"description\":\"${description}\"}}"
STRING="Updated"
fi
else
Expand All @@ -1146,7 +1185,7 @@ _upload_file() {
url="${API_URL}/upload/drive/${API_VERSION}/files?uploadType=resumable&supportsAllDrives=true&includeItemsFromAllDrives=true"
request_method="POST"
# JSON post data to specify the file name and folder under while the file to be created
postdata="{\"mimeType\": \"${mime_type}\",\"name\": \"${slug}\",\"parents\": [\"${folder_id}\"]}"
postdata="{\"mimeType\": \"${mime_type}\",\"name\": \"${slug}\",\"parents\": [\"${folder_id}\"]${description:+,\"description\":\"${description}\"}}"
STRING="Uploaded"
}

Expand Down Expand Up @@ -1509,6 +1548,10 @@ Options:\n
-f | --[file|folder] - Specify files and folders explicitly in one command, use multiple times for multiple folder/files. See README for more use of this command.\n
-cl | --clone - Upload a gdrive file without downloading, require accessible gdrive link or id as argument.\n
-o | --overwrite - Overwrite the files with the same name, if present in the root folder/input folder, also works with recursive folders.\n
-desc | --description | --description-all - Specify description for the given file. To use the respective metadata of a file, below is the format:\n
File name ( fullname ): %f | Size: %s | Mime Type: %m\n
Now to actually use it: --description 'Filename: %f, Size: %s, Mime: %m'\n
Note: For files inside folders, use --description-all flag.\n
-d | --skip-duplicates - Do not upload the files with the same name, if already present in the root folder/input folder, also works with recursive folders.\n
-S | --share <optional_email_address>- Share the uploaded input file/folder, grant reader permission to provided email address or to everyone with the shareable link.\n
--speed 'speed' - Limit the download speed, supported formats: 1K, 1M and 1G.\n
Expand Down Expand Up @@ -1603,7 +1646,7 @@ _setup_arguments() {
# De-initialize if any variables set already.
unset LIST_ACCOUNTS UPDATE_DEFAULT_ACCOUNT CUSTOM_ACCOUNT_NAME NEW_ACCOUNT_NAME DELETE_ACCOUNT_NAME ACCOUNT_ONLY_RUN
unset FOLDERNAME LOCAL_INPUT_ARRAY ID_INPUT_ARRAY CONTINUE_WITH_NO_INPUT
unset PARALLEL NO_OF_PARALLEL_JOBS SHARE SHARE_EMAIL OVERWRITE SKIP_DUPLICATES SKIP_SUBDIRS ROOTDIR QUIET
unset PARALLEL NO_OF_PARALLEL_JOBS SHARE SHARE_EMAIL OVERWRITE SKIP_DUPLICATES DESCRIPTION SKIP_SUBDIRS ROOTDIR QUIET
unset VERBOSE VERBOSE_PROGRESS DEBUG LOG_FILE_ID CURL_SPEED RETRY
export CURL_PROGRESS="-s" EXTRA_LOG=":" CURL_PROGRESS_EXTRA="-s"
INFO_PATH="${HOME}/.google-drive-upload" CONFIG_INFO="${INFO_PATH}/google-drive-upload.configpath"
Expand Down Expand Up @@ -1686,6 +1729,11 @@ _setup_arguments() {
;;
-o | --overwrite) export OVERWRITE="Overwrite" UPLOAD_MODE="update" ;;
-d | --skip-duplicates) export SKIP_DUPLICATES="Skip Existing" UPLOAD_MODE="update" ;;
-desc | --description | --description-all)
_check_longoptions "${1}" "${2}"
[[ ${1} = "--description-all" ]] && export DESCRIPTION_ALL="true"
export DESCRIPTION="${2}" && shift
;;
-f | --file | --folder)
_check_longoptions "${1}" "${2}"
LOCAL_INPUT_ARRAY+=("${2}") && shift
Expand Down Expand Up @@ -1903,6 +1951,9 @@ _process_arguments() {
for input in "${FINAL_LOCAL_INPUT_ARRAY[@]}"; do
# Check if the argument is a file or a directory.
if [[ -f ${input} ]]; then
# export DESCRIPTION_FILE, used for descriptions in _upload_file function
export DESCRIPTION_FILE="${DESCRIPTION}"

_print_center "justify" "Given Input" ": FILE" "="
_print_center "justify" "Upload Method" ": ${SKIP_DUPLICATES:-${OVERWRITE:-Create}}" "=" && _newline "\n"
_upload_file_main noparse "${input}" "${WORKSPACE_FOLDER_ID}"
Expand All @@ -1916,6 +1967,9 @@ _process_arguments() {
input="$(cd "${input}" && pwd)" || return 1 # to handle _dirname when current directory (.) is given as input.
unset EMPTY # Used when input folder is empty

# export DESCRIPTION_FILE only if DESCRIPTION_ALL var is available, used for descriptions in _upload_file function
export DESCRIPTION_FILE="${DESCRIPTION_ALL:+${DESCRIPTION}}"

_print_center "justify" "Given Input" ": FOLDER" "-"
_print_center "justify" "Upload Method" ": ${SKIP_DUPLICATES:-${OVERWRITE:-Create}}" "=" && _newline "\n"
FOLDER_NAME="${input##*/}" && "${EXTRA_LOG}" "justify" "Folder: ${FOLDER_NAME}" "="
Expand Down Expand Up @@ -2039,9 +2093,15 @@ _process_arguments() {
size="$(_json_value size 1 1 <<< "${json}" || :)"
for _ in 1 2; do _clear_line 1; done
if [[ ${type} =~ folder ]]; then
# export DESCRIPTION_FILE only if DESCRIPTION_ALL var is available, used for descriptions in _clone_file function
export DESCRIPTION_FILE="${DESCRIPTION_ALL+:${DESCRIPTION}}"

"${QUIET:-_print_center}" "justify" "Folder not supported." "=" 1>&2 && _newline "\n" 1>&2 && continue
## TODO: Add support to clone folders
else
# export DESCRIPTION_FILE, used for descriptions in _clone_file function
export DESCRIPTION_FILE="${DESCRIPTION}"

_print_center "justify" "Given Input" ": File ID" "="
_print_center "justify" "Upload Method" ": ${SKIP_DUPLICATES:-${OVERWRITE:-Create}}" "=" && _newline "\n"
_clone_file "${UPLOAD_MODE:-create}" "${gdrive_id}" "${WORKSPACE_FOLDER_ID}" "${name}" "${size}" ||
Expand Down
Loading

0 comments on commit 08a8bf3

Please sign in to comment.