291 lines
8.6 KiB
Plaintext
291 lines
8.6 KiB
Plaintext
|
#!/bin/bash -
|
||
|
#===============================================================================
|
||
|
#
|
||
|
# FILE: delete_ia_item
|
||
|
#
|
||
|
# USAGE: ./delete_ia_item episode
|
||
|
#
|
||
|
# DESCRIPTION: Deletes an uploaded item on the IA. The item (identifier)
|
||
|
# can't be deleted entirely but it can be stripped of contents
|
||
|
# and metadata and left in a 'Reserved' state so the slot can be
|
||
|
# reused.
|
||
|
#
|
||
|
# OPTIONS: ---
|
||
|
# REQUIREMENTS: ---
|
||
|
# BUGS: ---
|
||
|
# NOTES: ---
|
||
|
# AUTHOR: Dave Morriss (djm), Dave.Morriss@gmail.com
|
||
|
# VERSION: 0.0.3
|
||
|
# CREATED: 2022-05-08 19:40:37
|
||
|
# REVISION: 2022-08-14 23:09:51
|
||
|
#
|
||
|
#===============================================================================
|
||
|
|
||
|
set -o nounset # Treat unset variables as an error
|
||
|
|
||
|
VERSION="0.0.3"
|
||
|
|
||
|
SCRIPT=${0##*/}
|
||
|
# DIR=${0%/*}
|
||
|
|
||
|
STDOUT="/dev/fd/2"
|
||
|
|
||
|
#
|
||
|
# Load library functions
|
||
|
#
|
||
|
LIB="$HOME/bin/function_lib.sh"
|
||
|
[ -e "$LIB" ] || { echo "Unable to source functions"; exit 1; }
|
||
|
# shellcheck source=function_lib.sh
|
||
|
source "$LIB"
|
||
|
|
||
|
#
|
||
|
# Colour codes
|
||
|
#
|
||
|
define_colours
|
||
|
|
||
|
#
|
||
|
# 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: _DEBUG
|
||
|
# DESCRIPTION: Writes messages if in DEBUG mode
|
||
|
# PARAMETERS: List of messages
|
||
|
# RETURNS: Nothing
|
||
|
#===============================================================================
|
||
|
_DEBUG () {
|
||
|
[ "$DEBUG" == 0 ] && return
|
||
|
for msg in "$@"; do
|
||
|
printf 'D> %s\n' "$msg"
|
||
|
done
|
||
|
}
|
||
|
|
||
|
#=== FUNCTION ================================================================
|
||
|
# NAME: _usage
|
||
|
# DESCRIPTION: Report usage
|
||
|
# PARAMETERS: 1 [optional] exit value
|
||
|
# RETURNS: Nothing
|
||
|
#===============================================================================
|
||
|
_usage () {
|
||
|
local -i res="${1:-0}"
|
||
|
|
||
|
cat >$STDOUT <<-endusage
|
||
|
${SCRIPT} - version: ${VERSION}
|
||
|
|
||
|
Usage: ./${SCRIPT} [-h] [-d {0|1}] episode
|
||
|
|
||
|
Deletes an uploaded item on the IA. The item (identifier) can't be deleted
|
||
|
entirely but it can be stripped of contents and metadata and left in
|
||
|
a 'Reserved' state so the slot can be reused.
|
||
|
|
||
|
Options:
|
||
|
-h Print this help
|
||
|
-d 0|1 Dry run: -d 1 (the default) runs the script in dry-run
|
||
|
mode where nothing is moved but the actions that
|
||
|
will be taken are reported; -d 0 turns off dry-run
|
||
|
mode and the actions will be carried out.
|
||
|
|
||
|
Arguments:
|
||
|
episode Defines the episode (IA identifier) to be deleted from
|
||
|
archive.org. These identifiers are in the format
|
||
|
'hprNNNN' where 'NNNN' is a number with leading
|
||
|
zeroes, and 'hpr' is mandatory.
|
||
|
|
||
|
The script attempts to reformat incorrect identifiers
|
||
|
before giving up. The missing 'hpr' is added, and
|
||
|
missing leading zeroes are inserted. Thus '42' and
|
||
|
'hpr42' become 'hpr0042'.
|
||
|
|
||
|
Environment variables:
|
||
|
delete_ia_item_DEBUG If set to a non-zero value then the debugging
|
||
|
statements in the script are executed. Otherwise if
|
||
|
set to zero, or if the variable is absent no debug
|
||
|
information is produced. The variable can be set
|
||
|
using the 'export' command or on the same line as the
|
||
|
command calling the script. See the example below.
|
||
|
|
||
|
Examples
|
||
|
./delete_ia_item 3594 # Run in (default) dry-run mode
|
||
|
./delete_ia_item -d1 3594 # Run in (explicit) dry-run mode
|
||
|
./delete_ia_item -d0 3594 # Live mode
|
||
|
|
||
|
delete_ia_item_DEBUG=1 ./delete_ia_item 3594
|
||
|
# Run in dry-run mode with debugging enabled
|
||
|
|
||
|
endusage
|
||
|
exit "$res"
|
||
|
}
|
||
|
|
||
|
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
#
|
||
|
# Configure depending whether local or on borg
|
||
|
#
|
||
|
case $HOSTNAME in
|
||
|
hprvps|marvin|borg)
|
||
|
BASEDIR="$HOME/IA" ;;
|
||
|
i7-desktop)
|
||
|
BASEDIR="$HOME/HPR/IA" ;;
|
||
|
*)
|
||
|
echo "Wrong host!"; exit 1 ;;
|
||
|
esac
|
||
|
|
||
|
cd "$BASEDIR" || { echo "Can't cd to $BASEDIR"; exit 1; }
|
||
|
|
||
|
#
|
||
|
# Directories and files
|
||
|
#
|
||
|
LOGS="$BASEDIR/logs"
|
||
|
LOGFILE="$LOGS/$SCRIPT.log"
|
||
|
|
||
|
#
|
||
|
# Debug mode. Invoke it with: 'delete_ia_item_DEBUG=1 ./tidy_uploaded'
|
||
|
#
|
||
|
DEBUGVAR="${SCRIPT}_DEBUG"
|
||
|
DEBUG="${!DEBUGVAR:-0}"
|
||
|
[[ $DEBUG -eq 1 ]] && echo "Debug mode"
|
||
|
|
||
|
#
|
||
|
# File of processed shows
|
||
|
#
|
||
|
PROCFILE="$BASEDIR/.${SCRIPT}.dat"
|
||
|
[ -e "$PROCFILE" ] || touch "$PROCFILE"
|
||
|
|
||
|
#
|
||
|
# 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; }
|
||
|
|
||
|
#
|
||
|
# Process options
|
||
|
#
|
||
|
while getopts :d:h opt
|
||
|
do
|
||
|
case "${opt}" in
|
||
|
d) DRYRUN=$OPTARG;;
|
||
|
h) _usage 0;;
|
||
|
*) echo "** Unknown option"
|
||
|
_usage 1;;
|
||
|
esac
|
||
|
done
|
||
|
shift $((OPTIND - 1))
|
||
|
|
||
|
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"
|
||
|
|
||
|
#
|
||
|
# Should have only one argument
|
||
|
#
|
||
|
if [[ $# != 1 ]]; then
|
||
|
echo "${red}${SCRIPT} takes one argument${reset}"
|
||
|
_usage 1
|
||
|
fi
|
||
|
|
||
|
#
|
||
|
# Collect the argument and clean and validate it, forcing leading zeroes if
|
||
|
# needed
|
||
|
#
|
||
|
item="${1:-}"
|
||
|
item="${item,,}"
|
||
|
item="${item## }"
|
||
|
item="${item%% }"
|
||
|
if [[ $item =~ ^(hpr)?([0-9]{1,4})$ ]]; then
|
||
|
printf -v item 'hpr%04i' "${BASH_REMATCH[2]}"
|
||
|
else
|
||
|
echo "${red}Invalid episode specification: '$item'${reset}"
|
||
|
echo "${yellow}Use hprNNNN format with leading zeroes${reset}"
|
||
|
_usage 1
|
||
|
fi
|
||
|
|
||
|
_DEBUG "Dry run: $DRYRUN"
|
||
|
_DEBUG "Item chosen: $item"
|
||
|
|
||
|
#
|
||
|
# Check the item exists on the IA and if it does collect metadata and parse
|
||
|
# out the items we need.
|
||
|
#
|
||
|
_DEBUG "Testing IA for existence of $item"
|
||
|
if ia list "$item" > /dev/null 2>&1; then
|
||
|
ia metadata "$item" > "$TMP1"
|
||
|
|
||
|
# This one's an array but we want a CSV list.
|
||
|
# TODO: Not sure this works with tags containing spaces
|
||
|
# shellcheck disable=SC2046
|
||
|
subject="$(jq -r '.metadata.subject | @csv' "$TMP1")"
|
||
|
subject="${subject//\"\"\"/\"}"
|
||
|
|
||
|
creator="$(jq -r '.metadata.creator' "$TMP1")"
|
||
|
|
||
|
date="$(jq -r '.metadata.date' "$TMP1")"
|
||
|
|
||
|
_DEBUG "subject: $subject"
|
||
|
_DEBUG "creator: $creator"
|
||
|
_DEBUG "date: $date"
|
||
|
else
|
||
|
echo "${red}The requested item '$item' is not on archive.org${reset}"
|
||
|
exit 1
|
||
|
fi
|
||
|
|
||
|
#
|
||
|
# Either pretend to do stuff in dry-run mode or do it for real, but with
|
||
|
# confirmation first.
|
||
|
#
|
||
|
if [[ $DRYRUN -eq 1 ]]; then
|
||
|
echo "${yellow}Would have deleted item $item${reset}"
|
||
|
echo "Commands:"
|
||
|
echo "${blue}ia delete $item --all --no-backup${reset}"
|
||
|
echo "${blue}ia metadata $item --modify=title:\"Reserved\"${reset}"
|
||
|
echo "${blue}ia metadata $item --modify=description:\"Reserved\"${reset}"
|
||
|
echo "${blue}ia metadata $item --remove=creator:\"$creator\"${reset}"
|
||
|
echo "${blue}ia metadata $item --remove=date:$date${reset}"
|
||
|
echo "${blue}ia metadata $item --remove=subject:'$subject'${reset}"
|
||
|
echo
|
||
|
echo "${blue}Would have removed any cache entry found${reset}"
|
||
|
else
|
||
|
echo "${red}About to delete item $item.${reset}"
|
||
|
if yes_no "OK to continue? %s " "N"; then
|
||
|
# Not yet tested. Can't be until we have a need! Note that the quoted
|
||
|
# items will not be shown as such using this form of 'echo'.
|
||
|
# echo "Commands are being displayed, not run, until testing is complete"
|
||
|
#
|
||
|
# Now tested, and looking good
|
||
|
#
|
||
|
ia delete "$item" --all --no-backup
|
||
|
ia metadata "$item" --modify=title:"Reserved"
|
||
|
ia metadata "$item" --modify=description:"Reserved"
|
||
|
ia metadata "$item" --remove=creator:"$creator"
|
||
|
ia metadata "$item" --remove=date:"$date"
|
||
|
ia metadata "$item" --remove=subject:"$(printf "'%s'" "$subject")"
|
||
|
|
||
|
#
|
||
|
# Ensure the show is not marked as "processed" in the cache. We need
|
||
|
# 'grep' to determine if there's anything to do since 'sed' can't do
|
||
|
# this apparently.
|
||
|
#
|
||
|
if grep -q -E '^'"$item"'$' "$PROCFILE"; then
|
||
|
sed -i -e '/^'"$item"'$/d' "$PROCFILE"
|
||
|
echo "${yellow}$item removed from cache${reset}"
|
||
|
else
|
||
|
echo "${yellow}$item not found in cache${reset}"
|
||
|
fi
|
||
|
|
||
|
#
|
||
|
# Log this item
|
||
|
#
|
||
|
echo "$(date +%Y%m%d%H%M%S) deleted $item" >> "$LOGFILE"
|
||
|
else
|
||
|
echo "${red}Item not deleted. Aborting.${reset}"
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
# vim: syntax=sh:ts=8:sw=4:ai:et:tw=78:fo=tcrqn21
|