forked from HPR/hpr-tools
		
	
		
			
				
	
	
		
			480 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			480 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/bin/bash -
 | 
						|
#===============================================================================
 | 
						|
#
 | 
						|
#         FILE: past_upload
 | 
						|
#
 | 
						|
#        USAGE: ./past_upload [-h] [-r] [-v] [-d {0|1}] start [count]
 | 
						|
#
 | 
						|
#  DESCRIPTION: Run the commands necessary to upload a batch of older HPR
 | 
						|
#               shows to archive.org
 | 
						|
#
 | 
						|
#      OPTIONS: ---
 | 
						|
# REQUIREMENTS: ---
 | 
						|
#         BUGS: ---
 | 
						|
#        NOTES: ---
 | 
						|
#       AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com
 | 
						|
#      VERSION: 0.0.12
 | 
						|
#      CREATED: 2021-04-17 22:14:16
 | 
						|
#     REVISION: 2022-07-07 16:17:41
 | 
						|
#
 | 
						|
#===============================================================================
 | 
						|
 | 
						|
set -o nounset                              # Treat unset variables as an error
 | 
						|
 | 
						|
SCRIPT=${0##*/}
 | 
						|
# DIR=${0%/*}
 | 
						|
VERSION="0.0.12"
 | 
						|
 | 
						|
STDOUT="/dev/fd/2"
 | 
						|
 | 
						|
#
 | 
						|
# Select the appropriate working directory
 | 
						|
#
 | 
						|
case $(hostname) in
 | 
						|
    i7-desktop)
 | 
						|
        BASEDIR="$HOME/HPR/InternetArchive"
 | 
						|
        UPLOAD="$BASEDIR/uploads"
 | 
						|
        ;;
 | 
						|
    borg)
 | 
						|
        BASEDIR="$HOME/IA"
 | 
						|
        UPLOAD="/data/IA/uploads"
 | 
						|
        ;;
 | 
						|
    *)
 | 
						|
        echo "Wrong host!"
 | 
						|
        exit 1
 | 
						|
        ;;
 | 
						|
esac
 | 
						|
 | 
						|
cd "$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"
 | 
						|
 | 
						|
#
 | 
						|
# Log file
 | 
						|
#
 | 
						|
LOGS="$BASEDIR/logs"
 | 
						|
LOGFILE="$LOGS/$SCRIPT.log"
 | 
						|
 | 
						|
#
 | 
						|
# Make temporary files and set traps to delete them
 | 
						|
#
 | 
						|
TMP1=$(mktemp) || { echo "$SCRIPT: creation of temporary file failed!"; exit 1; }
 | 
						|
trap 'cleanup_temp $TMP1' SIGHUP SIGINT SIGPIPE SIGTERM EXIT
 | 
						|
 | 
						|
#===  FUNCTION  ================================================================
 | 
						|
#         NAME: _verbose
 | 
						|
#  DESCRIPTION: Writes a message in verbose mode
 | 
						|
#   PARAMETERS: $1      message
 | 
						|
#      RETURNS: Nothing
 | 
						|
#===============================================================================
 | 
						|
_verbose () {
 | 
						|
    local msg=${1:-}
 | 
						|
 | 
						|
    [[ $VERBOSE -eq 1 ]] && echo "$msg"
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#===  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] [-r] [-v] [-d {0|1}] start [count]
 | 
						|
 | 
						|
Generates the necessary metadata and script and uses them to upload HPR audio
 | 
						|
and other show-related files held on the VPS to the Internet Archive. This
 | 
						|
script is similar to 'weekly_upload' but it's for dealing with older shows
 | 
						|
where we only have the MP3 audio.
 | 
						|
 | 
						|
Options:
 | 
						|
  -h                    Print this help
 | 
						|
  -v                    Run in verbose mode where more information is reported
 | 
						|
  -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.
 | 
						|
  -F                    Force an upload even if the items are already on the
 | 
						|
                        IA. Use with *GREAT* caution!
 | 
						|
  -m                    Update the item's metadata from the file generated
 | 
						|
                        for (re-)uploads. This ensures that any changes to the
 | 
						|
                        notes, summary, tags, etc are propagated. This does
 | 
						|
                        not happen by default, but shows with assets are
 | 
						|
                        always updated this way.
 | 
						|
  -r                    Run in 'remote' mode, using the live database over an
 | 
						|
                        (already established) SSH tunnel. Default is to run
 | 
						|
                        against the local database.
 | 
						|
  -Y                    Answer 'Y' to the confirmation question (really don't
 | 
						|
                        ask at all)
 | 
						|
 | 
						|
Arguments:
 | 
						|
    start               the starting show number to be uploaded
 | 
						|
    count               (optional, default 1) the number of shows to be
 | 
						|
                        uploaded; not allowed to exceed 20
 | 
						|
 | 
						|
Notes:
 | 
						|
 | 
						|
1. When running on 'borg' the method used is to run in faux 'local' mode.
 | 
						|
   This means we have an open tunnel to the HPR server (mostly left open) and
 | 
						|
   the default file .hpr_db.cfg points to the live database via this tunnel.
 | 
						|
   So we do not use the -r option here. This is a bit of a hack! Sorry!
 | 
						|
 | 
						|
TODO: Needs fix!
 | 
						|
 | 
						|
2. There are potential problems when a show has no tags which haven't been
 | 
						|
   fully resolved. The make_metadata script fails in default mode when it
 | 
						|
   finds such a show, but this (weekly_upload) script can continue on and run
 | 
						|
   the generated script which uploads the source audio files. This can mean
 | 
						|
   the IA items end up as books! In this mode the description is not stored
 | 
						|
   and so there are no show notes.
 | 
						|
 | 
						|
endusage
 | 
						|
    exit "$result"
 | 
						|
}
 | 
						|
 | 
						|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
						|
 | 
						|
