Skip to content

Instantly share code, notes, and snippets.

@sntran
Last active August 28, 2021 17:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sntran/c1f83298412523cb0a20dafb2e1eacc0 to your computer and use it in GitHub Desktop.
Save sntran/c1f83298412523cb0a20dafb2e1eacc0 to your computer and use it in GitHub Desktop.
fclone.sh - rclone wrapper with extra functionality
#!/bin/bash
# fclone.sh v0.4.0
#
# Wrapper around rclone with extra functionality:
#
# - Flag `--drive-service-account-file-path` to take a random service account file from that folder
# - Flag `--drive-service-account-file-path` can also take a URL for a service account credentials.
# - `remote:{ID}` syntax to use the folder with that ID in the remote, instead of full path.
#
# Usage:
# ./fclone.sh --drive-service-account-file-path=accounts copy source:{ID-1} target:{ID-2}
# ./fclone.sh --drive-service-account-file-path="https://example.com/accounts/today.json" copy source:{ID-1} target:{ID-2}
fclone() {
local service_account_file=""
local service_account_file_path=""
local service_account_credentials=""
local args
while (($#)); do
case "$1" in
# `--drive-service-account-file-path path`
--drive-service-account-file-path)
if [ "$2" ]; then
service_account_file_path="$2"
shift
fi
;;
# `--drive-service-account-file-path=path`
--drive-service-account-file-path=?*)
service_account_file_path="${1#*=}" # Delete everything up to "=" and assign the remainder.
;;
# Empty `--drive-service-account-file-path=`
--drive-service-account-file-path=)
;;
# End of all options convention.
--)
shift
break
;;
# Remote in format remote:{folder-id}
*:{*})
name="${1%:*}"
NAME=$(echo ${name/-/_} | tr '[:lower:]' '[:upper:]')
root_folder_id="${1#*:}"
# Removes open curly bracket
root_folder_id=${root_folder_id#*{}
# Removes closing curly bracket
root_folder_id=${root_folder_id%\}}
export "RCLONE_CONFIG_${NAME}_ROOT_FOLDER_ID"=$root_folder_id
args+=("${name}:")
;;
# Default case: store into the args.
*)
args+=("$1")
;;
esac
shift
done
# Figures out a SA to use.
if [ -n "${service_account_file_path}" ]; then
case "${service_account_file_path}" in
# If a URL, gets the SA from it into credentials JSON.
http*)
service_account_credentials=$(curl -s "${service_account_file_path}")
args+=("--drive-service-account-credentials=${service_account_credentials}")
;;
# Otherwise a file, picks a random SA that has not been used today.
*)
service_account_file=$(find "${service_account_file_path}"/*.json -mtime +1 | sort -R | tail -1)
args+=("--drive-service-account-file=${service_account_file}")
;;
esac
fi
OPTARR=("${args[@]}")
set -- "${OPTARR[@]}"
# Removes the first element from `$@` if it is an empty string.
[ -z "$1" ] && shift
rclone "$@"
# Update the modified time on the service account file so it won't be reused today.
if [ -n "${service_account_file}" ]; then
touch "${service_account_file}"
fi
}
fclone "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment