From dc0f29e9575f8a5591e7b0d4a82eb49aea0cde22 Mon Sep 17 00:00:00 2001 From: Dave Morriss Date: Tue, 16 Jul 2024 21:39:28 +0100 Subject: [PATCH] Updates since 2024-06-15 Database/query2tt2: comment and documentation updates; use of Perl's try/catch. InternetArchive/.make_metadata.cfg: added comments for readability InternetArchive/make_metadata: bug fix needed now that all shows on the HPR server have a directory with assets under it. InternetArchive/repair_assets: new Bash script in development. Collects assets from the IA and uploads them to a new directory on the HPR server. Will run 'fix_asset_links' (to repair asset links for their new directories) once it is ready. InternetArchive/repair_item: Bash script which was originally written to run on 'borg' and upload files to a new IA item when the uploads timed out. Now enhanced to upload missing files recovered from the HPR backup disk, such as transcripts. --- Database/query2tt2 | 40 +- InternetArchive/.make_metadata.cfg | 50 ++- InternetArchive/ia.db | Bin 2162688 -> 2211840 bytes InternetArchive/make_metadata | 31 +- InternetArchive/repair_assets | 627 +++++++++++++++++++++++++++++ InternetArchive/repair_item | 51 ++- 6 files changed, 763 insertions(+), 36 deletions(-) create mode 100755 InternetArchive/repair_assets diff --git a/Database/query2tt2 b/Database/query2tt2 index 75e3704..9847e47 100755 --- a/Database/query2tt2 +++ b/Database/query2tt2 @@ -26,9 +26,9 @@ # BUGS: --- # NOTES: Had to revert to MySQL because of a problem with DBD::MariaDB # AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com -# VERSION: 0.0.4 +# VERSION: 0.0.5 # CREATED: 2021-06-18 13:24:49 -# REVISION: 2024-01-19 17:15:45 +# REVISION: 2024-06-29 18:42:49 # #=============================================================================== @@ -59,7 +59,7 @@ use Data::Dumper; # # Version number (manually incremented) # -our $VERSION = '0.0.4'; +our $VERSION = '0.0.5'; # # Script and directory names @@ -113,7 +113,7 @@ Options( \%options ); # # Default help # -pod2usage( -msg => "Version $VERSION\n", -exitval => 1 ) +pod2usage( -msg => "Version $VERSION\n", -exitval => 1, -verbose => 0 ) if ( $options{'help'} ); # @@ -234,7 +234,7 @@ catch ($e) { print STDERR "Failed to execute query.\n"; print STDERR "Placeholder/Argument mismatch: $pcount/$acount\n"; exit; -}; +} # # Grab everything from the query as an arrayref of hashrefs @@ -325,7 +325,7 @@ sub _dbargs { #=== FUNCTION ================================================================ # NAME: _define -# PURPOSE: Handles multiple instances of the same option '-define x=42' +# PURPOSE: Handles multiple instances of the option '-define x=42' # PARAMETERS: $opts hash reference holding the options # RETURNS: A hash containing all of the named items (e.g. { 'x' => 42 }) # DESCRIPTION: If there are -define options they will be a hashref in the hash @@ -386,12 +386,13 @@ query2tt2 - A script for formatting a report from database query using a templat =head1 VERSION -This documentation refers to query2tt2 version 0.0.4 +This documentation refers to query2tt2 version 0.0.5 =head1 USAGE - query2tt2 [-help] [-debug=N] [-config=FILE] [-query=FILE] - [-template=FILE] [QUERY] + query2tt2 [-help] [-doc] [-debug=N] [-config=FILE] [-query=FILE] + [-template=FILE] [-dbargs=ARG1 [-dbarg=ARG2] ...] + [define KEY1=VALUE [define key2=VALUE2] ...] [QUERY] query2tt2 -help @@ -462,10 +463,10 @@ If neither method is used the script aborts with an error message. =item B<-dbarg=ARG> [ B<-dbarg=ARG> ... ] -The query can have place holders ('?') in it and the corresponding values can -be passed to the script through the B<-dbarg=ARG> option. The option can be -repeated as many times as required and the order of B values is -preserved. +The query can have place holders ('?') in it and the corresponding values for +these placeholders can be passed to the script through the B<-dbarg=ARG> +option. The option can be repeated as many times as required and the order of +B values is preserved. =item B<-template=FILE> @@ -484,8 +485,10 @@ Output from the template is written to STDOUT. The Template Toolkit (TT2) template may receive values from the command line using this option. The argument to the B<-define> option is a B -pair. Keys should be unique otherwise they will overwrite one another. The -keys will become TT2 variables and the values will be assigned to them. +pair. Keys should be unique otherwise they will overwrite one another. They +should also not be 'names' or 'result' because these keys are used internally +(for the data from the database). See below for more details. The keys will +become TT2 variables and the values will be assigned to them. =back @@ -548,12 +551,7 @@ The nominated template file could not be found. An error has occurred while performing a database operation. -=item B - -There is a mismatch between the number of placeholders in the query ('?' -characters) and the number of arguments provided through the B<-dbargs=ARG> -option. The script will attempt to analyse whether there are too many or too -few arguments +=item B There is a mismatch between the number of placeholders in the query ('?' characters) and the number of arguments provided through the B<-dbargs=ARG> diff --git a/InternetArchive/.make_metadata.cfg b/InternetArchive/.make_metadata.cfg index dd4c135..ffacb5f 100644 --- a/InternetArchive/.make_metadata.cfg +++ b/InternetArchive/.make_metadata.cfg @@ -1,16 +1,62 @@ # Version for i7-desktop -# .make_metadata.cfg 2023-07-06 11:54:49 +# .make_metadata.cfg 2024-07-08 13:55:23 +# + +# +# A sanity check value in case an episode number given is too big # max_epno = 9000 + +# +# This is where the script will look for the audio files for upload (if there +# are other "assets" it finds them itself) +# #uploads = "/var/IA/uploads" # on the VPS and marvin uploads = "/home/cendjm/HPR/IA/uploads" + +# +# How a "standard" audio file name is made up +# filetemplate = "hpr%04d.%s" + +# +# How to fill in the "missing bit" in relative URLs +# baseURL = "https://hackerpublicradio.org/" + +# +# *** OBSOLETE *** +# If we need to fetch the MP3 version of the audio, which we do for older +# shows, these are under the 'local' directory. The 'eps' files are actually +# redirections to the IA. This is not normally used for the weekly uploads. +# #URLtemplate = "http://hackerpublicradio.org/eps/%s" #URLtemplate = "https://hackerpublicradio.org/local/%s" + +# +# Printf/sprintf template for building an URL which points back to the current +# show on the HPR site. +# sourceURLtemplate = "https://hackerpublicradio.org/eps/%s/index.html" + +# +# If we are having to collect assets from the HPR server and upload them to +# the IA server we want the final product to be addressable according to the +# following URL template. +# IAURLtemplate = "https://archive.org/download/%s/%s" + +# +# We build a Bash script to perform the upload of files which aren't in the +# CSV generated by make_metadata. We used to use the plain 'ia upload' command +# but now we call a Bash function declared in the script which is slightly +# cleverer. We need to do this to get round the IA code's tendency to "derive" +# all audio, and in doing so strip any audio tags. We perform our own +# equivalent of "derive" *with* the tags and upload them telling the IA *not* +# to re-derive. Mostly it listens. There's also a whole thing about IA keeping +# history of deletions which we want to turn off otherwise our items become +# stuffed with unwanted garbage. +# #iauploadtemplate = "ia upload %s %s --remote-name=%s" iauploadtemplate = "Upload %s %s '%s' '%s'" iauploadoptions = "--retries=5 --no-derive -H x-archive-keep-old-version:0" - diff --git a/InternetArchive/ia.db b/InternetArchive/ia.db index aa1d20e1d9dd5bb498c8c3f7cc98cba16b92cac7..e50f2e02cfba7724960b90ccf5dea10c48a04348 100644 GIT binary patch delta 139004 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 TcN=-@!|9lEQ+nUnd-DGS6rI@> delta 1514 zcmZwHS!@$W7{KuzXIbZRb`laCNJv7EI4T-~QgM_cPN9V&DCTO*rI3_RE+KQMm1x1s zHL1h{K?a+%flvZ1M*@brmxMr~^Z-&?prz23D?IRk;Dv_>ME_&rhoD&c&3yaKdgk+t zHI7p&9A|^5%gZb_43{(vV+LNwo-G5)`V<=_A8qoaHyIw$YS3e2Jh3~n|ECV}f#w0b=`JxrhsE%XvTw$4Pow7t*VSF&; zch2hhVrHp$YDeyj%~=qiko-dOR?PB?Hak)+MOGqzI$UR4wN^mHtbnVn<)yLsT>hj^ z=3?RI zhIil~h$^hXYJ7@MP>ofgALdpD#}MV6W|rO*F1!5!SiJ)FZ?oWYN%!TWd*?_xTpVJfCzGW?hXeT?%l z0I#A115t`WD8p+gMlbZ%=ii5*FZ!WBitq}&=!RVMKsK_F2?-k+$UzdGA|I`|j|X^& z$9Mug{+$07ouCo=dsc^AX_Ke1xr;w>3&d}-2BC_q#v=FJ4%yBwxtDS?+)5@ZnWAK> zl4(k&E9p@(LrGgnsbr>-SxR= 3, "\$uri = $uri\n" ); _debug( $DEBUG >= 3, "\$uri->fragment = " . $uri->fragment ) if $uri->fragment; - _debug( $DEBUG >= 3, "\$slink = $slink, \n" ); + _debug( $DEBUG >= 3, "\$slink = $slink\n" ); # # Is it an HPR link? @@ -1760,7 +1777,7 @@ sub find_links_in_file { # http://www.hackerpublicradio.org/eps/hpr1303/Music_Notes.html # Also things like this (**Why Ken?**) # ../eps/hpr2945/IMG_20191018_122746Z.jpg - # Don't match things like when *not* processing 1986: + # Don't match things like this when *not* processing 1986: # http://hackerpublicradio.org/eps/hpr1986/full_shownotes.html#example-2 # $epstr = sprintf( "hpr%04d", $episode ); diff --git a/InternetArchive/repair_assets b/InternetArchive/repair_assets new file mode 100755 index 0000000..c00b131 --- /dev/null +++ b/InternetArchive/repair_assets @@ -0,0 +1,627 @@ +#!/bin/bash - +#=============================================================================== +# +# FILE: repair_assets +# +# USAGE: ./repair_assets showid +# +# DESCRIPTION: Given a show where there was a directory of asset files on the +# old HPR server whichj got lost in the migration, rebuild it +# and fill it with assets from the IA. Modify the show notes to +# point to these recovered assets. +# +# OPTIONS: --- +# REQUIREMENTS: --- +# BUGS: --- +# NOTES: --- +# AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com +# VERSION: 0.0.6 +# CREATED: 2024-05-10 21:26:31 +# REVISION: 2024-07-10 15:12:54 +# +#=============================================================================== + +# set -o nounset # Treat unset variables as an error + +VERSION="0.0.6" + +SCRIPT=${0##*/} +# DIR=${0%/*} + +STDOUT="/dev/fd/2" + +# +# Select the appropriate working directory for the host +# +case $(hostname) in + i7-desktop) + BASEDIR="$HOME/HPR/InternetArchive" + ;; + borg) + BASEDIR="$HOME/IA" + ;; + *) + echo "Wrong host!" + exit 1 + ;; +esac + +cd "$BASEDIR" || { echo "Failed to cd to $BASEDIR"; exit 1; } + +# +# Load library functions +# +LIB="$HOME/HPR/function_lib.sh" +[ -e "$LIB" ] || { echo "Unable to source functions"; exit; } +# shellcheck disable=SC1090 +source "$LIB" + +# +# Enable coloured messages +# +define_colours + +# +# Sanity checks +# +IA=$(command -v ia) +[ -n "$IA" ] || { echo "Program 'ia' was not found"; exit 1; } +Q2T=$(command -v query2tt2) +[ -n "$Q2T" ] || { echo "Program 'query2tt2' was not found"; exit 1; } +FIXAL="$BASEDIR/fix_asset_links" +[ -e "$FIXAL" ] || { echo "Program '$FIXAL' was not found"; exit 1; } + +# +# Make temporary files and set traps to delete them +# +TMP1=$(mktemp) || { echo "$SCRIPT: creation of temporary file failed!"; exit 1; } +TMP2=$(mktemp) || { echo "$SCRIPT: creation of temporary file failed!"; exit 1; } +trap 'cleanup_temp $TMP1 $TMP2' SIGHUP SIGINT SIGPIPE SIGTERM EXIT + +# {{{ -- Functions -- _verbose, _usage, _log, find_missing, make_dir + +#=== FUNCTION ================================================================ +# NAME: find_missing +# DESCRIPTION: Given two arrays containing IA assets and HPR assets, +# determine which IA assets are missing from the HPR list. +# PARAMETERS: $1 (nameref) IA list +# $2 (nameref) HPR list +# $3 Name of array to receive list of missing assets +# RETURNS: Nothing +#=============================================================================== +find_missing () { + local -n IA="${1}" + local -n HPR="${2}" + local output="${3}" + + local -A hIA hHPR + local i key + + # + # Make a hash keyed by the IA file base names from an indexed array + # + for (( i=0; i<${#IA[@]}; i++ )); do + hIA+=([${IA[$i]##*/}]=${IA[$i]}) + done + + # + # Make a hash keyed by the HPR file base names from an indexed array + # + for (( i=0; i<${#HPR[@]}; i++ )); do + hHPR+=([${HPR[$i]##*/}]=${HPR[$i]}) + done + + # + # Use the basename keys to check what's missing, but return the full path + # names. + # + for key in "${!hIA[@]}"; do + if ! exists_in hHPR "$key"; then + eval "$output+=('${hIA[$key]}')" + fi + done +} + +#=== 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: _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: _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: _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] [-v] [-d {0|1}] [-D] showid + +Attempts to repair an show where the directory of assets was not transferred +from the old HPR server. + +Options: + -h Print this help + -v Run in verbose mode where more information is + reported. Default is off. If -v is repeated it + increases the verbosity level (levels 1 and 2 only). + -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 + +Arguments: + showid The show id in the form 'hpr1234' + +endusage + exit "$result" +} + +# }}} + +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#------------------------------------------------------------------------------- +# Directories and files +#------------------------------------------------------------------------------- +LOGS="$BASEDIR/logs" +make_dir "${LOGS}" +LOGFILE="$LOGS/$SCRIPT.log" + +#------------------------------------------------------------------------------- +# Options +#------------------------------------------------------------------------------- +# Default settings +# +VERBOSE=0 + +# +# Process options +# +while getopts :d:Dhv opt +do + case "${opt}" in + D) DEBUG=1;; + d) DRYRUN=$OPTARG;; + h) _usage 0;; + v) ((VERBOSE++));; + *) 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 + coloured 'red' "** Use '-d 0' or '-d 1'" + _usage 1 +fi +[[ $VERBOSE -gt 0 && $DRYRUN -eq 1 ]] && echo "Dry run mode" + +DEBUG=${DEBUG:-0} +[[ $DEBUG -eq 1 ]] && coloured 'yellow' "Debug mode" + +#------------------------------------------------------------------------------- +# Argument check +#------------------------------------------------------------------------------- +# Should have one argument +# +if [[ $# != 1 ]]; then + coloured 'red' "Missing argument" + _usage 1 +fi +show="${1,,}" + +# +# Ensure show id is correctly formatted. We want it to be 'hpr1234' +# +if [[ $show =~ (hpr)?([0-9]+) ]]; then + printf -v show 'hpr%04d' "${BASH_REMATCH[2]}" +else + coloured 'red' "Incorrect show specification: $show" + coloured 'yellow' "Use 'hpr9999' or '9999' format" + exit 1 +fi +_DEBUG "Parsed item: $show" +echo "Processing show $show" +_log "Processing show $show; dry-run: $([ "$DRYRUN" -eq 1 ] && echo "on" || echo "off")" + +#------------------------------------------------------------------------------- +# Declarations and constants +#------------------------------------------------------------------------------- +declare -a iacache + +# +# SHOWURL is where the show will be on the webserver +# +printf -v SHOWURL 'https://hackerpublicradio.org/eps/%s/index.html' "$show" + +# +# CACHEDIR is where we store asset details and files +# +CACHEDIR="$BASEDIR/assets" +[ ! -d "$CACHEDIR" ] && { + coloured 'red' "Creating cache directory" + make_dir "$CACHEDIR" +} + +# +# Pointers into the cache: +# LOCAL_ASSETDIR - where the cache for this show lives +# LOCAL_FILEDIR - where the IA files have been placed +# LOCAL_PARENTDIR - the equivalent directory to the top show dir +# +LOCAL_ASSETDIR="$CACHEDIR/${show}" +LOCAL_FILEDIR="$LOCAL_ASSETDIR/files" +LOCAL_PARENTDIR="$LOCAL_FILEDIR/${show}" + +# +# Pointers to the HPR server directories: +# REMOTE_ASSETDIR - where the assets are to go +# REMOTE_PARENTDIR - the remote parent directory +# +REMOTE_ASSETDIR="public_html/eps/${show}/${show}" +REMOTE_PARENTDIR="public_html/eps/${show}" + +CMDTPL='ssh hpr@hackerpublicradio.org %s' + +MANIFEST="$CACHEDIR/$show/manifest" +DBNOTES="$CACHEDIR/$show/notes.html" + +#------------------------------------------------------------------------------- +# Check the show exists in the database (or is visible on the website). +#------------------------------------------------------------------------------- +_verbose "Checking the show exists on the HPR server" +result=$(curl --head --silent --write-out "%{http_code}" --output /dev/null "$SHOWURL") +if [[ $result -eq 404 ]]; then + coloured 'red' "Could not detect show '$show' on the HPR server" + _log "Show '$show' not on the HPR server" + exit 1 +fi + +#------------------------------------------------------------------------------- +# Check the show exists on the IA +#------------------------------------------------------------------------------- +_verbose "Checking the show exists on the IA server" +if ! ia metadata "$show" --exists > /dev/null 2>&1; then + coloured 'red' "Could not detect show '$show' on the IA server" + coloured 'yellow' "Check that archive.org is available" + coloured 'yellow' "Try https://downfor.io/internet-archive" + _log "Show '$show' not on the IA server" + exit 1 +fi + +#------------------------------------------------------------------------------- +# Check IA, collect contents, classify them +#------------------------------------------------------------------------------- +# Interrogate the IA for the required item contents. If it returns True we can +# collect its contents, otherwise we can't proceed. The file 'TMP1' contains +# just a simple list of the files on the IA relating to this item. +# +_verbose "Collecting filenames from the IA server" +if ia list "$show" > "$TMP1"; then + while read -r iafile; do + iacache+=("$iafile") + done < "$TMP1" +else + coloured 'red' "Item $show can't be found on the IA" + coloured 'red' "Can't continue" + _log "Files for show '$show' not on the IA server" + exit 1 +fi + +_DEBUG "$(printf '%s\n' "${iacache[@]}")" + +# +# Determine which files are assets +# +_verbose "Categorising files held on the IA" + +declare -a audio ia_transcript ia_asset + +audio_re="^${show}\.(flac|mp3|ogg|opus|spx|wav)\$" +# transcript_re="^${show}/${show}/${show}\.(json|srt|tsv|txt|vtt)\$" +transcript_re="^${show}/${show}\.(json|srt|tsv|txt|vtt)\$" +asset_re="^${show}/(${show}/)?.*\$" +metadata_re="^(__ia_thumb.jpg|${show}[^/]+\.(afpk|torrent|gz|xml|sqlite|png))\$" + +for file in "${iacache[@]}"; do + if [[ $file =~ $audio_re ]]; then + audio+=("$file") + elif [[ $file =~ $metadata_re ]]; then + _verbose "Skipping $file" + continue + elif [[ $file =~ $transcript_re ]]; then + ia_transcript+=("$file") + elif [[ $file =~ $asset_re ]]; then + ia_asset+=("$file") + fi +done + +# +# Report what was collected at verbosity level 2 +# +if [[ $VERBOSE -gt 1 ]]; then + coloured 'cyan' "** audio (${#audio[@]}):" + printf '%s\n' "${audio[@]}" + + coloured 'cyan' "** transcript (${#ia_transcript[@]}):" + printf '%s\n' "${ia_transcript[@]}" + + coloured 'cyan' "** asset (${#ia_asset[@]}):" + printf '%s\n' "${ia_asset[@]}" + + _log "IA asset count for show '$show' = ${#ia_asset[@]}" +fi + +# +# No assets, no need to proceed! +# +if [[ ${#ia_asset[@]} -eq 0 ]]; then + coloured 'green' "No IA assets found for show $show; nothing to do" + _log "Nothing to do for show $show" + exit +fi + +#------------------------------------------------------------------------------- +# Check what's on the HPR server +#------------------------------------------------------------------------------- +# +# 'rc' is the remote command template +# +printf -v rc 'find public_html/eps/%s -type f -printf "%s/%%P\\n"' "$show" "$show" + +# +# 'command' is the local command we'll run to run a remote command on the HPR +# server +# +# shellcheck disable=SC2059 disable=SC2089 +printf -v command "$CMDTPL" "'$rc'" + +if [[ $VERBOSE -gt 1 ]]; then + echo "Command: $command" +fi + +declare -a hpr_asset +ignore_re="index.html$" + +# +# Run the command and save the output. Save the asset names returned in an +# array. TODO: Handle errors from the command +# +if [[ $DRYRUN -eq 0 ]]; then + eval "$command" > "$TMP2" + RES=$? + if [[ $RES -eq 0 ]]; then + _verbose "$(coloured 'green' "Remote command successful")" + while read -r hprfile; do + if [[ ! $hprfile =~ $ignore_re ]]; then + hpr_asset+=("${hprfile}") + fi + done < "$TMP2" + _verbose "$(coloured 'green' "Assets found on HPR server = ${#hpr_asset[@]}")" + _verbose "$(printf '%s\n' "${hpr_asset[@]}")" + _log "Assets found on HPR server = ${#hpr_asset[@]}" + else + coloured 'red' "Remote command failed" + _log "Failed while searching for HPR assets" + exit 1 + fi +else + coloured 'yellow' "Would have searched for assets on the HPR server" +fi + +#------------------------------------------------------------------------------- +# Compare the two asset lists and return what's missing on the HPR server +#------------------------------------------------------------------------------- +declare -a missing +find_missing ia_asset hpr_asset missing +_verbose "$(coloured 'cyan' "** missing (${#missing[@]}):")" +_verbose "$(printf '%s\n' "${missing[@]}")" + +if [[ ${#missing[@]} -eq 0 ]]; then + coloured 'green' "No missing assets detected; nothing to do" + _log "No missing assets detected; nothing to do" + exit +else + coloured 'yellow' "Found ${#missing[@]} files missing on the HPR server" +fi + +#------------------------------------------------------------------------------- +# Prepare to copy the missing files +#------------------------------------------------------------------------------- +make_dir "$LOCAL_FILEDIR" + +declare -a downloads + +# +# Check whether files are already downloaded +# +for file in "${missing[@]}"; do + if [[ ! -e "$LOCAL_FILEDIR/$show/$file" ]]; then + downloads+=("$file") + fi +done + +_verbose "$(coloured 'cyan' "** downloads (${#downloads[@]}):")" +_verbose "$(printf '%s\n' "${downloads[@]}")" + +# +# If we have files to download get them now +# +if [[ ${#downloads[@]} -gt 0 ]]; then + if [[ $DRYRUN -eq 1 ]]; then + coloured 'yellow' "Would have downloaded missing files from the IA" + else + ia download "$show" --destdir="$LOCAL_FILEDIR" "${downloads[@]}" + RES=$? + if [[ $RES -eq 0 ]]; then + coloured 'green' "Downloads complete" + _log "Downloaded IA assets for show $show" + fi + fi +else + coloured 'yellow' "IA files are already downloaded" +fi + +# shellcheck disable=SC2089 +RSYNCTPL="rsync -a -e 'ssh' %s hpr@hpr:%s" + +#------------------------------------------------------------------------------- +# Build the 'ssh' command to make a directory +#------------------------------------------------------------------------------- +# +# Prepare to make the remote directory if necessary. +# +# - $rc is the remote command we'll run on the server +# - $command is the full 'ssh' command including $rc +# +printf -v rc 'if [ ! -e "%s" ]; then mkdir -p "%s"; fi' \ + "$REMOTE_ASSETDIR" "$REMOTE_ASSETDIR" + +# shellcheck disable=SC2059 disable=SC2089 +printf -v command "$CMDTPL" "'$rc'" + +#------------------------------------------------------------------------------- +# Run or report the command that would be run +#------------------------------------------------------------------------------- +if [[ $DRYRUN -eq 0 ]]; then + eval "$command" + RES=$? + if [[ $RES -eq 0 ]]; then + coloured 'green' "Remote directory creation successful" + else + coloured 'red' "Remote directory creation failed" + fi +else + coloured 'yellow' "Would have created the remote directory" + echo "$command" +fi + +#------------------------------------------------------------------------------- +# Synchronise assets to the directory +#------------------------------------------------------------------------------- +# shellcheck disable=SC2059 disable=SC2089 +printf -v command "$RSYNCTPL" "$LOCAL_PARENTDIR/" "$REMOTE_PARENTDIR/" + +if [[ $DRYRUN -eq 0 ]]; then + eval "$command" + RES=$? + if [[ $RES -eq 0 ]]; then + coloured 'green' "Remote upload successful" + _log "Uploaded assets for show $show" + else + coloured 'red' "Remote upload failed" + exit 1 + fi +else + coloured 'yellow' "Would have synchronised local assets with the remote directory" + echo "$command" +fi + +#------------------------------------------------------------------------------- +# Make a 'manifest' file if necessary +#------------------------------------------------------------------------------- +if [[ $DRYRUN -eq 0 ]]; then + if [[ ! -e $MANIFEST ]]; then + find "$LOCAL_PARENTDIR" -type f -printf '%P\n' > "$MANIFEST" + _verbose "$(coloured 'green' "Created manifest file")" + _log "Created manifest file $MANIFEST" + fi +fi + +#------------------------------------------------------------------------------- +# Save the notes from the database if necessary +#------------------------------------------------------------------------------- +if [[ $DRYRUN -eq 0 ]]; then + if [[ ! -e $DBNOTES ]]; then + if ! tunnel_is_open; then + open_tunnel + fi + if query2tt2 -config="$BASEDIR/.hpr_livedb.cfg" \ + -temp="$BASEDIR/query2tt2_nokey.tpl" \ + -out="$DBNOTES" \ + -dbarg="${show:3}" \ + 'select notes from eps where id = ?' + then + _verbose "$(coloured 'green' "Created notes file")" + _log "Created notes file $DBNOTES" + else + _verbose "$(coloured 'red' "Creation of notes file failed")" + _log "Creation of notes file $DBNOTES failed" + fi + fi +fi + +#------------------------------------------------------------------------------- +# Adjust the notes with 'fix_asset_links' +#------------------------------------------------------------------------------- +if [[ $DRYRUN -eq 0 ]]; then + echo "$FIXAL" + # $FIXAL +fi + + +# +# All done +# +if [[ $DRYRUN -eq 0 ]]; then + _log "Repaired show $show" +fi + +#------------------------------------------------------------------------------- +# √ Make a place to hold the files on this machine +# √ Download them from the IA +# √ Make a directory on the HPR server +# √ Copy the assets to the HPR server +# Modify the notes to point to the assets on the server +#------------------------------------------------------------------------------- + +# vim: syntax=sh:ts=8:sw=4:ai:et:tw=78:fo=tcrqn21:fdm=marker diff --git a/InternetArchive/repair_item b/InternetArchive/repair_item index 7a6831c..7700330 100755 --- a/InternetArchive/repair_item +++ b/InternetArchive/repair_item @@ -3,7 +3,7 @@ # # FILE: repair_item # -# USAGE: ./repair_item [-h] [-v] [-d {0|1}] [-D] [-l N] itemname +# USAGE: ./repair_item [-h] [-v] [-d {0|1}] [-D] [-l N] [-X] itemname # # DESCRIPTION: Repairs an IA "item" (HPR show) if something has failed during # the upload. @@ -18,20 +18,32 @@ # temporarily on 'borg') and determines which have not been # uploaded, then takes steps to perform the uploads. # +# Version 0.0.10 onwards has the capability to repair an IA item +# from the HPR backup disk. This seems to be necessary because +# the transcripts were not carried over (although we are +# adding them to the IA for new shows now, older ones were never +# copied), and there has been a case where none of the assets +# were on the IA. The method used it to place the backup files +# in the directory 'repairs' under the local IA or +# InternetArchive directory. The files are held in the hierarchy +# '$item/$item/'. The assets are in the lower directory and the +# source file is in the upper one. This emulates the placement +# on the IA itself. +# # OPTIONS: --- # REQUIREMENTS: --- # BUGS: --- # NOTES: --- # AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com -# VERSION: 0.0.9 +# VERSION: 0.0.10 # CREATED: 2020-01-05 22:42:46 -# REVISION: 2024-06-14 18:03:58 +# REVISION: 2024-07-12 14:39:38 # #=============================================================================== #set -o nounset # Treat unset variables as an error -VERSION="0.0.9" +VERSION="0.0.10" SCRIPT=${0##*/} # DIR=${0%/*} @@ -45,10 +57,12 @@ case $(hostname) in i7-desktop) BASEDIR="$HOME/HPR/InternetArchive" UPLOADS="$HOME/HPR/IA/uploads" + REPAIRS="$BASEDIR/repairs" ;; borg) BASEDIR="$HOME/IA" UPLOADS="/data/IA/uploads" + REPAIRS="$BASEDIR/repairs" ;; *) echo "Wrong host!" @@ -185,7 +199,7 @@ _usage () { cat >$STDOUT <<-endusage ${SCRIPT} - version: ${VERSION} -Usage: ./${SCRIPT} [-h] [-v] [-d {0|1}] [-D] [-l N] item +Usage: ./${SCRIPT} [-h] [-v] [-d {0|1}] [-D] [-l N] [-X] item Attempts to repair an IA item where the upload has failed for some reason. @@ -203,6 +217,12 @@ Options: during one run of the script. The range is 1 to $DEFLIMIT. This can be helpful when there are upload problems. + -X Run in "extended" mode. In this mode the directory + holding files to be added to the IA is '~/IA/repairs' + and the files have most likely come from the HPR + backup disk and aren't on the IA due some error. We + want to use the capabilities of ${SCRIPT} to repair + things and deal with the IA upload problems. Arguments: item The item in the form 'hpr1234' @@ -229,7 +249,7 @@ DEFLIMIT=20 # # Process options # -while getopts :d:Dhl:v opt +while getopts :d:Dhl:vX opt do case "${opt}" in D) DEBUG=1;; @@ -237,6 +257,7 @@ do h) _usage 0;; l) LIMIT=$OPTARG;; v) VERBOSE=1;; + X) EXTENDED=1;; *) echo "** Unknown option" _usage 1;; esac @@ -264,6 +285,8 @@ if [[ $LIMIT -lt 1 || $LIMIT -gt $DEFLIMIT ]]; then _usage 1 fi +EXTENDED=${EXTENDED:-0} + # # Should have one argument # @@ -295,6 +318,22 @@ if ! ia metadata "$item" --exists > /dev/null 2>&1; then exit 1 fi +# +# The -X (EXTENDED) mode is for when we have to upload files that have +# mysteriously vanished from the IA. The directories here are equivalent to +# those used by 'repair_assets'. There is a top-level directory the represents +# the IA item, and below that a hierarchy defining placement under the item. +# There is a 'repairs' directory per host in case we need to preair IA stuff +# from elsewhere. +# +if [[ $EXTENDED -eq 1 ]]; then + coloured 'cyan' "Using 'Extended' mode" + if [[ ! -e $REPAIRS ]]; then + mkdir -p "$REPAIRS" + fi + UPLOADS="$REPAIRS/$item" +fi + # # Declarations #