#!/bin/bash
# By Linc 10/1/2004
# Find the latest script at http://linc.homeunix.org:8080/scripts/bashpodder
# If you use this and have made improvements or have comments
# drop me an email at linc dot fessenden at gmail dot com
# I'd appreciate it!
#
# This revision by Brian Hefferan 2004/02/06, adding configuration options.
# No warranty. It seems to work for me, I hope it works for you.
# Questions /corrections on the additions by Brian Hefferan can be sent to
# brian at heftone  dot  com
#
# Further revision by Ryan Frishkorn 2008/01/19

# general settings
datadir="/media/mmc2/podcasts"
# configuration file (looks in home dir)
fetchlist="${HOME}/.bashpodderrc"
# lockfile
lockfile="${datadir}/.bashpodder_lock"
# logfile
logfile="${HOME}/.bashpodderlog"

#default values can be set here. Command-line flags override theses.
catchup_all=
first_only=
read_timeout=120
sync_disks=
unix2dos=
verbose=
wget_quiet='-q'  #default is -q
wget_continue=

function usage
{
  echo "
Usage: $0 [OPTIONS]
Options are:
-v, --verbose          display verbose messages. Also enables wget's continue
                      option.
--catchup_all          write all urls to the log file without downloading the
                      actual podcasts. This is useful if you want to subscribe
                      to some podcasts but don't want to download all the back
                      issues. You can edit the podcast log file afterwards to
                      delete any url you still wish to download next time
                      bashpodder is run.
--first_only           grab only the first new enclosed file found in each feed.
                      The --catchup_all flag won't work with this option. If
                      you want to download the first file and also permanently
                      ignore the other files, run bashpodder with this option,
                      and then run it again with --catchup_all.
--sync_disks           run the "sync" command twice when finished. This helps
                      makes sure all data is written to disk. Recommended if
                      data is being written directly to a portable player or
                      other removable media.
-u, --url_list         ignore conf file, instead use url(s) provided on the
                      command line. The urls should point to rss feeds.
                      If used, this needs to be the last option on the
                      command line. This can be used to quickly download just
                      a favorite podcast, or to take a few new podcasts for a
                      trial spin.
-h, --help             display this help message

"
}

# Lockfile functions
function create_lockfile
{
	echo -n "$$" > "$lockfile"
	if [ $? -ne 0 ]; then echo "WARNING: could not create lockfile - $lockfile"; fi
}

function remove_lockfile
{
	if [ -f "$lockfile" ]; then
		rm $lockfile
	fi
}

function check_lockfile
{
	if [ -f "$lockfile" ]; then
		# get pid from file
		pid=$(cat $lockfile)
		if [ -n "$verbose" ]; then echo "$@ is already running on pid $pid"; fi
		exit 1
	fi
}

if [ -n "$verbose" ]; then wget_quiet='';wget_continue='-c';fi
if test -f urls.temp;then rm urls.temp;fi

# Make script crontab friendly:
#cd $(dirname $0)
cd ~

while [ "$1" != "" ];do
   case $1 in
             -v|--verbose ) verbose=1
                            wget_continue='-c'
                            wget_quiet=''
                         ;;
            -u|--url_list ) shift
                            while [ "$1" != "" ];do
                               echo "$1" >> urls.temp
                               shift
                            done
                            if test ! -f urls.temp
                               then
                                   echo "Error: -u or --url_list option specified, but no urls given on command line. quitting."
                                   exit 1;
                            fi
                            fetchlist='urls.temp'
                         ;;
            --catchup_all ) catchup_all=1
                         ;;
             --first_only ) first_only=1
                         ;;
             --sync_disks ) sync_disks=1
                         ;;
                -h|--help ) usage
                            exit
                         ;;
   esac
   shift
done

# Check for lockfile
check_lockfile

# Create lockfile
create_lockfile

# Check for and create datadir if necessary:
if test ! -d $datadir
      then
      mkdir $datadir
fi

#if test ! -f "$fetchlist" && test ! -f urls.temp;
if [ ! -f "$fetchlist" ] && [ ! -f "urls.temp" ]; then
   echo "Sorry no config file found, and no urls in command line. Run $0 -h for usage."
   remove_lockfile
   exit
fi

# Read the config file and wget any url not already in the podcast.log file:
# remove comments first
grep -v "^[#;]" $fetchlist | while read podcast
      do
	  # seperate dir from podcast url
	  podcast_dir=$(echo $podcast | cut -d '|' -f 1 | tr ' ' _)
	  podcast_num=$(echo $podcast | cut -d '|' -f 2)
	  podcast_url=$(echo $podcast | cut -d '|' -f 3)
	  # create dir for podcast if not present
	  if test ! -d "${datadir}/${podcast_dir}"
			then
			mkdir "${datadir}/${podcast_dir}"
	  fi

      seenfirst=
      if [ -n "$verbose" ]; then
          echo
          echo "Updating $podcast_dir"
          echo "fetching rss $podcast_url..."
      fi
      for url in $(wget -q "$podcast_url" -O - | tr '\r' '\n' | tr \' \" | \
                   sed -n 's/.*url *= *"\([^"]*\)".*/\1/p' )
              do
          if [ -n "$first_only" ] && [ -n "$seenfirst" ]; then break;fi
          echo $url >> temp.log
          if [ -n "$catchup_all" ];
          then
              if [ -n "$verbose" ]; then echo " catching up $url...";fi
          elif   ! grep "$url" "$logfile" > /dev/null ;
          then
             if [ -n "$verbose" ]; then echo "  downloading $url...";fi
             wget $wget_continue $wget_quiet --read-timeout=${read_timeout} -P "${datadir}/${podcast_dir}" "$url"
          fi
		  
          seenfirst=1
      done

	  # remove old podcasts
	  if [ $podcast_num -ne 0 ]; then
		  present=$(ls -1 "${datadir}/${podcast_dir}" | grep -v 'm3u' | wc -l)
		  if [ $present -gt $podcast_num ]; then
			  let remove=$present-$podcast_num
			  echo "pruning podcasts to $podcast_num most recent..."

			  # remove the files
			  for file in $(ls -1tc "${datadir}/${podcast_dir}" | grep -v 'm3u' | tail -n $remove)
			  do
				  echo "Removing \"${datadir}/${podcast_dir}/$file\""
				  rm "${datadir}/${podcast_dir}/$file"
			  done
		  fi
	  fi
done

if test ! -f temp.log && [ -n "$verbose" ];then echo "nothing to download.";fi

if test -f urls.temp; then rm urls.temp;fi

# Move dynamically created log file to permanent log file:
cat "$logfile" >> temp.log
sort temp.log | uniq > "$logfile"
rm temp.log

# Create an m3u playlist for each podcast:
for dir in $(ls $datadir)
	do
		ls -1rc "${datadir}/${dir}" | grep -v m3u > "${datadir}/${dir}/${dir}.m3u"
		#if [ -n "$unix2dos" ];then unix2dos "${datadir}/${dir}/${dir}.m3u";fi;
done

if [ -n "$sync_disks" ]
then
    if [ -n "$verbose" ]; then echo "running sync..";fi;
    sync
    if [ -n "$verbose" ]; then echo "running sync again..";fi;
    sync
fi

# Remove lockfile
remove_lockfile

if [ -n "$verbose" ]; then echo "done.";fi;