#
 | 
						|
# Prerequisites
 | 
						|
#
 | 
						|
jq=$(command -v jq)
 | 
						|
[ -z "$jq" ] && { echo "Needs the 'jq' JSON filter"; exit 1; }
 | 
						|
ia=$(command -v ia)
 | 
						|
[ -z "$ia" ] && { echo "Needs the 'ia' Internet Archive script"; exit 1; }
 | 
						|
transfer_tags=$(command -v transfer_tags)
 | 
						|
[ -z "$transfer_tags" ] && { echo "Needs the 'transfer_tags' script"; exit 1; }
 | 
						|
tunnel_is_open=$(command -v tunnel_is_open)
 | 
						|
[ -z "$tunnel_is_open" ] && { echo "Needs the 'tunnel_is_open' script"; exit 1; }
 | 
						|
[ -e "$BASEDIR/transcode" ] || {
 | 
						|
    echo "Needs the 'transcode' script"
 | 
						|
    exit 1
 | 
						|
}
 | 
						|
[ -e "$BASEDIR/make_metadata" ] || {
 | 
						|
    echo "Needs the 'make_metadata' script"
 | 
						|
    exit 1
 | 
						|
}
 | 
						|
 | 
						|
#
 | 
						|
# Constant
 | 
						|
#
 | 
						|
RETRIES=5
 | 
						|
 | 
						|
#
 | 
						|
# Check the tunnel is open
 | 
						|
#
 | 
						|
if ! tunnel_is_open; then
 | 
						|
    echo "Open the tunnel before running this script (open_tunnel)"
 | 
						|
    exit 1
 | 
						|
fi
 | 
						|
 | 
						|
#-------------------------------------------------------------------------------
 | 
						|
# Process options
 | 
						|
#-------------------------------------------------------------------------------
 | 
						|
while getopts :d:FhmrvY opt
 | 
						|
do
 | 
						|
    case "${opt}" in
 | 
						|
        d) DRYRUN=$OPTARG;;
 | 
						|
        F) FORCE=1;;
 | 
						|
        h) _usage 1;;
 | 
						|
        m) METADATA=1;;
 | 
						|
        r) REMOTE=1;;
 | 
						|
        v) VERBOSE=1;;
 | 
						|
        Y) YES=1;;
 | 
						|
        *) _usage 1;;
 | 
						|
    esac
 | 
						|
done
 | 
						|
shift $((OPTIND - 1))
 | 
						|
 | 
						|
#
 | 
						|
# Check choices and set defaults
 | 
						|
#
 | 
						|
DRYRUN=${DRYRUN:-1}
 | 
						|
if [[ $DRYRUN -ne 0 && $DRYRUN -ne 1 ]]; then
 | 
						|
    echo "** Use '-d 0' or '-d 1'"
 | 
						|
    _usage 1
 | 
						|
fi
 | 
						|
 | 
						|
FORCE=${FORCE:-0}
 | 
						|
 | 
						|
METADATA=${METADATA:-0}
 | 
						|
 | 
						|
YES=${YES:-0}
 | 
						|
 | 
						|
VERBOSE=${VERBOSE:-0}
 | 
						|
 | 
						|
REMOTE=${REMOTE:-0}
 | 
						|
