#!/bin/bash
# Use --dry-run as third argument to pass to rclone
for f in 'd' 'dry' 'dry-run' 'echo'; do
if [ "${1}" == "--${f}" ]; then
Z_DRY=1
shift && break;
fi
done
# set flag to sync FROM bucket instead of TO
for f in 'rev' 'reverse' 'down' 'r'; do
if [ "${1}" == "--${f}" ]; then
Z_REV=1
shift && break;
fi
done
# set share
Z_SHR="${1}"
shift
# set path
Z_PTH="${1}"
shift
# rcloud bucket profile
Z_HST="midnight"
# local src directory
Z_SRC="/media/local"
# local dir = local src + share
Z_SRD="${Z_SRC}/${Z_SHR}"
# share name to lowercase = bucket name
Z_BUK="$(echo "${Z_SHR}" | tr '[:upper:]' '[:lower:]')"
# allow no path properly
if [ "${Z_PTH}" == "/" ]; then
Z_PTH=""
Z_NOP=1
fi
# bucket path = share path (without source dir)
Z_LPT="${Z_PTH}"
Z_OLP="${Z_LPT}"
# rclone (defined so we can echo instead when --echo used)
Z_CMD="rclone"
# rcloud command
Z_RCC="sync"
# default rclone options
Z_OPT=(
'-P'
'--delete-before'
'--delete-excluded'
);
# echo only
if [ ! -z "${Z_DRY}" ]; then
Z_CMD="echo ${Z_CMD}"
fi
# convenience handler to add option
function opt_add() {
Z_OPT+=("${@}")
}
# convenience handler to remove option (by name)
function opt_remove() {
delete=("${@}")
for target in "${delete[@]}"; do
for i in "${!Z_OPT[@]}"; do
if [[ ${Z_OPT[i]} = "${delete[0]}" ]]; then
unset 'Z_OPT[i]'
fi
done
done
}
# not really needed but keeping with the functions, sets rclone command
function opt_set_command() {
Z_RCC = "${1}"
}
# convenience wrapper to use convenience handler to remove multiple options
function opt_set_no_delete() {
opt_remove '--delete-before'
opt_remove '--delete-after'
opt_remove '--delete-during'
opt_remove '--delete-excluded'
opt_add '--max-delete 0'
}
# convenience wrapper to use convenience hander add an exclude option
function opt_add_exclude() {
# dont quote the argument or it wont work ¯\_(ツ)_/¯
opt_add "--exclude ${1}"
}
# convenience wrapper to use another convenience wrapper to use convenience handler to exclude a directory ;)
function opt_add_exclude_directory() {
opt_add_exclude "/${1}/**"
}
# check if original path starts with ${1}
function check_path() {
echo -n "${Z_OLP}" | grep -Pc "^${1}"
}
function set_custom_path() {
# redirect structure to another bucket
# /media/local/Console -> midnight:software/Console
if [ "${Z_SHR}" == "Console" ]; then
# override bucket name
Z_BUK="software"
# override source directory
Z_SRD="${Z_SRC}/Console"
# override local path
Z_LPT="${Z_PTH}"
# override bucket-side path
Z_PTH="Console/${Z_PTH}"
# /media/local/Console/PS3/archive -> midnight:software/Console/PS3
if [ $(check_path "PS3") -eq 1 ]; then
Z_LPT="PS3/archive"
if [ $(check_path "PS3/ISO") -eq 1 ]; then
# don't delete
opt_set_no_delete
opt_set_command 'copyto'
# lower system stress by limiting to 1 transfer/hasher
opt_add '--transfers 1' '--checkers 1'
fi
if [ $(check_path 'PS3(/)?$') -eq 1 ]; then
# root, so exclude ISO (see above)
opt_add_exclude_directory "ISO"
# don't delete excluded files
opt_remove '--delete-excluded'
else
# override local path, retaining extra path info
Z_TMP=$(echo "${Z_OLP}" | cut -d'/' -f2-)
if [ ! -z "${Z_TMP}" ]; then
Z_LPT="${Z_LPT}/${Z_TMP}"
fi
fi
fi
fi
if [ "${Z_SHR}" == "Backups" ] && [ $(check_path 'Videos') -eq 1 ]; then
# override bucket name
Z_BUK="backups"
# override source directory
Z_SRD="${Z_SRC}"
# override local path
Z_LPT="${Z_PTH}"
# override bucket-side path
Z_PTH="Media/${Z_PTH}"
fi
if [ "${Z_SHR}" == "Backups" ] && [ $(check_path 'Hosting') -eq 1 ]; then
# lower system stress by limiting to 4 transfers, 2 hashers
opt_add '--transfers 4' '--checkers 2'
fi
if [ "${Z_SHR}" == "YouTube" ]; then
opt_add_exclude_directory '.tmp'
opt_add_exclude_directory 'Web/cache'
fi
}
function do_bsync() {
if [ -z "${Z_PTH}" ] && [ -z "${Z_NOP}" ] || [ -z "${Z_BUK}" ]; then
# fail if arguements not provided
echo "Usage: ${0} [bucket] [path]"
else
# process path overrides (see function above)
set_custom_path
# make directory on bucket (doesn't fail if exists)
${Z_CMD} mkdir "${Z_HST}:${Z_BUK}/${Z_PTH}"
Z_RES=$?
if [ ! -d "${Z_SRD}/${Z_LPT}" ]; then
echo "Could not find source directory: ${Z_SRD}/${Z_LPT}";
exit 1;
fi
if [ ${Z_RES} -ne 0 ]; then
echo "Could not create directory ${Z_HST}:${Z_BUK}/${Z_PTH}. Does the bucket exist?"
exit ${Z_RES};
fi
# do the magic sync
if [ -z ${Z_REV} ]; then
# to bucket
${Z_CMD} "${Z_RCC}" "${Z_SRD}/${Z_LPT}" "${Z_HST}:${Z_BUK}/${Z_PTH}" "${Z_OPT[@]}" "${@}"
else
# from bucket
${Z_CMD} "${Z_RCC}" "${Z_HST}:${Z_BUK}/${Z_PTH}" "${Z_SRD}/${Z_LPT}" "${Z_OPT[@]}" "${@}"
fi
fi
}
if [ -z "${Z_INCLUDED}" ]; then
# if Z_INCLUDED is not defined, assume we are not included for our functions
do_bsync "${@}"
fi
Comments