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
 |