if [[ $REMOTE -eq 0 ]]; then
 | 
						|
    dbconfig="$BASEDIR/.hpr_db.cfg"
 | 
						|
    _verbose "Local database mode"
 | 
						|
else
 | 
						|
    dbconfig="$BASEDIR/.hpr_livedb.cfg"
 | 
						|
    _verbose "Remote database mode"
 | 
						|
fi
 | 
						|
 | 
						|
#
 | 
						|
# Check argument count
 | 
						|
#
 | 
						|
if [[ ! ( $# -eq 1 || $# -eq 2 ) ]]; then
 | 
						|
    echo "Wrong number of arguments"
 | 
						|
    _usage 1
 | 
						|
fi
 | 
						|
 | 
						|
#
 | 
						|
# Validate arguments
 | 
						|
#
 | 
						|
for arg; do
 | 
						|
    if [[ ! $arg =~ ^[0-9]{1,4}$ ]]; then
 | 
						|
        echo "Invalid number: $arg"
 | 
						|
        echo "Use a plain number"
 | 
						|
        exit 1
 | 
						|
    fi
 | 
						|
done
 | 
						|
 | 
						|
#
 | 
						|
# Set variables for the range of shows
 | 
						|
#
 | 
						|
start=$1
 | 
						|
count=${2:-1}
 | 
						|
if [[ $count -gt 20 ]]; then
 | 
						|
    echo "Can't process more than 20 shows at a time"
 | 
						|
    exit 1
 | 
						|
fi
 | 
						|
((end = start + count - 1))
 | 
						|
 | 
						|
[[ $DRYRUN -eq 1 ]] && _verbose "Dry run mode"
 | 
						|
 | 
						|
if [[ $VERBOSE -eq 1 ]]; then
 | 
						|
    echo "Processing $count $(ngettext show shows "$count") from $start"
 | 
						|
else
 | 
						|
    echo "${start}..${end}"
 | 
						|
fi
 | 
						|
 | 
						|
#
 | 
						|
# Log the start of this run
 | 
						|
#
 | 
						|
[[ $DRYRUN -eq 0 ]] && \
 | 
						|
    echo "$(date +%Y%m%d%H%M%S) Processing ${start}..${end} (v$VERSION)" >> "$LOGFILE"
 | 
						|
 | 
						|
#
 | 
						|
# Store the show numbers in an array. We need 'eval' to substitute `$start'
 | 
						|
# and '$end' for the 'printf'.
 | 
						|
#
 | 
						|
declare -a shows
 | 
						|
mapfile -t shows < <(eval "printf '%04d\n' {$start..$end}")
 | 
						|
 | 
						|
#
 | 
						|
# Walk the array and delete elements that are already on the IA
 | 
						|
#
 | 
						|
if [[ $FORCE -eq 1 ]]; then
 | 
						|
    _verbose 'Not checking for shows on archive.org; forcing!'
 | 
						|
    [[ $DRYRUN -eq 0 ]] && echo "$(date +%Y%m%d%H%M%S) Forcing an update (-F)" >> "$LOGFILE"
 | 
						|
else
 | 
						|
    _verbose 'Checking for shows on archive.org'
 | 
						|
    [[ $DRYRUN -eq 0 ]] && echo "$(date +%Y%m%d%H%M%S) Checking archive.org" >> "$LOGFILE"
 | 
						|
    i=0
 | 
						|
    for item in "${shows[@]}"; do
 | 
						|
        if ia list "hpr$item" > /dev/null 2>&1; then
 | 
						|
            _verbose "Found hpr$item on archive.org"
 | 
						|
            unset "shows[$i]"
 | 
						|
        fi
 | 
						|
        ((i++))
 | 
						|
        done
 | 
						|
fi
 | 
						|
 | 
						|
#
 | 
						|
# Stop if there's nothing to do
 | 
						|
#
 | 
						|
if [[ ${#shows[@]} -eq 0 ]]; then
 | 
						|
    echo "Nothing to do; nominated show(s) are currently on archive.org"
 | 
						|
    [[ $DRYRUN -eq 0 ]] && echo "$(date +%Y%m%d%H%M%S) Nothing to do" >> "$LOGFILE"
 | 
						|
    exit 1
 | 
						|
else
 | 
						|
    _verbose "There $(ngettext 'is 1 show' "are ${#shows[@]} shows" "${#shows[@]}") to process"
 | 
						|
fi
 | 
						|
 | 
						|
#
 | 
						|
# Find which audio needs to be downloaded and go get it
 | 
						|
#
 | 
						|
_verbose "Downloading missing audio..."
 | 
						|
if [[ $DRYRUN -eq 1 ]]; then
 | 
						|
    echo "Would have attempted to download ${#shows[@]} $(ngettext show shows "${#shows[@]}") (dry run)"
 | 
						|
else
 | 
						|
    for item in "${shows[@]}"; do
 | 
						|
        if [[ ! -e $UPLOAD/hpr$item.mp3 ]]; then
 | 
						|
            echo "Downloading hpr$item.mp3"
 | 
						|
            wget -q "http://hackerpublicradio.org/local/hpr$item.mp3" \
 | 
						|
                -O "$UPLOAD/hpr$item.mp3"
 | 
						|
            _verbose "Downloaded $UPLOAD/hpr$item.mp3"
 | 
						|
        else
 | 
						|
            _verbose "$UPLOAD/hpr$item.mp3 already exists"
 | 
						|
        fi
 | 
						|
    done
 | 
						|
fi
 | 
						|
 | 
						|
#
 | 
						|
# Transcode the audio as needed
 | 
						|
#
 | 
						|
_verbose "Transcoding missing audio..."
 | 
						|
if [[ $DRYRUN -eq 1 ]]; then
 | 
						|
    echo "Would have transcoded ${#shows[@]} $(ngettext show shows "${#shows[@]}") (dry run)"
 | 
						|
else
 | 
						|
    [[ $DRYRUN -eq 0 ]] && \
 | 
						|
        echo "$(date +%Y%m%d%H%M%S) Transcoding ${#shows[@]} $(ngettext show shows "${#shows[@]}")" >> "$LOGFILE"
 | 
						|
    for item in "${shows[@]}"; do
 | 
						|
        if [[ $VERBOSE -eq 1 ]]; then
 | 
						|
            ./transcode -v "$UPLOAD/hpr$item.mp3"
 | 
						|
        else
 | 
						|
            ./transcode "$UPLOAD/hpr$item.mp3"
 | 
						|
        fi
 | 
						|
    done
 | 
						|
fi
 | 
						|
 | 
						|
#
 | 
						|
# We now have a list of shows in the right state to be uploaded, so we can do
 | 
						|
# what's necessary
 | 
						|
#
 | 
						|
_verbose "Uploading $(ngettext show shows "${#shows[@]}")..."
 | 
						|
 | 
						|
#
 | 
						|
# Define files for make_metadata. For aesthetic reasons don't use '1-1' when
 | 
						|
# there's only one show!
 | 
						|
#
 | 
						|
if [[ $start -eq $end ]]; then
 | 
						|
    printf -v metadata 'metadata_%04d.csv' "$start"
 | 
						|
    printf -v script 'script_%04d.sh' "$start"
 | 
						|
else
 | 
						|
    printf -v metadata 'metadata_%04d-%04d.csv' "$start" "$end"
 | 
						|
    printf -v script 'script_%04d-%04d.sh' "$start" "$end"
 | 
						|
fi
 | 
						|
 | 
						|
#
 | 
						|
# Check on the dry-run choice
 | 
						|
#
 | 
						|
if [[ $DRYRUN -eq 1 ]]; then
 | 
						|
    echo "Dry run: Would have uploaded $count $(ngettext show shows "$count") from $start"
 | 
						|
    echo "Dry run: Would have created $metadata and $script"
 | 
						|
    echo "Dry run: Would have uploaded $metadata and run $script"
 | 
						|
    echo "Dry run: Would have used $dbconfig"
 | 
						|
    echo -n "Dry run: Would have done metadata updates for "
 | 
						|
    if [[ $METADATA -eq 0 ]]; then
 | 
						|
       echo "shows with assets"
 | 
						|
   else
 | 
						|
       echo "all shows"
 | 
						|
    fi
 | 
						|
else
 | 
						|
    #
 | 
						|
    # Really do the upload
 | 
						|
    #
 | 
						|
    if [[ $start -eq $end ]]; then
 | 
						|
        echo "Uploading $start"
 | 
						|
    else
 | 
						|
        echo "Uploading $start to $end inclusive"
 | 
						|
    fi
 | 
						|
 | 
						|
    #
 | 
						|
    # Implement the -Y (override) option
 | 
						|
    #
 | 
						|
    if [[ $YES -eq 1 ]]; then
 | 
						|
        confirmed=1
 | 
						|
    else
 | 
						|
        echo "$(date +%Y%m%d%H%M%S) Waiting for confirmation" >> "$LOGFILE"
 | 
						|
        if yes_no "OK to continue? %s " "N"; then
 | 
						|
            confirmed=1
 | 
						|
        else
 | 
						|
            confirmed=0
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
 | 
						|
    #---------------------------------------------------------------------------
 | 
						|
    # Do the work
 | 
						|
    #---------------------------------------------------------------------------
 | 
						|
    if [[ $confirmed -eq 1 ]]; then
 | 
						|
        # shellcheck disable=2086
 | 
						|
        {
 | 
						|
            #
 | 
						|
            # Make the metadata
 | 
						|
            #
 | 
						|
            _verbose "Running make_metadata"
 | 
						|
            $BASEDIR/make_metadata -dbconf=${dbconfig} \
 | 
						|
                -from=$start -count=$count \
 | 
						|
                -verb -out -script -a_count=$TMP1
 | 
						|
            RES=$?
 | 
						|
 | 
						|
            #
 | 
						|
            # If it all went OK perform the uploads, otherwise report the
 | 
						|
            # problem(s)
 | 
						|
            #
 | 
						|
            if [[ $RES -eq 0 ]]; then
 | 
						|
                _verbose "Uploading audio and any assets"
 | 
						|
                ia upload --retries=$RETRIES --spreadsheet=${metadata} \
 | 
						|
                    -H x-archive-keep-old-version:0 && \
 | 
						|
                    [ -e $script ] && ./${script}
 | 
						|
                echo "$(date +%Y%m%d%H%M%S) Uploaded shows" >> "$LOGFILE"
 | 
						|
            else
 | 
						|
                echo "Upload aborted due to errors"
 | 
						|
                echo "$(date +%Y%m%d%H%M%S) Upload failed due to errors" >> "$LOGFILE"
 | 
						|
                exit 1
 | 
						|
            fi
 | 
						|
 | 
						|
            #
 | 
						|
            # Update metadata for all shows if requested
 | 
						|
            #
 | 
						|
            if [[ $METADATA -eq 1 ]]; then
 | 
						|
                _verbose "Uploading changed metadata"
 | 
						|
                ia metadata --spreadsheet=${metadata}
 | 
						|
                echo "$(date +%Y%m%d%H%M%S) Metadata uploaded for all shows" >> "$LOGFILE"
 | 
						|
            else
 | 
						|
                #
 | 
						|
                # We aren't updating metadata for all, but if any shows had
 | 
						|
                # assets we need to do metadata updates. The show details are
 | 
						|
                # in the temporary file $TMP1
 | 
						|
                #
 | 
						|
                if [[ -s $TMP1 ]]; then
 | 
						|
                    _verbose "Refreshing metadata for shows with assets"
 | 
						|
                    declare -a mshows
 | 
						|
                    mapfile -t mshows < <(cut -f1 -d' ' $TMP1 | sed -e 's/^hpr//' | sort)
 | 
						|
                    mlist="${mshows[*]}"
 | 
						|
 | 
						|
                    if [[ ${#mshows[@]} -eq 1 ]]; then
 | 
						|
                        printf -v metadata 'meta_metadata_%04d.csv' "${mshows[0]}"
 | 
						|
                    else
 | 
						|
                        printf -v metadata 'meta_metadata_%04d-%04d.csv' "${mshows[0]}" "${mshows[-1]}"
 | 
						|
                    fi
 | 
						|
 | 
						|
                    _verbose "Regenerating metadata"
 | 
						|
                    $BASEDIR/make_metadata -dbconf=${dbconfig} -list="${mlist/ /,}" \
 | 
						|
                        -out=${metadata} -meta -noassets -verb
 | 
						|
                    RES=$?
 | 
						|
 | 
						|
                    if [[ $RES -eq 0 ]]; then
 | 
						|
                        _verbose "Uploading new metadata"
 | 
						|
                        ia metadata --spreadsheet=${metadata}
 | 
						|
                        echo "$(date +%Y%m%d%H%M%S) Metadata uploaded for eligible shows" >> "$LOGFILE"
 | 
						|
                    else
 | 
						|
                        echo "Metadata update aborted due to errors"
 | 
						|
                        echo "$(date +%Y%m%d%H%M%S) Metadata upload failed due to errors" >> "$LOGFILE"
 | 
						|
                        exit 1
 | 
						|
                    fi
 | 
						|
                fi
 | 
						|
            fi
 | 
						|
        }
 | 
						|
    else
 | 
						|
        echo "Not uploaded"
 | 
						|
        echo "$(date +%Y%m%d%H%M%S) Upload aborted" >> "$LOGFILE"
 | 
						|
    fi
 | 
						|
fi
 | 
						|
 | 
						|
# vim: syntax=sh:ts=8:sw=4:ai:et:tw=78:fo=tcrqn21
 |