#!/bin/bash
# /usr/local/bin/kkcr
# https://crystalfaeries.net/posix/bin/kkcr
# https://crystalfaeries.net/audio/kkcr/kkcr
# celeste:crystalfaery KKCR 2017-08-20 21:19:15+00:00
# Streamrip shows from KKCR (http://kkcr.org/) Kaua'i Community Radio.
# see also: script "subscriptions" which displays from your .crontab your set of KKCR subscriptions.
# First argument is number of minutes to rip; if null then rip until terminated and monitor relayed stream.
# Second argument is the show name for the saved file, else the file name is a timestamp.
# On BSD or Linux(TM) system you will probably only need to install streamripper if not already present.
# On MacOSuX systems you may need to also install cron, and change the "start_time=" line for nonGNU "date".
# On WinDblOwS you will need to install CygWin and use that to install cron and streamripper.
# NOTE: Not yet reviewed for XDG compliance, and likely depends on other crystalfaeries.net scripts.
# NOTE: the files we produce are named by their UTC start time, but time tagged their Local stop time.
# NOTE: DayOfWeek (DOW) 0=7=Sunday
# Uncomment (remove leading #) and add to your crontab any shows to which you wish to subscribe:
# DayOfMonth DayOfWeek KKCR schedule goes into crontab
#Minute Hour DOM Month DOW Command____________ Length KKCR_Show
#______ ____ __ __ _ ____________________ ___ ________________________________________
#00 00 * * * /usr/local/bin/kkcr 420 hawaiianmusic
#00 07 * * 1 /usr/local/bin/kkcr 120 mahalo_mondays
#00 07 * * 2 /usr/local/bin/kkcr 120 mele_no_ka_oi
#00 07 * * 3 /usr/local/bin/kkcr 120 himeni_o_hawai_i
#00 07 * * 4,5 /usr/local/bin/kkcr 120 aloha_kaua_i
#00 07 * * 6 /usr/local/bin/kkcr 120 classical
#00 07 * * 7 /usr/local/bin/kkcr 120 classical
#00 09 * * 1 /usr/local/bin/kkcr 120 kani_ka_pila
#00 09 * * 2 /usr/local/bin/kkcr 120 ano_ano
#00 09 * * 3 /usr/local/bin/kkcr 120 songs_of_sovereignty
#00 09 * * 4 /usr/local/bin/kkcr 120 kahea_kaua_i
#00 09 * * 5 /usr/local/bin/kkcr 120 kani_ka_pila
#00 09 * * 6 /usr/local/bin/kkcr 60 pets_and_people_in_paradise
#00 09 * * 7 /usr/local/bin/kkcr 60 new_dimensions
#00 10 * * 6 /usr/local/bin/kkcr 60 zucchini_brothers
#00 10 * * 7 /usr/local/bin/kkcr 120 oasis
#00 11 * * 1-5 /usr/local/bin/kkcr 60 democracy_now
#00 11 * * 6 /usr/local/bin/kkcr 120 na_leo_hawaiian_issues
#00 12 * * 1 /usr/local/bin/kkcr 60 health_talk+makai+olelo
#00 12 * * 2 /usr/local/bin/kkcr 120 island_roots
#00 12 * * 3 /usr/local/bin/kkcr 60 in_garden+on_farm
#00 12 * * 4 /usr/local/bin/kkcr 120 jungle_jukebox
#00 12 * * 5 /usr/local/bin/kkcr 60 diner_zoo2
#00 12 * * 7 /usr/local/bin/kkcr 60 sunday_show+tea
#00 13 * * 1 /usr/local/bin/kkcr 120 one_world_radio
#00 13 * * 3 /usr/local/bin/kkcr 120 kaua_i_vibrations
#00 13 * * 6 /usr/local/bin/kkcr 60 teen_radio
#00 13 * * 7 /usr/local/bin/kkcr 120 omnitorium
#00 14 * * 2 /usr/local/bin/kkcr 120 garden_isle_bluegrass
#00 14 * * 4 /usr/local/bin/kkcr 120 mu+ells_bells
#00 14 * * 5 /usr/local/bin/kkcr 120 mardi_gras_soul
#00 14 * * 6 /usr/local/bin/kkcr 120 rock_storyz
#00 15 * * 1 /usr/local/bin/kkcr 120 mischievous_mermaid+wonderland
#00 15 * * 3 /usr/local/bin/kkcr 120 pupule
#00 15 * * 7 /usr/local/bin/kkcr 120 ka_leo_ni_ihau
#00 16 * * 2 /usr/local/bin/kkcr 120 kaua_i_soapbox
#00 16 * * 4 /usr/local/bin/kkcr 120 out_of_the_box
#00 16 * * 5 /usr/local/bin/kkcr 120 rock+roll_happy_hour
#00 16 * * 6 /usr/local/bin/kkcr 120 saturday_rocks
#00 17 * * 1 /usr/local/bin/kkcr 60 mixed_plate
#00 17 * * 3 /usr/local/bin/kkcr 60 surf_stories
#00 17 * * 7 /usr/local/bin/kkcr 120 de_ja_blues
#00 18 * * 1 /usr/local/bin/kkcr 120 jazz
#00 18 * * 2 /usr/local/bin/kkcr 120 jazz
#00 18 * * 3 /usr/local/bin/kkcr 120 king_zor
#00 18 * * 4 /usr/local/bin/kkcr 120 evolve
#00 18 * * 5 /usr/local/bin/kkcr 120 domestic_disturbance
#00 18 * * 6 /usr/local/bin/kkcr 120 grateful_dead
#00 19 * * 7 /usr/local/bin/kkcr 60 kaua_i_reggae
#00 20 * * 1 /usr/local/bin/kkcr 120 rad_on_the_rock
#00 20 * * 2 /usr/local/bin/kkcr 120 blues
#00 20 * * 3 /usr/local/bin/kkcr 240 noodles
#00 20 * * 4 /usr/local/bin/kkcr 120 mystery_train
#00 20 * * 5 /usr/local/bin/kkcr 120 beat_box_time_machine
#00 20 * * 6 /usr/local/bin/kkcr 120 funk_odyssey
#00 20 * * 7 /usr/local/bin/kkcr 120 rastafari_reggae
#00 22 * * 1 /usr/local/bin/kkcr 120 hi_to_pi
#00 22 * * 2 /usr/local/bin/kkcr 120 blues
#00 22 * * 4 /usr/local/bin/kkcr 120 loco_moco
#00 22 * * 5 /usr/local/bin/kkcr 120 g_spot
#00 22 * * 6 /usr/local/bin/kkcr 120 late_to_the_party
#00 22 * * 7 /usr/local/bin/kkcr 120 because_of_h.i.m.
# CHECK THIS VERSUS http://kkcr.org/schedule.html
# CONFIGURATION:
streams_dir=/home/audio/streams # designated destination for streamripper (absolute path)
# if you edited above line, also edit the matching sed command at end of script
cd $streams_dir || exit -1 # is to be our working directory
# $streams_dir/KKCR Kaua`i Community Radio # actual streamripper directory for KKCR per their stream
kkcr_dir=$streams_dir/kkcr # ultimate destination once we name_tidy (symlink'd aliases)
kaqa_playlist="$kkcr_dir/kkcr.m3u" # KAQA playlist destination (generated in chronological order)
url='http://s1.phx.icastcenter.com/tunein/kkcr.pls' # KKCR url
let port=8009 # allocated relay port
let hysteresis=30 # necessary gap in seconds between shows for processing
start_time="`date -u --rfc-3339=seconds | sed 's/:[0-9][0-9]+00:00// ; s/ /./g ; s/:/-/'`" # sanitize the time
# ARGUMENTS:
if [ "$1" == "" ] # were we called with arguments?
then # We have a no arguments to define a "show"
show=`/usr/local/bin/now -h`
mkdir -p $kkcr_dir/$show || exit $?
echo "`/usr/local/bin/now` Started $show/$start_time" >> $kkcr_dir/.streamripper.txt
/usr/bin/streamripper $url -r $port -R 0 >> $kkcr_dir/$show/.streamripper.txt 2>&1 & # rip in background until a "rip_tidy" command
sleep ${hysteresis} # wait for streamrip to begin
mplayer http://127.0.0.1:$port # monitor live until manual quit
rsync -auvzH KKCR*/incomplete/*.mp3 $kkcr_dir/$show/$start_time.kkcr.mp3 >& /dev/null
rm KKCR*/incomplete/*.mp3 >& /dev/null
rmdir KKCR*/incomplete >& /dev/null
echo "`/usr/local/bin/now` Completed $show/$start_time" >> $kkcr_dir/.streamripper.txt
/usr/local/bin/rip_tidy # kill ALL rippers and clean up after them
echo "`/usr/local/bin/now` Rip_Tidied $show/$start_time" >> $kkcr_dir/.streamripper.txt
else # duration argument means rip with automatic ending
let duration="`echo $1 | tr -d -c '[:digit:]'`" # sanitize input argument integer number of minutes
let length=(60*"$duration")-"$hysteresis" # convert to seconds for streamripper's -l argument
show="$(echo ${2} | tr '[A-Z]' '[a-z]')" # lower case only (non ASCII char sets not handled)
# the new show file path gets e-mailed to the user via cron:
echo "Monitor the Fdeduped time of each show not run over into the next hour."
echo "Adjust accordingly the setting of "hysteresis" in $0"
echo $kkcr_dir/$show/$start_time.$show.mp3
# record the show:
mkdir -p $kkcr_dir/$show || exit $?
echo "`/usr/local/bin/now` Started $show/$start_time" >> $kkcr_dir/.streamripper.txt # debugging hysteresis setting
/usr/bin/streamripper $url -r $port -R 0 --quiet -l $length >> $kkcr_dir/$show/.streamripper.txt 2>&1 # rip in foreground until completion of show
rsync -auvzH KKCR*/incomplete/*.mp3 $kkcr_dir/$show/$start_time.$show.mp3 >& /dev/null \
&& rm KKCR*/incomplete/*.mp3 >& /dev/null \
&& rmdir KKCR*/incomplete >& /dev/null
echo "`/usr/local/bin/now` Completed $show/$start_time" >> $kkcr_dir/.streamripper.txt # debugging hysteresis setting
yes | /usr/local/bin/fdedupe >& /dev/null
echo "`/usr/local/bin/now` Fdeduped $show/$start_time" >> $kkcr_dir/.streamripper.txt # debugging hysteresis setting
rsync -auvzH /home/crystalfaeries.net/audio/kkcr/* divservi@box6537.bluehost.com:~/public_html/crystalfaeries.net/audio/kkcr #upload
echo "`/usr/local/bin/now` Uploaded $show/$start_time" >> $kkcr_dir/.streamripper.txt # debugging hysteresis setting
fi
# CLEAN-UP:
# remove error-free logs or e-mail error-logs:
find $kkcr_dir/ -name .streamripper.txt \( \( -size 0 -exec rm {} \; \) -o \( -print -exec cat {} \; \) \)
# remove empty directories:
find $kkcr_dir/ -depth -type d -exec rmdir {} \; >& /dev/null
# THE FOLLOWING COMMENTED-OUT CODE IS FOR LOCAL USE, PRESUMING WE HOLD THE SUPERSET OF FILES:
# generate new playlist with newest shows on top:
# cd $kkcr_dir
# we often use audacity to extract just preferred "songs" from a "program", thus
# we have not just streamrippers output .mp3 files, but also file formats we typically export from audacity:
# find $kkcr_dir/ \( -name '*.flac' -o -name '*.m4a' -o -name '*.mp4' -o -name '*.mp3' -o -name '*.oga' -o -name '*.ogg' \) -print | xargs ls -t 2>> $kkcr_dir/.streamripper.txt 1> $kkcr_playlist
# convert local-file based playlist to URL based playlist for the KAQA script
# sed 's/^\/home\/audio\/streams\/kkcr/http:\/\/crystalfaeries.net\/audio\/kkcr/g' < $kkcr_playlist > $kaqa_playlist
# THE FOLLOWING CODE IS FOR REMOTE SERVER USE, PRESUMING IT HOLDS THE SUPERSET OF FILES:
# Presuming we completed at the top of an hour, and then uploaded the latest files,
# We wait for the server to run its cronjob at 10 minutes after the hour,
# and then we can download the new playlists for local use.
sleep 900 # wait 15 minutes
rsync -auvzH divservi@box6537.bluehost.com:~/crystalfaeries.net/audio/kkcr/kkcr.m3u ${kkcr_dir}
echo "`/usr/local/bin/now` Playlists $show/$start_time" >> $kkcr_dir/.streamripper.txt
exit $? # pau for now
#
# KKCR streamripper while running looks like this:
#
# Here's listening live to the recording in progress:
# UID PID PPID C STIME TTY TIME CMD
# celeste 2702 19166 0 Jun18 pts/3 00:00:00 \_ /bin/bash
# celeste 10396 2702 0 18:02 pts/3 00:00:31 | \_ mplayer http://127.0.0.1:8009
# celeste 10525 10396 0 18:02 pts/3 00:00:01 | \_ mplayer http://127.0.0.1:8009
#
# Here's the cron-job running the streamrip:
# UID PID PPID C STIME TTY TIME CMD
# root 7616 602 0 18:00 ? 00:00:00 \_ /usr/sbin/CRON -f
# celeste 7618 7616 0 18:00 ? 00:00:00 \_ /bin/bash /usr/local/bin/kkcr 120 jazz
# celeste 7669 7618 0 18:00 ? 00:00:11 \_ /usr/bin/streamripper http://s1.phx.icastcenter.com/tunein/kkcr.pls -r 8009 -R 0 --quiet -l 7160
#
# /home/audio/streams:
# total 12
# lrwxrwxrwx 1 celeste celeste 20 Mar 25 08:33 kkcr -> /home/audio/www/kkcr/
# lrwxrwxrwx 1 celeste celeste 4 Mar 25 09:18 kkcr_kaua_i_community_radio -> kkcr/
# drwxrwsr-x 17 celeste celeste 4096 Jun 19 08:53 ../
# drwxr-sr-x 3 celeste celeste 4096 Jun 19 18:00 KKCR Kaua`i Community Radio/
# drwxrwsr-x 3 celeste celeste 4096 Jun 19 18:00 ./
#
# ./KKCR Kaua`i Community Radio:
# total 12
# drwxrwsr-x 3 celeste celeste 4096 Jun 19 18:00 ../
# drwxr-sr-x 3 celeste celeste 4096 Jun 19 18:00 ./
# drwxr-sr-x 2 celeste celeste 4096 Jun 19 18:00 incomplete/
#
# ./KKCR Kaua`i Community Radio/incomplete:
# total 97232
# drwxr-sr-x 3 celeste celeste 4096 Jun 19 18:00 ../
# drwxr-sr-x 2 celeste celeste 4096 Jun 19 18:00 ./
# -rw-r--r-- 1 celeste celeste 99550794 Jun 19 19:43 - .mp3
#
# After Clean-Up operations:
#
# /home/audio/kkcr:
# total 24
# drwxrwsr-x 3 celeste celeste 4096 Jun 19 20:01 ./
# drwxrwsr-x 37 celeste celeste 4096 Jun 18 20:13 ../
# drwxr-sr-x 2 celeste celeste 4096 Jun 19 20:00 jazz/
# -rw-r--r-- 1 celeste celeste 80 Jun 19 17:42 kkcr.m3u
# -rw-r--r-- 1 celeste celeste 380 Jun 19 20:00 .streamripper.txt
#
# ./jazz:
# total 111924
# drwxr-sr-x 2 celeste celeste 4096 Jun 19 20:00 ./
# drwxrwsr-x 3 celeste celeste 4096 Jun 19 20:01 ../
# -rw-r--r-- 1 celeste celeste 114591306 Jun 19 19:59 2017-06-20.04-00.jazz.mp3
# -rw-r--r-- 1 celeste celeste 0 Jun 19 18:00 .streamripper.txt
#
syntax highlighted by Code2HTML, v. 0.9.1