#!/usr/bin/env bash # Copyright Ken Fallon - Released into the public domain. http://creativecommons.org/publicdomain/ #============================================================ processing_dir="$HOME/tmp/hpr/processing" # The directory where the files will be copied to for processing if [ ! -d "${processing_dir}" ] then echo "ERROR: The application \"${this_program}\" is required but is not installed." exit 1 fi ################### # Check that all the programs are installed function is_installed () { for this_program in "$@" do if ! command -v ${this_program} 2>&1 >/dev/null then echo "ERROR: The application \"${this_program}\" is required but is not installed." exit 2 fi done } is_installed awk base64 cat curl curl date detox eval ffprobe file find grep grep head jq jq kate magick mediainfo mv mv rsync rsync seamonkey sed sed sort sponge ssh touch touch wget echo "Processing the next HPR Show in the queue" ################### # Get the show # # Replaced METADATA_PROCESSED with SHOW_SUBMITTED response=$( curl --silent --netrc-file ${HOME}/.netrc "https://hub.hackerpublicradio.org/cms/status.php" | \ grep 'SHOW_SUBMITTED' | \ head -1 | \ sed 's/,/ /g' ) if [ -z "${response}" ] then echo "INFO: There appear to be no more shows with the status \"SHOW_SUBMITTED\"." echo "Getting a list of all the reservations." curl --silent --netrc-file ${HOME}/.netrc "https://hub.hackerpublicradio.org/cms/status.php" | sort -n exit 3 fi timestamp_epoc="$( echo ${response} | awk '{print $1}' )" ep_num="$( echo ${response} | awk '{print $2}' )" ep_date="$( echo ${response} | awk '{print $3}' )" key="$( echo ${response} | awk '{print $4}' )" status="$( echo ${response} | awk '{print $5}' )" email="$( echo ${response} | awk '{print $6}' )" email_unpadded="$( echo $email | sed 's/.nospam@nospam./@/g' )" upload_dir="/home/hpr/upload/${timestamp_epoc}_${ep_num}_${ep_date}_${key}" source_dir="hpr:${upload_dir}" dest_dir="${timestamp_epoc}_${ep_num}_${ep_date}_${key}" ssh hpr -t "detox -v ${upload_dir}/" echo "INFO: Downloading hpr${ep_num} from ${email_unpadded}" echo "" echo rsync -ave ssh --partial --progress ${source_dir}/ ${processing_dir}/${dest_dir}/ rsync -ave ssh --partial --progress ${source_dir}/ ${processing_dir}/${dest_dir}/ echo "" echo "INFO: Working directory is \"${processing_dir}/${dest_dir}/\"" echo "" shownotes_json="${processing_dir}/${dest_dir}/shownotes.json" if [ ! -s "${shownotes_json}" ] then echo "ERROR: \"${shownotes_json}\" is missing" exit 4 fi if [ "$( file "${shownotes_json}" | grep -ic "text" )" -eq 0 ] then echo "ERROR: \"${shownotes_json}\" is not a text file" exit 5 fi mv -v "${shownotes_json}" "${shownotes_json%.*}_origional.json" jq '.' "${shownotes_json%.*}_origional.json" > "${shownotes_json}" ################### # Get the media # remote_media="$( jq --raw-output '.metadata.url' "${shownotes_json}" )" if [ -n "${remote_media}" ] then echo "INFO: Fetching remote media from \"${remote_media}\"" wget --timestamping --directory-prefix="${processing_dir}/${dest_dir}/" "${remote_media}" if [ $? -ne 0 ] then echo "ERROR: Could not get the remote media" exit 6 fi fi shownotes_html="${processing_dir}/${dest_dir}/shownotes.html" jq --raw-output '.episode.Show_Notes' "${shownotes_json}" > "${shownotes_html}" if [ ! -s "${shownotes_html}" ] then echo "ERROR: \"${shownotes_html}\" is missing" exit 7 fi # Process Shownotes sed "s#>#>\n#g" "${shownotes_html}" | sponge "${shownotes_html}" # Extract Images image_count="1" touch ${shownotes_html%.*}_combined.html for image in $( grep --color=never -Po 'data:image/[^;]*;base64,\K[a-zA-Z0-9+/=]*' "${shownotes_html}" ) do this_image="${processing_dir}/${dest_dir}/hpr${ep_num}_${image_count}" echo -n "$image" | base64 -di > ${this_image} this_ext="$( file --mime-type ${this_image} | awk -F '/' '{print $NF}' )" mv -v "${this_image}" "${this_image}.${this_ext}" this_width="$( mediainfo "${this_image}.${this_ext}" | grep Width | awk -F ': | pixels' '{print $2}' | sed 's/ //g' )" if [ "${this_width}" -gt "400" ] then magick "${this_image}.${this_ext}" -resize 400x "${this_image}_tn.${this_ext}" fi ((image_count=image_count+1)) done ## Manually edit the shownotes to fix issues kate "${shownotes_json}" >/dev/null 2>&1 & # librewolf "${shownotes_html}" >/dev/null 2>&1 & seamonkey "${shownotes_html}" >/dev/null 2>&1 & # bluefish "${shownotes_html}" >/dev/null 2>&1 & read -p "Does the metadata 'look ok ? (N|y) ? " -n 1 -r echo # (optional) move to a new line if [[ ! $REPLY =~ ^[yY]$ ]] then echo "skipping...." exit 8 fi media=$( find "${processing_dir}/${dest_dir}/" -type f -exec file {} \; | grep -Ei 'audio|mpeg|video|MP4' | awk -F ': ' '{print $1}' ) if [ -z "${media}" ] then echo "ERROR: Can't find any media in \"${processing_dir}/${dest_dir}/\"" find "${processing_dir}/${dest_dir}/" -type f exit 9 fi the_show_media="" if [ "$( echo "${media}" | wc -l )" -ne 1 ] then echo "Multiple files found. Which one do you want to use ?" select this_media in $( echo "${media}" ) do echo "INFO: You selected \"${this_media}\"." ls -al "${this_media}" the_show_media="${this_media}" break done else echo "INFO: Selecting media as \"${media}\"." the_show_media="${media}" fi duration=$( \date -ud "1970-01-01 $( ffprobe -i "${the_show_media}" 2>&1| awk -F ': |, ' '/Duration:/ { print $2 }' )" +%s ) if [ $? -ne 0 ] then echo 'ERROR: Invalid duration found in '\"${media}\" >&2 exit 10 fi ################### # Gather episode information # if [ "$( curl --silent --write-out '%{http_code}' http://hackerpublicradio.org/say.php?id=${ep_num} --output /dev/null )" == 200 ] then echo "ERROR: The Episode hpr${ep_num} has already been posted" exit 11 fi if [ "$( jq --raw-output '.metadata.Episode_Number' ${shownotes_json} )" != "${ep_num}" ] then echo "ERROR: The Episode_Number: \"${ep_num}\" was not found in \"${shownotes_json}\"" exit 12 fi if [ "$( jq --raw-output '.metadata.Episode_Date' ${shownotes_json} )" != "${ep_date}" ] then echo "ERROR: The Episode_Date: \"${ep_date}\" was not found in \"${shownotes_json}\"" exit 13 fi if [ "$( jq --raw-output '.host.Host_Email' ${shownotes_json} )" != "${email_unpadded}" ] then echo "ERROR: The Host_Email: \"${email_unpadded}\" was not found in \"${shownotes_json}\"" exit 14 fi ################### # Assemble the components # # https://newbedev.com/how-to-urlencode-data-for-curl-command/ hostid="$( jq --raw-output '.host.Host_ID' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' )" host_name="$( jq --raw-output '.host.Host_Name' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' )" title=$( jq --raw-output '.episode.Title' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' ) summary="$( jq --raw-output '.episode.Summary' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' )" series_id="$( jq --raw-output '.episode.Series' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' )" series_name="$( jq --raw-output '.episode.Series_Name' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' )" explicit="$( jq --raw-output '.episode.Explicit' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' )" episode_license="$( jq --raw-output '.episode.Show_License' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' )" tags="$( jq --raw-output '.episode.Tags' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' )" host_license=$( jq --raw-output '.host.Host_License' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' ) host_profile=$( jq --raw-output '.host.Host_Profile' ${shownotes_json} | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' ) # notes="$( grep -P ":\t" ${shownotes_txt} | awk -F "\t" '{print $2}' )" notes="$( cat "${shownotes_html}" | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' )" if [ $# -gt 0 ] then declare -A hash for argument do if [[ $argument =~ ^[^=]+=.*$ ]] then this_key="${argument%=*}" # "${} Kate format hack this_value="${argument#*=}" # "${} Kate format hack this_value="$( echo "${this_value}" | jq --slurp --raw-input @uri | sed -e 's/%0A"$//g' -e 's/^"//g' )" eval "${this_key}=${this_value}" echo "INFO: Replacing \"${this_key}\" with \"${this_value}\"." fi done fi if [ "${hostid}" == '0' ] then echo "ERROR: The hostid is 0. Create the host and use \"hostid=???\" to override" exit 15 fi ################### # Post show to HPR # post_show_json="${processing_dir}/${dest_dir}/post_show.json" post_show_response="${processing_dir}/${dest_dir}/post_show_response.txt" echo "Sending:" cat "${post_show}" echo "key=${key} ep_num=${ep_num} ep_date=${ep_date} email=${email} title=${title} duration=${duration} summary=${summary} series_id=${series_id} series_name=${series_name} explicit=${explicit} episode_license=${episode_license} tags=${tags} hostid=${hostid} host_name=${host_name} host_license=${host_license} host_profile=${host_profile} notes=${notes}" echo "{ \"key\": \"${key}\", \"ep_num\": \"${ep_num}\", \"ep_date\": \"${ep_date}\", \"email\": \"${email}\", \"title\": \"${title}\", \"duration\": \"${duration}\", \"summary\": \"${summary}\", \"series_id\": \"${series_id}\", \"series_name\": \"${series_name}\", \"explicit\": \"${explicit}\", \"episode_license\": \"${episode_license}\", \"tags\": \"${tags}\", \"hostid\": \"${hostid}\", \"host_name\": \"${host_name}\", \"host_license\": \"${host_license}\", \"host_profile\": \"${host_profile}\", \"notes\": \"${notes}\" }" | tee "${post_show_json}" echo "INFO: Uploading hpr${ep_num} from ${email_unpadded}" echo "" echo rsync -ave ssh --partial --progress ${processing_dir}/${dest_dir}/ ${source_dir}/ rsync -ave ssh --partial --progress ${processing_dir}/${dest_dir}/ ${source_dir}/ echo "" curl --netrc --include --request POST "https://hub.hackerpublicradio.org/cms/add_show_json.php" --header "Content-Type: application/json" --data-binary "@${post_show_json}"