#!/bin/bash # script to check for completed torrents and stop and move them # lock dirs/files LOCKDIR="/tmp/statsgen-lock" PIDFILE="${LOCKDIR}/PID" # exit codes and text for them - additional features nobody needs :-) ENO_SUCCESS=0; ETXT[0]="ENO_SUCCESS" ENO_GENERAL=1; ETXT[1]="ENO_GENERAL" ENO_LOCKFAIL=2; ETXT[2]="ENO_LOCKFAIL" ENO_RECVSIG=3; ETXT[3]="ENO_RECVSIG" ### ### start locking attempt ### trap 'ECODE=$?; echo "[statsgen] Exit: ${ETXT[ECODE]}($ECODE)" >&2' 0 echo -n "[statsgen] Locking: " >&2 if mkdir "${LOCKDIR}" &>/dev/null; then # lock succeeded, install signal handlers before storing the PID just in case # storing the PID fails trap 'ECODE=$?; echo "[statsgen] Removing lock. Exit: ${ETXT[ECODE]}($ECODE)" >&2 rm -rf "${LOCKDIR}"' 0 echo "$$" >"${PIDFILE}" # the following handler will exit the script on receiving these signals # the trap on "0" (EXIT) from above will be triggered by this trap's "exit" command! trap 'echo "[statsgen] Killed by a signal." >&2 exit ${ENO_RECVSIG}' 1 2 3 15 echo "success, installed signal handlers" else # lock failed, now check if the other PID is alive OTHERPID="$(cat "${PIDFILE}")" # if cat wasn't able to read the file anymore, another instance probably is # about to remove the lock -- exit, we're *still* locked # Thanks to Grzegorz Wierzowiecki for pointing this race condition out on # http://wiki.grzegorz.wierzowiecki.pl/code:mutex-in-bash if [ $? != 0 ]; then echo "lock failed, PID ${OTHERPID} is active" >&2 exit ${ENO_LOCKFAIL} fi if ! kill -0 $OTHERPID &>/dev/null; then # lock is stale, remove it and restart echo "removing stale lock of nonexistant PID ${OTHERPID}" >&2 rm -rf "${LOCKDIR}" echo "[statsgen] restarting myself" >&2 exec "$0" "$@" else # lock is valid and OTHERPID is active - exit, we're locked! echo "lock failed, PID ${OTHERPID} is active" >&2 exit ${ENO_LOCKFAIL} fi fi BLOCKLIST="/var/lib/transmission/.config/transmission-daemon/blocklists/blocklist.bin" # Update blocklist if older than 1 day if [[ $(find "$BLOCKLIST" -mtime +0 -print) ]]; then transmission-remote --blocklist-update fi TORRENTLIST=$(transmission-remote --list | sed -e '1d;$d;s/^ *//' | cut -f1 -d' ') for TORRENTID in $TORRENTLIST do TORRENTID=$(echo "$TORRENTID" | sed 's:*::') INFO=$(transmission-remote --torrent $TORRENTID --info) NAME=$(echo "$INFO" | grep "Name: *") DL_COMPLETED=$(echo "$INFO" | grep "Percent Done: 100%") STATE_STOPPED=$(echo "$INFO" | grep "State: Stopped\|Finished\|Idle") if [ "$DL_COMPLETED" != "" ] && [ "$STATE_STOPPED" != "" ]; then echo "Removing torrent from list" transmission-remote --torrent $TORRENTID --remove fi done