| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- #!/bin/bash
- # Config
- BASE_LOCAL="`~/bin/video/mediaPath`"
- BASE_REMOTE="/Volumes/Bitcasa Infinite Drive"
- # Command-line arguments
- SUB_DIR="${1}"
- declare -i NUM_FILES
- NUM_FILES=1
- if [ -n "${2}" ]; then
- NUM_FILES="${2}"
- fi
- declare -i DELAY_DAYS
- DELAY_DAYS=30
- if [ -n "${3}" ]; then
- DELAY_DAYS="${3}"
- fi
- # Usage checks
- if [ -z "${SUB_DIR}" ] || [ $NUM_FILES -lt 1 ] || [ $DELAY_DAYS -lt 1 ]; then
- echo "Usage: `basename "${0}"` sub_directory [num_files] [delay_days]" 1>&2
- exit 1
- fi
- # Allow usage with absolute local paths
- if [ "`echo "${SUB_DIR}" | head -c 1`" == '/' ]; then
- BASE_LOCAL="`dirname "${SUB_DIR}"`"
- SUB_DIR="`basename "${SUB_DIR}"`"
- fi
- # Sanity checks
- if [ ! -d "${BASE_LOCAL}/${SUB_DIR}" ]; then
- echo "Invalid local directory: ${BASE_LOCAL}/${SUB_DIR}" 1>&2
- exit 1
- fi
- if [ ! -d "${BASE_REMOTE}" ]; then
- echo "Remote drive not mounted" 1>&2
- exit 1
- fi
- # Ensure we can actually write to the remote drive
- WC="${BASE_REMOTE}/.write_check"
- touch "${WC}" >/dev/null 2>&1
- if [ ! -e "${WC}" ]; then
- echo "Remote drive not writable" 1>&2
- exit 1
- fi
- rm -f "${WC}" >/dev/null 2>&1
- if [ -e "${WC}" ]; then
- echo "Remote drive not writable" 1>&2
- exit 1
- fi
- # Create the named subdirectory if it does not exist on the remote drive
- if [ ! -d "${BASE_REMOTE}/${SUB_DIR}" ]; then
- mkdir -p "${BASE_REMOTE}/${SUB_DIR}"
- fi
- # Grab and sort the local file list
- # Limit files by mtime, but include all directories
- TMP_LOCAL="`mktemp -t sync.local.XXXXXXXX`"
- TMP_LOCAL2="`mktemp -t sync.local2.XXXXXXXX`"
- (cd "${BASE_LOCAL}" && find "${SUB_DIR}" -type f -mtime "+${DELAY_DAYS}d" > "${TMP_LOCAL2}")
- (cd "${BASE_LOCAL}" && find "${SUB_DIR}" -type d >> "${TMP_LOCAL2}")
- cat "${TMP_LOCAL2}" | sort > "${TMP_LOCAL}"
- # Grab and sort the remote file list
- TMP_REMOTE="`mktemp -t sync.remote.XXXXXXXX`"
- (cd "${BASE_REMOTE}" && find "${SUB_DIR}" | sort > "${TMP_REMOTE}")
- # Diff to find the first mis-matched file, then drop out temp files
- TMP_DIFF="`mktemp -t sync.diff.XXXXXXXX`"
- TMP_DIFF2="`mktemp -t sync.diff2.XXXXXXXX`"
- diff -u "${TMP_LOCAL}" "${TMP_REMOTE}" | grep "^[\+\-]${SUB_DIR}" > "${TMP_DIFF2}"
- rm -f "${TMP_LOCAL}" "${TMP_LOCAL2}" "${TMP_REMOTE}"
- # Filter junk
- grep -v '\/\._' "${TMP_DIFF2}" | grep -v '\/\.DS_Store$' | grep -v '\/\.git\/' > "${TMP_DIFF}"
- rm -f "${TMP_DIFF2}"
- # Limit NUM_FILES to the number of files available
- COUNT="`cat "${TMP_DIFF}" | wc -l`"
- if [ $NUM_FILES -gt $COUNT ]; then
- NUM_FILES=$COUNT
- fi
- # Loop for NUM_FILES
- for (( i=1; i<=${NUM_FILES}; i++ )); do
- # Choose the file/directory to sync
- FILE="`head -n $i "${TMP_DIFF}" | tail -n 1`"
- ACTION="`echo "${FILE}" | head -c 1`"
- FILE="`echo "${FILE}" | cut -d "${ACTION}" -f 2-`"
- # Construct absolute paths
- PATH_LOCAL="${BASE_LOCAL}/${FILE}"
- PATH_REMOTE="${BASE_REMOTE}/${FILE}"
- # Determine the action (i.e. copy to or delete from remote)
- if [ "${ACTION}" == '+' ]; then
- if [ -d "${PATH_REMOTE}" ]; then
- echo "Removing directory: ${FILE}"
- rmdir "${PATH_REMOTE}"
- elif [ -f "${PATH_REMOTE}" ]; then
- echo "Deleting file: ${FILE}"
- rm "${PATH_REMOTE}"
- else
- echo "Unable to delete file: ${FILE}" 1>&2
- exit 2
- fi
- elif [ "${ACTION}" == '-' ]; then
- # Handle files by type
- if [ -h "${PATH_LOCAL}" ]; then
- echo "Unable to create symlink: ${FILE}" 1>&2
- exit 2
- elif [ -d "${PATH_LOCAL}" ]; then
- echo "Creating directory: ${FILE}"
- mkdir "${PATH_REMOTE}"
- elif [ -f "${PATH_LOCAL}" ] && [ -r "${PATH_LOCAL}" ]; then
- echo "Copying: ${FILE}"
- cp "${BASE_LOCAL}/${FILE}" "${BASE_REMOTE}/${FILE}"
- else
- echo "Unable to copy file: ${FILE}" 1>&2
- exit 2
- fi
- else
- echo "Invalid action: ${ACTION}" 1>&2
- exit 2
- fi
- done
- # Cleanup
- rm -f "${TMP_DIFF}"
- exit 0
|