#!/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