aboutsummaryrefslogtreecommitdiff
path: root/share/hydractl/sync-media
diff options
context:
space:
mode:
Diffstat (limited to 'share/hydractl/sync-media')
-rwxr-xr-xshare/hydractl/sync-media130
1 files changed, 124 insertions, 6 deletions
diff --git a/share/hydractl/sync-media b/share/hydractl/sync-media
index 8132315..2373413 100755
--- a/share/hydractl/sync-media
+++ b/share/hydractl/sync-media
@@ -17,6 +17,7 @@ CACHE="/var/cache/$HOST/media"
MEDIA="media.$DOMAIN"
INCOMING="$CACHE/incoming"
WHOAMI="`whoami`"
+LOCK=".sync-media.lock"
OPTIONS="$*"
# Dependencies
@@ -24,6 +25,66 @@ hydra_install_package rsync
hydra_install_package unison
hydra_install_package git-annex
+# Fatal error
+# Adapted from borger
+function fatal {
+ info [fatal] $*
+ exit 1;
+}
+
+# Create lockfile
+# Adapted from borger
+function sync_media_set_lockfile {
+ if [ ! -z "$LOCKFILE" ]; then
+ mkdir -p `dirname $LOCKFILE`
+
+ if ( set -o noclobber; echo "$$" > "$LOCKFILE" ) &> /dev/null; then
+ trap 'sync_media_unset_lockfile' INT TERM EXIT
+ else
+ fatal "Could not create lockfile $LOCKFILE, exiting"
+ fi
+ fi
+}
+
+# Remove lockfile
+# Adapted from borger
+function sync_media_unset_lockfile {
+ if [ ! -z "$LOCKFILE" ] && [ -e "$LOCKFILE" ]; then
+ git annex unannex $LOCK &> /dev/null
+ git rm -f $LOCKFILE &> /dev/null || \
+ rm -f $LOCKFILE || echo "Could not remove lockfile $LOCKFILE"
+ fi
+}
+
+# Check lockfile
+# Adapted from borger
+function sync_media_check_lockfile {
+ local pid process
+
+ if [ ! -e ".gitignore" ] || ! grep -q "$LOCK" .gitignore; then
+ # With git-ignore from git-extras package
+ #git ignore $LOCK
+
+ # Without git-ignore from git-extras package
+ echo "$LOCK" >> .gitignore
+ fi
+
+ if [ ! -z "$LOCKFILE" ] && [ -f "$LOCKFILE" ]; then
+ pid="`cat $LOCKFILE`"
+ process="`ps --no-headers -o comm $pid`"
+
+ if [ "$?" == "0" ] && [ "`ps --no-headers -o comm $$`" == "$process" ]; then
+ echo "Another program is running for $LOCKFILE, skipping"
+ return 1
+ else
+ echo "Found old lockfile $LOCKFILE, removing it"
+ sync_media_unset_lockfile
+ fi
+
+ return 0
+ fi
+}
+
# Fix identity
function sync_media_identity {
if [ -z "`git config --local user.email`" ] || [ -z "`git config --local user.name`" ]; then
@@ -54,20 +115,42 @@ function sync_media_add {
# Add meta files, making sure they're handled directly by Git
function sync_media_add_metadata {
+ # Metadata state on the annex
+ #
+ # * add: metadata is managed in the annex, normally.
+ # * unlock: managed in the annex, but modifications are tracked as well.
+ # * unannex: metadata is kept out of the annex, but still tracked by Git.
+ #
+ # Usually, they should be regular files trackes by Git, so `git diff`
+ # works as expected.
+ #
+ #metadata_state="add"
+ #metadata_state="unlock"
+ metadata_state="unannex"
+
+ # Gitignore
+ if [ -e ".gitignore" ]; then
+ git annex $metadata_state .gitignore
+ git add .gitignore
+ fi
+
# Playlist files in the playlist folder
if [ -d "playlists" ]; then
- find playlists -name '*.m3u' -type l -exec git annex unlock {} \;
- find playlists -name '*.m3u' -exec git add {} \;
+ find playlists -name '*.m3u' -type l -exec git annex $metadata_state {} \;
+ find playlists -name '*.m3u' -exec git add {} \;
+ find playlists -name '*.m3u8' -type l -exec git annex $metadata_state {} \;
+ find playlists -name '*.m3u8' -exec git add {} \;
fi
# Koreader metadata files
- find -name metadata.pdf.lua -type l -exec git annex unlock {} \;
+ find -name metadata.pdf.lua -type l -exec git annex $metadata_state {} \;
+ find -name metadata.pdf.lua -type l -exec git annex $metadata_state {} \;
find -name metadata.pdf.lua -exec git add {} \;
- find -name metadata.pdf.lua.old -type l -exec git annex unlock {} \;
+ find -name metadata.pdf.lua.old -type l -exec git annex $metadata_state {} \;
find -name metadata.pdf.lua.old -exec git add {} \;
# Darktable sidecar files
- find -name '*.xmp' -type l -not -path '*.git*' -exec git annex unlock {} \;
+ find -name '*.xmp' -type l -not -path '*.git*' -exec git annex $metadata_state {} \;
find -name '*.xmp' -not -path '*.git*' -exec git add {} \;
}
@@ -171,12 +254,16 @@ if echo $OPTIONS | grep -q -- "--dropunused"; then
fi
# Set drive config
-# Ingore drive/volume if it's set to "local"
+# Ignore drive/volume if it's set to "local"
if [ ! -z "$REMOTE" ] && [ "$REMOTE" != "local" ] && [ "$REMOTE" != "localhost" ]; then
# Check storage media
MOUNT="`mount | grep $VOLUME`"
+
if [ ! -z "$MOUNT" ]; then
DRIVE="$(basename `echo $MOUNT | awk '{ print $1 }'`)"
+ #else
+ # echo "$BASENAME: volume $MEDIA is not mounted"
+ # exit 1
fi
fi
@@ -203,6 +290,8 @@ fi
# Iterate over existing repositories in the local cache
for folder in $REPOSITORIES; do
+ LOCKFILE="$CACHE/$folder/$LOCK"
+
# Sync each repository in the local cache
if [ -d "$CACHE/$folder/.git/annex" ]; then
if [ "`git -C $CACHE/$folder config sync-media.skip`" == "true" ]; then
@@ -211,7 +300,16 @@ for folder in $REPOSITORIES; do
(
cd $CACHE/$folder
+ echo ""
echo "Syncing $CACHE/$folder..."
+ echo ""
+
+ # Lockfile handling
+ if ! sync_media_check_lockfile; then
+ continue
+ else
+ sync_media_set_lockfile
+ fi
# Ensure the removable volume is in the list of remotes
sync_media_ensure_remote $REMOTE $VOLUME/$MEDIA/$folder
@@ -244,6 +342,11 @@ for folder in $REPOSITORIES; do
# Repository maintenance
sync_media_fsck
sync_media_dropunused
+ git prune
+ git gc
+
+ # Unset the lockfile
+ sync_media_unset_lockfile
)
fi
@@ -287,6 +390,7 @@ if [ ! -z "$DRIVE" ] && [ -d "$VOLUME/$MEDIA" ]; then
# Iterate over existing repositories in the removable media
for folder in $REPOSITORIES; do
+ LOCKFILE="$VOLUME/$MEDIA/$folder/$LOCK"
# Sync each local repository in the removable media
if [ -d "$VOLUME/$MEDIA/$folder/.git/annex" ]; then
@@ -296,7 +400,16 @@ if [ ! -z "$DRIVE" ] && [ -d "$VOLUME/$MEDIA" ]; then
(
cd $VOLUME/$MEDIA/$folder
+ echo ""
echo "Syncing $VOLUME/$MEDIA/$folder..."
+ echo ""
+
+ # Lockfile handling
+ if ! sync_media_check_lockfile; then
+ continue
+ else
+ sync_media_set_lockfile
+ fi
sync_media_playlist_perms
sync_media_ensure_remote $HOST $CACHE/$folder
@@ -311,7 +424,12 @@ if [ ! -z "$DRIVE" ] && [ -d "$VOLUME/$MEDIA" ]; then
sync_media_getall $VOLUME/$MEDIA/$folder
sync_media_fsck
sync_media_dropunused
+ git gc
+ git prune
#git annex drop --auto --numcopies=2
+
+ # Unset the lockfile
+ sync_media_unset_lockfile
)
elif [ -d "$CACHE/$folder" ] && [ ! -d "$CACHE/$folder/.git" ]; then
# Avoid those configured to be skipped