mirror of https://github.com/vitalif/grive2
126 lines
3.6 KiB
Bash
Executable File
126 lines
3.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Copyright (C) 2009 Przemyslaw Pawelczyk <przemoc@gmail.com>
|
|
# (C) 2017 Jan Schulz <jasc@gmx.net>
|
|
##
|
|
## This script is licensed under the terms of the MIT license.
|
|
## https://opensource.org/licenses/MIT
|
|
|
|
# Fail on all errors
|
|
set -o pipefail
|
|
|
|
# We always start in the current users home directory so that names always start there
|
|
cd ~
|
|
|
|
|
|
### ARGUMENT PARSING ###
|
|
SCRIPT="${0}"
|
|
DIRECTORY=$(systemd-escape --unescape "$2")
|
|
|
|
if [[ -z "$DIRECTORY" ]] || [[ ! -d "$DIRECTORY" ]] ; then
|
|
echo "Need a directory name in the current users home directory as second argument. Aborting."
|
|
exit 1
|
|
fi
|
|
|
|
|
|
if [[ -z "${1}" ]] ; then
|
|
echo "Need a command as first argument. Aborting."
|
|
exit 1
|
|
else
|
|
if [[ "sync" == "${1}" ]] ; then
|
|
COMMAND=sync
|
|
elif [[ "listen" == "${1}" ]] ; then
|
|
COMMAND=listen
|
|
else
|
|
echo "Unknown command. Aborting."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
|
|
### LOCKFILE BOILERPLATE ###
|
|
LOCKFILE="/run/user/"$(id -u)"/"$(basename "$0")"_"${DIRECTORY//\//_}""
|
|
LOCKFD=99
|
|
|
|
# PRIVATE
|
|
_lock() { flock -"$1" "$LOCKFD"; }
|
|
_no_more_locking() { _lock u; _lock xn && rm -f "$LOCKFILE"; }
|
|
_prepare_locking() { eval "exec "$LOCKFD">\""$LOCKFILE"\""; trap _no_more_locking EXIT; }
|
|
|
|
# ON START
|
|
_prepare_locking
|
|
|
|
# PUBLIC
|
|
exlock_now() { _lock xn; } # obtain an exclusive lock immediately or fail
|
|
exlock() { _lock x; } # obtain an exclusive lock
|
|
shlock() { _lock s; } # obtain a shared lock
|
|
unlock() { _lock u; } # drop a lock
|
|
|
|
### SYNC SCRIPT ###
|
|
# Idea: only let one script run, but if the sync script is called a second time
|
|
# make sure we sync a second time, too
|
|
|
|
sync_directory() {
|
|
_directory="${1}"
|
|
if ping -c1 -W1 -q accounts.google.com >/dev/null 2>&1; then
|
|
true
|
|
# pass
|
|
else
|
|
echo "Google drive server not reachable..."
|
|
exit 0
|
|
fi
|
|
|
|
reset_timer_and_exit() { echo "Retriggered google drive sync" && touch -m "$LOCKFILE" && exit; }
|
|
|
|
exlock_now || reset_timer_and_exit
|
|
|
|
TIME_AT_START=0
|
|
TIME_AT_END=1
|
|
while [[ "${TIME_AT_START}" -lt "${TIME_AT_END}" ]]; do
|
|
echo "Syncing "${_directory}"..."
|
|
TIME_AT_START="$(stat -c %Y "$LOCKFILE")"
|
|
# exclude symlinks from sync
|
|
cat "${_directory}"/.griveignore 2>/dev/null | sed '/#LINKS-EDIT_BEFORE_THIS$/,$d' > /tmp/.griveignore.base
|
|
cp /tmp/.griveignore.base "${_directory}"/.griveignore
|
|
rm /tmp/.griveignore.base
|
|
echo "#LINKS-EDIT_BEFORE_THIS" >> "${_directory}"/.griveignore
|
|
( cd "${_directory}" && find . -type l | sed 's/^.\///g'; ) >> "${_directory}"/.griveignore
|
|
grive -p "${_directory}" 2>&1 | grep -v -E "^Reading local directories$|^Reading remote server file list$|^Synchronizing files$|^Finished!$"
|
|
TIME_AT_END="$(stat -c %Y "$LOCKFILE")"
|
|
echo "Sync of "${_directory}" done."
|
|
done
|
|
|
|
# always exit ok, so that we never go into a wrong systemd state
|
|
exit 0
|
|
}
|
|
|
|
### LISTEN TO DIRECTORY CHANGES ###
|
|
|
|
|
|
listen_directory() {
|
|
_directory="${1}"
|
|
|
|
type inotifywait >/dev/null 2>&1 || { echo >&2 "I require inotifywait but it's not installed. Aborting."; exit 1; }
|
|
|
|
echo "Listening for changes in ~/"${_directory}""
|
|
|
|
while true #run indefinitely
|
|
do
|
|
# Use a different call to not need to change exit into return
|
|
inotifywait -q -r -e modify,attrib,close_write,move,create,delete --exclude ".grive_state|.grive" "${_directory}" > /dev/null 2>&1 && ${SCRIPT} sync $(systemd-escape "${_directory}")
|
|
#echo ${SCRIPT} "${_directory}"
|
|
done
|
|
|
|
# always exit ok, so that we never go into a wrong systemd state
|
|
exit 0
|
|
}
|
|
|
|
if [[ "${COMMAND}" == listen ]] ; then
|
|
listen_directory "${DIRECTORY}"
|
|
else
|
|
sync_directory "${DIRECTORY}"
|
|
fi
|
|
|
|
# always exit ok, so that we never go into a wrong systemd state
|
|
exit 0
|