2024-08-22 12:13:38 +00:00
|
|
|
#!/bin/bash -
|
|
|
|
#===============================================================================
|
|
|
|
#
|
|
|
|
# FILE: recover_transcripts
|
|
|
|
#
|
|
|
|
# USAGE: ./recover_transcripts item
|
|
|
|
#
|
|
|
|
# DESCRIPTION: Intended to be run on `borg`; collects assets from the
|
|
|
|
# locally-mounted backup disk and places them in a local
|
|
|
|
# directory (organised to be compatible with the IA), then
|
|
|
|
# uploads anything that is missing on the IA.
|
|
|
|
#
|
|
|
|
# Version 0.1.* looks for assets in the 'eps/' directory and
|
|
|
|
# copies them to the cache. Also moves the IA copies so all is
|
|
|
|
# aligned. Many shows earlier than mid 2019 are likely to need
|
|
|
|
# this addition.
|
|
|
|
#
|
|
|
|
# OPTIONS: ---
|
|
|
|
# REQUIREMENTS: ---
|
|
|
|
# BUGS: ---
|
|
|
|
# NOTES: ---
|
|
|
|
# AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com
|
|
|
|
# VERSION: 0.1.4
|
|
|
|
# CREATED: 2024-07-14 13:22:58
|
|
|
|
# REVISION: 2024-08-20 17:38:19
|
|
|
|
#
|
|
|
|
#===============================================================================
|
|
|
|
|
|
|
|
# set -o nounset # Treat unset variables as an error
|
|
|
|
|
|
|
|
VERSION="0.1.4"
|
|
|
|
|
|
|
|
SCRIPT=${0##*/}
|
|
|
|
# DIR=${0%/*}
|
|
|
|
|
|
|
|
STDOUT="/dev/fd/2"
|
|
|
|
|
|
|
|
#
|
|
|
|
# Select the appropriate working directory for the host
|
|
|
|
#
|
|
|
|
case $(hostname) in
|
|
|
|
i7-desktop)
|
|
|
|
echo "To be run only on 'borg'"
|
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
borg)
|
|
|
|
BASEDIR="$HOME/IA"
|
|
|
|
REPAIRS="$BASEDIR/repairs"
|
|
|
|
BACKUP="/mnt/backup_disk/HPR/HPR-MIRROR"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "Wrong host!"
|
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
cd "$BASEDIR" || { echo "Failed to cd to $BASEDIR"; exit 1; }
|
|
|
|
|
|
|
|
#
|
|
|
|
# Load library functions
|
|
|
|
#
|
|
|
|
LIB="$HOME/bin/function_lib.sh"
|
|
|
|
[ -e "$LIB" ] || { echo "Unable to source functions"; exit; }
|
|
|
|
# shellcheck disable=SC1090
|
|
|
|
source "$LIB"
|
|
|
|
|
|
|
|
#
|
|
|
|
# Enable coloured messages
|
|
|
|
#
|
|
|
|
define_colours
|
|
|
|
|
|
|
|
#
|
|
|
|
# Sanity checks
|
|
|
|
#
|
|
|
|
JQ=$(command -v jq)
|
|
|
|
[ -n "$JQ" ] || { echo "Program 'jq' was not found"; exit 1; }
|
|
|
|
IA=$(command -v ia)
|
|
|
|
[ -n "$IA" ] || { echo "Program 'ia' was not found"; exit 1; }
|
|
|
|
REPIT="$BASEDIR/repair_item"
|
|
|
|
[ -e "$REPIT" ] || { echo "Program '$REPIT' was not found"; exit 1; }
|
|
|
|
IADB="$BASEDIR/ia.db"
|
|
|
|
[ -e "$IADB" ] || { echo "Database '$IADB' was not found"; exit 1; }
|
|
|
|
|
|
|
|
# {{{ -- Functions -- _IA_move, queued_tasks, _verbose, _usage
|
|
|
|
|
|
|
|
|
|
|
|
#=== FUNCTION ================================================================
|
|
|
|
# NAME: _IA_move
|
|
|
|
# DESCRIPTION: Performs a file move on the IA, with retries if it fails.
|
|
|
|
# Assumes the existence of functions 'coloured', '_log',
|
|
|
|
# '_verbose' and '_DEBUG'
|
|
|
|
# PARAMETERS: $1 IA command to run (as a string)
|
|
|
|
# $2 The path to move from
|
|
|
|
# $3 The path to move to
|
|
|
|
# RETURNS: False if the number of retries is exceeded, otherwise true.
|
|
|
|
#===============================================================================
|
|
|
|
_IA_move () {
|
|
|
|
local from="${1:?Usage _IA_move command from to}"
|
|
|
|
local to="${2:?Usage _IA_move command from to}"
|
|
|
|
|
|
|
|
local retry_threshold=5
|
|
|
|
local retries=0
|
|
|
|
local sleeptime=20
|
|
|
|
local command="ia move \"$from\" \"$to\" --no-derive --no-backup > /dev/null 2>&1"
|
|
|
|
_DEBUG "$command"
|
|
|
|
|
|
|
|
# coloured 'blue' "Moving $from to $to"
|
|
|
|
|
|
|
|
#
|
|
|
|
# Run 'command'. If it succeeds then exit. If it fails enter the 'until'
|
|
|
|
# loop and report the problem, then sleep and try again. Count the number
|
|
|
|
# of times this is done, so it doesn't loop forever. If we have reached
|
|
|
|
# the limit count this as a failure and exit with an error. If we haven't
|
|
|
|
# retried enough yet, sleep for a while and try again. The intention is to
|
|
|
|
# catch the case when an upload times out. The 'ia' command is performing
|
|
|
|
# its own retries per upload when the system is overloaded, but these are
|
|
|
|
# non-fatal.
|
|
|
|
#
|
|
|
|
until eval "$command"; do
|
|
|
|
coloured 'red' "Failure when moving $from to $to"
|
|
|
|
((retries++))
|
|
|
|
|
|
|
|
_log "$(printf 'Failed to move %s to %s [%d]' "$from" "$to" $retries)"
|
|
|
|
|
|
|
|
[ "$retries" -eq "$retry_threshold" ] && {
|
|
|
|
_verbose \
|
|
|
|
"$(coloured 'red' "Retry limit reached; abandoning this move")"
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
_verbose "$(coloured 'blue' "Pausing for $sleeptime seconds and retrying")"
|
|
|
|
sleep $sleeptime
|
|
|
|
done # until eval ...
|
|
|
|
|
|
|
|
coloured 'green' "Moved $from to $to on the IA"
|
|
|
|
_log "Moved $from to $to on the IA"
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
#=== FUNCTION ================================================================
|
|
|
|
# NAME: queued_tasks
|
|
|
|
# DESCRIPTION: Queries the IA for any queued or running tasks for an item.
|
|
|
|
# Writes the number to STDOUT so it can be captured.
|
|
|
|
# PARAMETERS: $1 IA item (like hpr1192)
|
|
|
|
# RETURNS: Nothing
|
|
|
|
#===============================================================================
|
|
|
|
queued_tasks () {
|
|
|
|
local item="${1:?Usage: queued_tasks item}"
|
|
|
|
local -i count=0
|
|
|
|
|
|
|
|
count="$(ia tasks "$item" |\
|
|
|
|
jq -s '[.[] | if .category == "catalog" then .status else empty end] | length')"
|
|
|
|
|
|
|
|
echo "$count"
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
#=== FUNCTION ================================================================
|
|
|
|
# NAME: make_dir
|
|
|
|
# DESCRIPTION: Make a directory if it doesn't exist, failing gracefully on
|
|
|
|
# errors.
|
|
|
|
# PARAMETERS: $1 directory path
|
|
|
|
# RETURNS: True if success, otherwise exits the caller script
|
|
|
|
#===============================================================================
|
|
|
|
make_dir () {
|
|
|
|
local dir="${1}"
|
|
|
|
|
|
|
|
if [[ ! -d $dir ]]; then
|
|
|
|
mkdir -p "$dir" || {
|
|
|
|
coloured 'red' "Failed to create $dir"
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
#=== FUNCTION ================================================================
|
|
|
|
# NAME: _ifbool
|
|
|
|
# DESCRIPTION: Simplifies conditional expressions when they nned to return
|
|
|
|
# one of two strings. Use as:
|
|
|
|
# echo "Hello $(_ifbool 1 'World' 'Everyone')" → "Hello World"
|
|
|
|
# PARAMETERS: $1 Integer being tested. If 1 then it's true, otherwise
|
|
|
|
# it's false. Non-numeric is treated as 0/false.
|
|
|
|
# $2 String returned for True
|
|
|
|
# $3 String returned for False
|
|
|
|
# RETURNS: Nothing
|
|
|
|
#===============================================================================
|
|
|
|
_ifbool () {
|
|
|
|
local -i _bool="${1:-0}"
|
|
|
|
local _t="${2:-true}"
|
|
|
|
local _f="${3:-false}"
|
|
|
|
|
|
|
|
if [ "$_bool" -eq 1 ]; then
|
|
|
|
echo "$_t"
|
|
|
|
else
|
|
|
|
echo "$_f"
|
|
|
|
fi
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
#=== FUNCTION ================================================================
|
|
|
|
# NAME: _log
|
|
|
|
# DESCRIPTION: Appends a record to the file "$LOGFILE"
|
|
|
|
# PARAMETERS: $1 Message to write
|
|
|
|
# RETURNS: Nothing
|
|
|
|
#===============================================================================
|
|
|
|
_log () {
|
|
|
|
local message="${1}"
|
|
|
|
|
|
|
|
echo "$(date +%F\ %T) $message" >> "$LOGFILE"
|
|
|
|
}
|
|
|
|
|
|
|
|
#=== FUNCTION ================================================================
|
|
|
|
# NAME: _verbose
|
|
|
|
# DESCRIPTION: Writes a message in verbose mode
|
|
|
|
# PARAMETERS: * message strings to write
|
|
|
|
# RETURNS: Nothing
|
|
|
|
#===============================================================================
|
|
|
|
_verbose () {
|
|
|
|
[ "$VERBOSE" -eq 0 ] && return
|
|
|
|
for msg; do
|
|
|
|
printf '%s\n' "$msg"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
#=== FUNCTION ================================================================
|
|
|
|
# NAME: _usage
|
|
|
|
# DESCRIPTION: Reports usage; always exits the script after doing so
|
|
|
|
# PARAMETERS: 1 - the integer to pass to the 'exit' command
|
|
|
|
# RETURNS: Nothing
|
|
|
|
#===============================================================================
|
|
|
|
_usage () {
|
|
|
|
local -i result=${1:-0}
|
|
|
|
|
|
|
|
cat >$STDOUT <<-endusage
|
|
|
|
${SCRIPT} - version: ${VERSION}
|
|
|
|
|
|
|
|
Usage: ./${SCRIPT} [-h] [-D] [-F] [-v] item
|
|
|
|
|
|
|
|
Attempts to repair an IA item where the upload has failed for some reason.
|
|
|
|
|
|
|
|
Options:
|
|
|
|
-h Print this help.
|
|
|
|
-d 0|1 Dry run: -d 1 (the default) runs the script in dry-run
|
|
|
|
mode where nothing is changed but the actions that
|
|
|
|
will be taken are reported; -d 0 turns off dry-run
|
|
|
|
mode and the actions will be carried out.
|
|
|
|
-D Run in debug mode where a lot more information is
|
|
|
|
reported.
|
|
|
|
-F Ignore (some) interlocks that will cause failure, such
|
|
|
|
as the existence of the local cache directory for the
|
|
|
|
item being processed.
|
|
|
|
-v Run in verbose mode where more information is
|
|
|
|
reported. Default is off.
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
item The item in the form 'hpr1234'
|
|
|
|
|
|
|
|
endusage
|
|
|
|
exit "$result"
|
|
|
|
}
|
|
|
|
|
|
|
|
# }}}
|
|
|
|
|
|
|
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Directories and files
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
LOGS="$BASEDIR/logs"
|
|
|
|
make_dir "${LOGS}"
|
|
|
|
LOGFILE="$LOGS/$SCRIPT.log"
|
|
|
|
|
|
|
|
while getopts :d:DFhv opt
|
|
|
|
do
|
|
|
|
case "${opt}" in
|
|
|
|
D) DEBUG=1;;
|
|
|
|
d) DRYRUN=$OPTARG;;
|
|
|
|
F) FORCE=1;;
|
|
|
|
h) _usage 0;;
|
|
|
|
v) VERBOSE=1;;
|
|
|
|
*) echo "** Unknown option"
|
|
|
|
_usage 1;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
shift $((OPTIND - 1))
|
|
|
|
|
|
|
|
#
|
|
|
|
# Set option defaults and check their values
|
|
|
|
#
|
|
|
|
DRYRUN=${DRYRUN:-1}
|
|
|
|
if [[ $DRYRUN -ne 0 && $DRYRUN -ne 1 ]]; then
|
|
|
|
echo "** Use '-d 0' or '-d 1'"
|
|
|
|
_usage 1
|
|
|
|
fi
|
|
|
|
[[ $DRYRUN -eq 1 ]] && echo "Dry run mode"
|
|
|
|
|
|
|
|
DEBUG=${DEBUG:-0}
|
|
|
|
[[ $DEBUG -eq 1 ]] && coloured 'yellow' "Debug mode"
|
|
|
|
|
|
|
|
FORCE=${FORCE:-0}
|
|
|
|
|
|
|
|
VERBOSE=${VERBOSE:-0}
|
|
|
|
|
|
|
|
#
|
|
|
|
# Should have one argument
|
|
|
|
#
|
2024-11-23 22:28:52 +00:00
|
|
|
if [[ $# -ne 1 ]]; then
|
2024-08-22 12:13:38 +00:00
|
|
|
coloured 'red' "Missing argument"
|
|
|
|
_usage 1
|
|
|
|
fi
|
|
|
|
item="${1}"
|
|
|
|
|
|
|
|
#
|
|
|
|
# Ensure item spec is correctly formatted
|
|
|
|
#
|
|
|
|
if [[ $item =~ hpr([0-9]+) ]]; then
|
|
|
|
printf -v item 'hpr%04d' "$((10#${BASH_REMATCH[1]}))"
|
|
|
|
else
|
|
|
|
coloured 'red' "Incorrect show specification: $item"
|
|
|
|
coloured 'yellow' "Use 'hpr9999' format"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
_DEBUG "Parsed item: $item"
|
|
|
|
|
|
|
|
_log "$SCRIPT $VERSION ($(_ifbool "$DRYRUN" 'dry-run' 'live'))"
|
|
|
|
|
|
|
|
#
|
|
|
|
# Having an entry for the show in 'ia.db' is important, so check there is one
|
|
|
|
#
|
|
|
|
SQL="select 1 from episodes where id = ${item:3}"
|
|
|
|
if [[ $(sqlite3 -list "$IADB" "$SQL" 2>/dev/null) -ne 1 ]]; then
|
|
|
|
coloured 'red' "Unable to find show $item in the local IA database"
|
|
|
|
coloured 'yellow' "Can't continue"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
_verbose "$(coloured 'yellow' "Show $item is in the local IA database")"
|
|
|
|
_log "Show $item is in the local IA database"
|
|
|
|
|
|
|
|
#
|
|
|
|
# It's possible that the show upload failed before anything was uploaded, even
|
|
|
|
# the metadata. It's never been seen, but it seems wise to cater for it.
|
|
|
|
#
|
|
|
|
# TODO: uncomment below; disabled for speed
|
|
|
|
if ! ia metadata "$item" --exists > /dev/null 2>&1; then
|
|
|
|
coloured 'red' "This item is not apparently on the IA; can't continue"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
_verbose "$(coloured 'yellow' "Show $item is on the IA")"
|
|
|
|
_log "Show $item is on the IA"
|
|
|
|
|
|
|
|
#
|
|
|
|
# Directory paths
|
|
|
|
#
|
|
|
|
FROMPARENTDIR="$BACKUP/public_html/eps"
|
|
|
|
FROMDIR="$FROMPARENTDIR/$item"
|
|
|
|
TOPARENTDIR="$REPAIRS/$item"
|
|
|
|
TOASSETDIR="$TOPARENTDIR/$item"
|
|
|
|
|
|
|
|
#
|
|
|
|
# RE to ignore certain files using 'grep -v -E ...'
|
|
|
|
#
|
|
|
|
IGNORE="($item\.(flac|mp3|ogg|opus|spx|wav)$)"
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Check there are asset files on the backup disk before proceeding. At least
|
|
|
|
# we need the transcripts. If no files at all we can't continue.
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
declare -a BACKUPFILES
|
|
|
|
mapfile -t BACKUPFILES < \
|
|
|
|
<(find "$FROMPARENTDIR" -type f -name "$item*" | grep -v -E "${IGNORE}")
|
|
|
|
_DEBUG "$(coloured 'purple' "Backup files")" "${BACKUPFILES[@]}"
|
|
|
|
|
|
|
|
if [[ ! -d $FROMDIR || ${#BACKUPFILES[@]} -eq 0 ]]; then
|
|
|
|
coloured 'red' "No files found in $FROMDIR"
|
|
|
|
coloured 'red' "Can't continue!"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
_log "Files found on backup disk ${#BACKUPFILES[*]}"
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Make the needed local cache directory for later
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
if [[ $FORCE -ne 1 && -e $TOPARENTDIR ]]; then
|
|
|
|
coloured 'red' "Directory $TOPARENTDIR already exists; can't continue".
|
|
|
|
coloured 'yellow' 'This implies that all files have been copied already.'
|
|
|
|
coloured 'yellow' "If you're sure, consider running: '$REPIT -X -d0 $item'"
|
|
|
|
coloured 'yellow' 'Otherwise, consider running again with option -F.'
|
|
|
|
exit 1
|
|
|
|
else
|
|
|
|
if [[ $DRYRUN -eq 1 ]]; then
|
|
|
|
coloured 'yellow' "Would have created directory $TOPARENTDIR"
|
|
|
|
else
|
|
|
|
mkdir -p "$TOASSETDIR"
|
|
|
|
_verbose "$(coloured 'yellow' "Created directory $TOASSETDIR")"
|
|
|
|
_log "Created directory $TOASSETDIR"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Collect asset data from the database
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
SQL="select filename from assets where episode_id = ${item:3}"
|
|
|
|
declare -a IADBASSETS
|
|
|
|
mapfile -t IADBASSETS < <(sqlite3 -list "$IADB" "$SQL" 2>/dev/null)
|
|
|
|
_DEBUG "$(coloured 'purple' "SQLite IA DB files")" "${IADBASSETS[@]}"
|
|
|
|
_log "Files found in ia.db ${#IADBASSETS[*]}"
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Collect IA data, only original files generated by HPR. We exclude audio
|
|
|
|
# files from this set.
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
JQPROG='.files[] | select(.source == "original" and .format != "Metadata" and '
|
|
|
|
JQPROG+='.format != "Item Tile") | (.name) | @text'
|
|
|
|
declare -a IAFILES
|
|
|
|
mapfile -t IAFILES < \
|
|
|
|
<(ia metadata "$item" | $JQ -r "$JQPROG" | grep -v -E "${IGNORE}")
|
|
|
|
_DEBUG "$(coloured 'purple' "IA files (originals)")" "${IAFILES[@]}"
|
|
|
|
_log "Files found on IA (originals) ${#IAFILES[*]}"
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Work out whether to copy assets from the backup disk, or whether to move
|
|
|
|
# files on the IA. Whatever we decide we also need to copy transcripts from
|
|
|
|
# the backup disk and upload to the IA
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
#
|
|
|
|
# Check each asset from the $IADB database to see if it's on the IA. We'll get back
|
|
|
|
# a path if it's where we want it, otherwise just a filename.
|
|
|
|
#
|
|
|
|
declare -a MOVES
|
|
|
|
|
|
|
|
coloured 'purple' "Checking IA files for moves"
|
|
|
|
|
|
|
|
#
|
|
|
|
# If we find an asset by looking for its basename in the list of files we got
|
|
|
|
# from the IA and if they are the same we need to move such files to the
|
|
|
|
# sub-directory.
|
|
|
|
#
|
|
|
|
for asset in "${IAFILES[@]}"; do
|
|
|
|
#
|
|
|
|
# Skip IA files with directories
|
|
|
|
#
|
|
|
|
if [[ $asset =~ / ]]; then
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
|
|
|
IA_match=$( grep "${asset}" <(printf '%s\n' "${IADBASSETS[@]}") )
|
|
|
|
if [[ $IA_match = "$asset" ]]; then
|
|
|
|
MOVES+=("$IA_match")
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
#
|
|
|
|
# If we found any moves then we can move them in the IA item now and copy the
|
|
|
|
# files from the backup disk to the cache in case we need them. They will
|
|
|
|
# eventually get deleted by 'cron'.
|
|
|
|
#
|
|
|
|
if [[ ${#MOVES[@]} -gt 0 ]]; then
|
|
|
|
_DEBUG "$(coloured 'purple' "Files to be moved")" "${MOVES[@]}" "----"
|
|
|
|
|
|
|
|
mcount=0
|
|
|
|
for asset in "${MOVES[@]}"; do
|
|
|
|
# source & destination for IA moves
|
|
|
|
iafrom="$item/$asset"
|
|
|
|
iato="$item/$item/$asset"
|
|
|
|
_DEBUG "\$iafrom: $iafrom" "\$iato: $iato" ""
|
|
|
|
|
|
|
|
#
|
|
|
|
# If IA source and destination are the same no moves are needed. For
|
|
|
|
# the local cache the later 'rsync' will be enough.
|
|
|
|
#
|
|
|
|
if [[ $iafrom != "$iato" ]]; then
|
|
|
|
if [[ $DRYRUN -eq 1 ]]; then
|
|
|
|
coloured 'yellow' "ia move $iafrom $iato --no-derive --no-backup"
|
|
|
|
coloured 'yellow' "cp $FROMPARENTDIR/$asset $TOASSETDIR/"
|
|
|
|
else
|
|
|
|
#
|
|
|
|
# Perform the move. If the retries are exceeded things get
|
|
|
|
# complicated, so just abort so we can try again later.
|
|
|
|
#
|
|
|
|
_verbose "$(coloured 'blue' "Moving $iafrom → $iato on IA")"
|
|
|
|
if _IA_move "$iafrom" "$iato"; then
|
|
|
|
#
|
|
|
|
# Update the cache (but only if the move occurred)
|
|
|
|
#
|
|
|
|
_verbose "$(coloured 'blue' "Copying from backup disk to cache")"
|
|
|
|
cp "$FROMPARENTDIR/$asset" "$TOASSETDIR/"
|
|
|
|
|
|
|
|
((mcount++))
|
|
|
|
else
|
|
|
|
coloured 'red' "Retries exhausted. Aborting recovery"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
done
|
|
|
|
#
|
|
|
|
# Report what was done
|
|
|
|
#
|
|
|
|
coloured 'green' "Moved $mcount $(ngettext file files "$mcount")"
|
|
|
|
_log "Moved $mcount $(ngettext file files "$mcount")"
|
|
|
|
|
|
|
|
else
|
|
|
|
coloured 'yellow' "No moves needed"
|
|
|
|
_log "No moves needed"
|
|
|
|
fi
|
|
|
|
|
|
|
|
#
|
|
|
|
# Wait for the IA moves to finish
|
|
|
|
#
|
|
|
|
if [[ $DRYRUN -eq 0 ]]; then
|
|
|
|
if [[ $mcount -gt 0 ]]; then
|
|
|
|
until [[ $(queued_tasks "$item") -eq 0 ]]; do
|
|
|
|
coloured 'yellow' "Waiting for IA tasks to complete"
|
|
|
|
sleep 1m
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
if [[ $mcount -gt 0 ]]; then
|
|
|
|
coloured 'yellow' "Would have waited for any IA tasks to complete"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Copy files from the backup disk to the cache
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
if [[ $DRYRUN -eq 1 ]]; then
|
|
|
|
coloured 'yellow' "Would have copied files from backup disk → cache"
|
|
|
|
rsync -n -vaP --exclude=index.html "$FROMDIR" "$TOPARENTDIR"
|
|
|
|
else
|
|
|
|
rsync -vaP --exclude=index.html "$FROMDIR" "$TOPARENTDIR"
|
|
|
|
_verbose "$(coloured 'yellow' "Copied files from $FROMDIR")"
|
|
|
|
_log "Copied files from $FROMDIR"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# TODO: Is this needed?
|
|
|
|
#
|
|
|
|
# Put any source audio in the right place.
|
|
|
|
#
|
|
|
|
# if [[ $DRYRUN -eq 1 ]]; then
|
|
|
|
# coloured 'yellow' "Would have moved source files if found"
|
|
|
|
# else
|
|
|
|
# #
|
|
|
|
# # Turn on 'nullglob' to get an empty result if the glob expression doesn't
|
|
|
|
# # match.
|
|
|
|
# #
|
|
|
|
# NG=$(shopt -p nullglob)
|
|
|
|
# shopt -s nullglob
|
|
|
|
#
|
|
|
|
# #
|
|
|
|
# # Any source files should be in repairs/hpr1234/ and should go to the IA
|
|
|
|
# # in the comparable place. We will not put it on the HPR server though.
|
|
|
|
# #
|
|
|
|
# # TODO: Is this right?
|
|
|
|
# movecount=0
|
|
|
|
# for file in "$TOPARENTDIR"/*_source.*; do
|
|
|
|
# if mv "$file" "$TOPARENTDIR"; then
|
|
|
|
# ((movecount++))
|
|
|
|
# fi
|
|
|
|
# done
|
|
|
|
#
|
|
|
|
# eval "$NG"
|
|
|
|
#
|
|
|
|
# #
|
|
|
|
# # Show the directories after any move
|
|
|
|
# #
|
|
|
|
# if [[ $movecount -gt 0 ]]; then
|
|
|
|
# _verbose "$(coloured 'yellow' "Moved source file(s)")"
|
|
|
|
# ls -lR "$REPAIRS/$item/"
|
|
|
|
# fi
|
|
|
|
#
|
|
|
|
# fi
|
|
|
|
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Using the cache as the reference upload whatever is missing to the IA
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
if [[ $DRYRUN -eq 1 ]]; then
|
|
|
|
coloured 'yellow' "Would have found and repaired missing files"
|
|
|
|
else
|
|
|
|
_verbose "$(coloured 'yellow' "Finding and repairing missing files")"
|
|
|
|
_log "Finding and repairing missing files (with $REPIT)"
|
|
|
|
"$REPIT" -X -d0 "$item"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# vim: syntax=sh:ts=8:sw=4:ai:et:tw=78:fo=tcrqn21:fdm=marker
|
|
|
|
|