#!/usr/bin/env bash
# ----------------------------------------------------------------------------------------------------------------------------------
# Filename:      podget                                                                                                          {{{
# Maintainer:    Dave Vehrs <davevehrs(at)users.sourceforge.net>
# Created:       05 Mar 2005 09:35:44 PM
# Last Modified: 17 May 2014 12:21:39 PM by Dave Vehrs
# Copyright:     (c) 2005,2006,2007,2008,2009,2010,2011,2012,2013,2014 Dave Vehrs
#
#                This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
#                License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any
#                later version.
#
#                This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
#                warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
#                details.
#
# Description:   Podget is a simple bash script to automate the downloading and
#                organizing of podcast content.
# Dependencies:  bash, coreutils, grep, libc6 (for iconv), sed, tofrodos (unix2dos for ASX Playlists) and wget.
# Installation:  cp podget.sh /usr/local/bin
#                chmod 755 /usr/local/bin/podget.sh                                                                              }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Exit Codes                                                                                                                     {{{

# "Reserved" Exit codes
# 1     General Error
# 2     Misuse of shell built-ins
# 126   Command invoked cannot execute
# 127   Command not found
# 128   Invalid argument to exit
# 130   Script terminated by Control-C

# "Our" Exit codes

# Display Help (set to '0' because it is an valid exit condition, just not an error.)
err_displayhelp=0

# Library directory not defined.
err_libnotdef=50

# Library directory available space below limit
err_liblowspace=51

# Libc6 not installed.  Cannot convert UTF16 feeds.
err_libc6notinstalled=60

# Another running session already exists.
err_runningsession=70

# OPML import error.
err_importopml=80

# OPML export error.
err_exportopml=90

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Help text and default file formats                                                                                             {{{

: << HELP_STEXT
    -c --config <FILE>           Name of configuration file.
    -C --cleanup                 Skip downloading and only run cleanup loop.
    --cleanup_simulate           Skip downloading and simulate running
                                 cleanup loop.
                                 Display files to be deleted.
    --cleanup_days               Number of days to retain files.  Anything
                                 older will be removed.
    -d --dir_config <DIRECTORY>  Directory that configuration files are
                                 stored in.
    --dir_session <DIRECTORY>    Directory that session files are stored in.
    -f --force                   Force download of items from each feed even
                                 if they have already been downloaded.
    --import_opml <FILE or URL>  Import servers from OPML file or
                                 HTTP/FTP URL.
    --export_opml <FILE>         Export serverlist to OPML file
    --import_pcast <FILE or URL> Import servers from iTunes PCAST file or
                                 HTTP/FTP URL.
    -l --library <DIRECTORY>     Directory to store downloaded files in.
    -n --no-playlist             Do not create M3U playlist
    -p --playlist-asx            In addition to the default M3U playlist,
                                 create an ASX Playlist.  M3U playlist must be
                                 created to convert to ASX.
    --playlist-per-podcast       Create playlist for each podcast feed
    -r --recent <count>          Download only the <count> newest items from
                                 each feed.
    --serverlist <list>          Serverlist to use.
    -s --silent                  Run silently (for cron jobs).
    --verbosity <LEVEL>          Set verbosity level (0-4).
    -v                           Set verbosity to level 1.
    -vv                          Set verbosity to level 2.
    -vvv                         Set verbosity to level 3.
    -vvvv                        Set verbosity to level 4.
    -h --help                    Display help.
HELP_STEXT

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Defaults                                                                                                                       {{{

     #########################################################################################################################
     ## Do not configure here.  Run podget once to install default user configuration files ($HOME/.podget) and edit those. ##
     #########################################################################################################################

# Set dir_session, dir_cache, dir_install, dir_log, dir_temp in config file.
dir_config="${HOME}/.podget"
config_core="podgetrc"
config_serverlist="serverlist"

# Default VERBOSITY
#  0 == silent
#  1 == Warning messages only.
#  2 == Progress and Warning messages.
#  3 == Debug, Progress and Warning messages.
#  4 == All messages and wget set to maximum VERBOSITY.
VERBOSITY=2

# Silent mode (for calling from cron jobs)
# 0 == normal
# 1 == suppress all messages
silent=0

# Auto-Cleanup.
# 0 == disabled
# 1 == delete any old content
cleanup=0

# Skip downloading and just run cleanup
# 0 == disable
cleanup_only=0

# Simulate cleanup
cleanup_simulate=0

# Number of days to keep files.   Cleanup will remove anything
# older than this.
cleanup_days=7

# Most Recent
# 0  == download all new items.
# 1+ == download only the <count> most recent
most_recent=0

# Force
# 0 == Only download new material.
# 1 == Force download all items even those you've downloaded before.
force=0

# Install session.  This gets called when script is first installed.
install_session=0

# Fix filenames for FAT32 compatibility
modify_filename=0

# Fix downloaded file names of format filename.mp3?1232456 to filename123456.mp3
filename_formatfix=1

# Filename Cleanup 3:  Fix filenames from feeds downloaded from LBC Plus.
filename_formatfix2=1

# Filename Cleanup 4:
filename_formatfix3=1

# Filename Cleanup 5:
filename_formatfix4=0

# Filename Cleanup 6:
filename_formatfix5=1

# Filename Cleanup 7:
filename_formatfix6=1

# Filename Cleanup 8:
filename_formatfix7=1

# Filename Cleanup 9:
filename_formatfix8=1

# Filename Cleanup 10:
filename_formatfix9=1

# Stop downloads if available space drops below
min_space=10000

# Date format for new playlist names
date_format=+%F

# ASX Playlists for Windows Media Player
# 0 == do not create
# 1 == create
asx_playlist=0

# Enable playlist creation
no_playlist=0

     #########################################################################################################################
     ## Do not configure here.  Run podget once to install default user configuration files ($HOME/.podget) and edit those. ##
     #########################################################################################################################

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Text for default configuration files:                                                                                          {{{

: << TEXT_DEFAULT_CONFIG
# -----------------------------------------------------------------------------
# Podget configuration file created by verison @VERSION@
# [ NOTE:  Do not delete version line as it will be used by future versions to
#          to test if configuration files have been updated with any required changes.
# -----------------------------------------------------------------------------
# File name and location configuration:

# Name of Server List configuration file
config_serverlist=@SERVERLIST@

# Directory to store session files
dir_session=/tmp/podget

# Directory where to store downloaded files
dir_library=@HOME@/POD

# Directory to store logs in
# dir_log=@HOME@/POD/LOG

# Set logging file names
log_fail=errors
log_comp=done

# -----------------------------------------------------------------------------
# Download Options:

# Wget base options
# Commonly used options:
#   -c                          Continue interupted downloads
#   -nH                         No host directories (overrides .wgetrc defaults if necessary)
#   --proxy=off                 To disable proxy set by environmental variable http_proxy/
#   --no-check-certificate      To disable HTTPS certificate checks.  Useful for sites that may
#                                   be using self-signed cerficates and not those from a trusted
#                                   service authority.
#wget_baseopts=-c --proxy=off --no-check-certificate
wget_baseopts=-c -nH

# Most Recent
# 0  == download all new items.
# 1+ == download only the <count> most recent
most_recent=0

# Force
# 0 == Only download new material.
# 1 == Force download all items even those you've downloaded before.
force=0

# Autocleanup.
# 0 == disabled
# 1 == delete any old content
cleanup=0

# Number of days to keep files.   Cleanup will remove anything
# older than this.
cleanup_days=7

# Stop downloading if available space on the partition drops below value (in KB)
# default:  614400 (600MB)
min_space=614400

# -----------------------------------------------------------------------------
# Playlist Options:

# Disable playlist creation [ No need to comment out other playlist variables ]
# 0 == create
# 1 == do not create
no_playlist=0

# Build playlists (comment out or set to a blank string to accept default format: New-).
playlist_namebase=New-

# Date format for new playlist names
# +%f        = YYYY-MM-DD  like 2014-01-15  (DEFAULT)
# +%m-%d-%Y  = MM-DD-YYYY  like 01-15-2014
# For other options 'man date'
date_format=+%F

# ASX Playlists for Windows Media Player
# 0 == do not create
# 1 == create
asx_playlist=0

# -----------------------------------------------------------------------------
# Filename Cleanup Options:

# Filename Cleanup: For FAT32 filename compatability (Feature Request #1378956)
# Tested with the following characters: !@#$%^&*()_-+=||{[}]:;"'<,>.?/
#
# The \ character needs to be escaped by itself or the system may interpret it as
# escaping the newline character that comes after it, which would then be included in
# the filename_badchars to be tested.
#
filename_badchars=!#$^&=+{}[]:;"'<>?|\\

# Filename Replace Character: Character to use to replace any/all
# bad characters found.
filename_replacechar=_

# When you run podget at a VERBOSITY of 3 or 4, it may appear that the filename format fixes are done out of order.  That is because
# they are named as they are created and as new fixes have been developed, those with more detailed exclusionary conditions have had
# to be done before those with more generic conditions.  Looking for improvements to fix this issue.

# Filename Cleanup 2:  Some RSS Feeds (like the BBC World News Bulletin)
# download files with names like filename.mp3?1234567.  Enable this mode
# to fix the format to filename1234567.mp3.
# 0 == disabled
# 1 == enabled (default)
filename_formatfix=1

# Filename Cleanup 3: Filenames of feeds hosted by LBC Plus corrupted.
# Fixed per MoonUnit's feature request (#1660764)
#
# Takes an URL that looks like:  http://lbc.audioagain.com/shared/audio/stream.mp3?guid=2007-03/14<...snip>
#                            <snip...>a7766e8ad2748269fd347eaee2b2e3f8&amp;source=podcast.php&amp;channel_id=88
#
# Which normally creates a file named: a7766e8ad2748269fd347eaee2b2e3f8&amp;source=podcast.php&amp;channel_id=88
#
# This fix extracts the date of the episode and changes the filename to 2007-03-14.mp3
# 0 == disabled
# 1 == enabled (default)
filename_formatfix2=1

# Filename Cleanup 4: Filenames of feeds hosted by CatRadio.cat need fixing.
# Fixed per Oriol Rius's Bug Report (#1744705)
#
# Downloaded filenames look like: 1189153569775.mp3?programa=El+mat%ED+de+Catalunya+R%E0dio&amp;podcast=y
# This fix removes everything after the .mp3
#
# 0 == disabled
# 1 == enabled (default)
filename_formatfix3=1

# Filename Cleanup 5:  When the filename is part of the URL and the actual filename stays the same for
# all items listed.
#
# Download URLs look like: http://feeds.theonion.com/~r/theonion/radionews/~5/213589629/podcast_redirect.mp3
# Where 213589629 is the unique filename.
#
# This filename change is disabled by default because it may cause unintended changes to the filename.
#
# 0 == disabled (default)
# 1 == enabled
filename_formatfix4=0

# Filename Cleanup 6: Remove "?referrer=rss" from the end of filenames as included in some feeds like
# those from Vimcasts.org.  Setup to work for MP3, M4V, OGG and OGV files.
#
# Feed URLs: http://vimcasts.org/feeds/ogg
#            http://vimcasts.org/feeds/quicktime
#
# In the feed, enclosure URLs look like: http://media.vimcasts.org/videos/1/show_invisibles.ogv?referrer=rss
#
# 0 == disabled
# 1 == enabled (default)
filename_formatfix5=1

# Filename Cleanup 7:  Removes the trailing part of the filename after the '?'.
# Fixed at the request of Joerg Schiermeier
#
# For dealing with enclosures like those formatted in the ZDF podcast.
# Feed URL: http://www.zdf.de/ZDFmediathek/podcast/1193018?view=podcast
# Example enclosure:
# http://podfiles.zdf.de/podcast/zdf_podcasts/101103_backstage_afo_p.mp4?2010-11-03+06-42
#
# 0 == disabled
# 1 == enabled (default)
filename_formatfix6=1

# Filename Cleanup 8:
# This fix is for feeds that assign the same filename to be downloaded for each
# enclosure and then embedded the actual filename of the object to be saved in
# the media_url= parameter.  This fix extracts that name and uses it for the
# saved file.
#
# 0 == disabled
# 1 == enabled (default)
filename_formatfix7=1

# Filename Cleanup 9:
# This fix is for feeds like Smodcast.  It removes the "?client_id=<string>"
# from the end of each enclosure url in the feed.
#
# NOTE:  To fully fix the filenames on feeds like Smodcast, this fix should
# be used in conjunction with filename_formatfix4.
#
# Example URL: http://api.soundcloud.com/tracks/62837276/stream.mp3?client_id=a427c512429c9c90e58de7955257879c
# Fixed filename: 62837276_stream.mp3
#
# 0 == disabled
# 1 == enabled (default)
filename_formatfix8=1

# Filename Cleanup 10:
#
# This is a fix for podcast feeds formatted like those for Audioboo.  Removes everything after the ?
# in the filename.  Attempted to make this fix generic enough to work with a variety of feeds of mp3, mp4,
# ogg and ogv files.
#
# Feed URL: http://audioboo.fm/users/39903/boos.rss
# Example URL: http://audioboo.fm/boos/1273271-mw-123-es-wird-fruhling.mp3?keyed=true&amp;source=rss
# Fixed Filename: 1273271-mw-123-es-wird-fruhling.mp3
#
# 0 == disabled
# 1 == enabled (default)
filename_formatfix9=1

# Filename Cleanup 11:
#
# This is an attempt to fix feeds hosted on Apple ITunes.  The enclosure URL from these feeds defines the
# the filename as a long string of numbers and letter.  It's not very descriptive.  However, after the
# filename and a '?', in the information passed down to the application as part of the URL, we can
# extract the episode name for each podcast.  It is that name that this fix will use for the filename,
# with a few character replacements to insure good filenames.
#
# 0 == disabled
# 1 == enabled (default)
filename_formatfix10=1
# -----------------------------------------------------------------------------
TEXT_DEFAULT_CONFIG

: << TEXT_DEFAULT_SERVERLIST
# Default Server List for podget
#
# FORMAT:    <url> <category> <name>
#
# NOTES:
#    1. URL Rules:
#      A. Any spaces in the URL need to be converted to %20
#    2. Category Rules:
#      A.  Must be one word without spaces.
#      B.  You may use underscores and dashes.
#      C.  You can insert date substitions.
#          %YY%  ==  Year
#          %MM%  ==  Month
#          %DD%  ==  Day
#    3. Name Rules:
#      A.  If you are creating ASX playlists, make sure the feed name does not
#          have any spaces in it and the filename cannot be blank.
#      B.  You can leave the feed name blank, and files will be saved in the
#          category directory.
#      C.  Names with spaces are only compatible with filesystems that allow for spaces
#          in filenames.  For example, spaces in feed names are OK for feeds saved to
#          Linux ext partitions but are not OK for those saved to Microsoft FAT partitions.
#    4. Disable the downloading of any feed by commenting it out with a leading #.
#
# Examples:
#   http://www.lugradio.org/episodes.rss Linux LUG Radio
#
# Example with date substitution in the category and a blank feed name:
#   http://downloads.bbc.co.uk/rmhttp/downloadtrial/worldservice/summary/rss.xml News-%YY%-%MM%-%DD%
#
# Example of two ways to do a feed with authentication:
#   http://somesite.com/feed.rss CATEGORY Feed Name USER:username PASS:password
#     OR
#   http://username:password@somesite.com/feed.rss CATEGORY Feed Name
#
#   NOTE:   The second method will fail if a colon (:) is part of the username or password.
#           Both methods will fail if a space is part of the username or password.
#
http://thelinuxlink.net/tllts/tllts.rss LINUX The Linux Link
TEXT_DEFAULT_SERVERLIST

: << TEXT_ASX_BEGINNING
<ASX version = "3.0">
        <PARAM NAME = "Encoding" VALUE = "UTF-8" />
        <PARAM NAME = "Custom Playlist Version" VALUE = "V1.0 WMP8 for CE" />
TEXT_ASX_BEGINNING

: << TEXT_ASX_END
</ASX>
TEXT_ASX_END

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Functions                                                                                                                      {{{

function display_shelp {
	echo; echo "Usage $0 [options]"; echo
	sed --silent -e '/HELP_STEXT$/,/^HELP_STEXT/p' "$0" | sed -e '/HELP_STEXT/d'
}

# Function: filenameFixFormat ${1} ${2}
# Arguments:
# ${1} == name of variable to hold return string
# ${2} == string to fix the format of
function filenameFixFormat() {
    # variable to hold returned value.
    local var_return=${1}

    # Set original value for filename format fixes and character substitutions.
    # Set according to what is passed as the second argument to function.
    local modified_filename=${2}


    if [ ${filename_formatfix} -gt 0 ] || [ ${filename_formatfix2} -gt 0 ] || [ ${filename_formatfix3} -gt 0 ] ||
       [ ${filename_formatfix4} -gt 0 ] || [ ${filename_formatfix5} -gt 0 ] || [ ${filename_formatfix6} -gt 0 ] ||
       [ ${filename_formatfix7} -gt 0 ] || [ ${filename_formatfix8} -gt 0 ] || [ ${filename_formatfix9} -gt 0 ] ||
       [ ${filename_formatfix10} -gt 0 ]; then
        if [ ${VERBOSITY} -ge 3 ] ; then
           echo "ORIGINAL FILENAME:        ${modified_filename}"
        fi
    fi

    # Note:  Filename format fixes that have more specific conditions come first.  More generic last.  This is
    # because a fix with too liberal a condition can prevent a more specific fix from running.  Fixes are named in
    # the order they were created, so it may appear that they are out of order.  By changing the order that they are
    # executed in, it is possible to have more enabled by default.
    #
    # TODO: Create exclusionary conditions for the fixes that are out of order to restore sanity to this list.
    #
    # filename_formatfix has been moved to the end of the order.
    #
    # filename_formatfix4 is not part of this function and is called immediately after this function ends.

    # Filename format fix for podcasts hosted on http://lbc.audioagain.com.
    if [ ! -z ${filename_formatfix2} ] && [ ${filename_formatfix2} -gt 0 ] ; then
        if [ $(expr "${modified_filename}" : "[0-9a-zA-Z]\+[&]amp;source=podcast.php[&]amp;channel_id=[0-9]\+\$") -gt 0 ] ; then
            modified_filename=$(echo ${url} | sed 's/.*stream.mp3[?]guid=\([0-9]\+\)-\([0-9]\+\)\/\([0-9]\+\)\/.*/\1-\2-\3.mp3/')
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "FILENAME FORMAT(2) FIXED: $modified_filename"
            fi
        fi
    fi

    # Filename format fix for podcasts hosted on http://www.catradio.cat
    if [ ! -z ${filename_formatfix3} ] && [ ${filename_formatfix3} -gt 0 ] ; then
        if [ $(expr "${modified_filename}" : "[0-9]\+\.mp3\?[\\?]programa=[0-9a-Z+=%&;]*\$") -gt 0 ] ; then
            modified_filename=$(echo ${modified_filename} | sed 's/\(.*\)\.mp3\(.*\)/\1\.mp3/g')
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "FILENAME FORMAT(3) FIXED: $modified_filename"
            fi
        fi
    fi

    # Remove "?referrer=rss" from filename as included with some feeds like Vimcasts.org
    if [ ! -z ${filename_formatfix5} ] &&  [ ${filename_formatfix5} -gt 0 ] ; then
        if [ $(expr "${modified_filename}" : "[-0-9a-zA-Z_]\+\.[gmopv34]\+[?]referrer=rss") -gt 0 ] ; then
            modified_filename=$(echo ${modified_filename} | sed -r 's/([-A-Za-z0-9_]+.[ogmpv34]+)[?]referrer=rss/\1/g')
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "FILENAME FORMAT(5) FIXED: $modified_filename"
            fi
        fi
    fi

    # ZDF podcast filename fix
    if [ ! -z ${filename_formatfix6} ] && [ ${filename_formatfix6} -gt 0 ] ; then
        if [ $(expr "${modified_filename}" : "[-_0-9a-zA-Z]\+\.[gmopv34]\+[?][-_+0-9]\+") -gt 0 ] ; then
            modified_filename=$(echo ${modified_filename} | sed -ru 's/([-_A-Za-z0-9]+.[ogmpv3-4]+)[?][-+0-9]*/\1/g')
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "FILENAME FORMAT(6) FIXED: $modified_filename"
            fi
        fi
    fi

    # media_url cleanup
    # This fix was inspired by the Radio France podcast feed.  Each enclosure URL in the feed had the same filename
    # specified to be downloaded, and the actual filename of the MP3 file was appended in the media_url variable.
    # This fix extracts that filename and uses it for the downloaded file.
    #
    # Filename consists of: numbers, letters, dashes, underscore, plus, percent, equals, question mark, ampersand, and period
    # with extended regex and buffers limited
    # wget -O - http://radiofrance-podcast.net/podcast09/rss_12036.xml | grep enclosure | sed -ru 's/.*(media_url=.*[.][gmopv34]+)"\ .*/\1/' | sed -ru 's/.*%2F([-0-9A-Za-z_.]+[.][gmopv34]+)/\1/'
    if [ ! -z ${filename_formatfix7} ] && [ ${filename_formatfix7} -gt 0 ] ; then
        if [ $(expr "${modified_filename}" : "[+_%&=?.0-9a-zA-Z]*media_url=http") -gt 0 ] ; then
            modified_filename=$(echo ${modified_filename} | sed -ru 's/.*(media_url=http.*[.][gmopv34]+)"\ .*/\1/' | sed -ru 's/.*%2F([-0-9A-Za-z_.]+[.][gmopv34]+)/\1/')
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "FILENAME FORMAT(7) FIXED: $modified_filename"
            fi
        fi
    fi

    # SMODCAST cleanup
    # Remove "?client_id=<string>" from filename.
    #
    # Note: This is only the first part of the cleanup needed for the SMODCAST feeds.  These removes the trailing portion of the
    # enclosure URL but every filename is left as "stream.mp3".  The distinguishing part of each URL is held one segment before the
    # filename and so filename_formatfix4 must also be enabled.  This can potentially affect other feeds and so it may be desirable
    # to separate these feeds to their own configuration and serverlist files.  They can then be loaded by using the -c and
    # --serverlist flags on the command line.
    if [ ! -z ${filename_formatfix8} ] && [ ${filename_formatfix8} -gt 0 ] ; then
        if [ $(expr "${modified_filename}" : "stream[.]mp3[?]client_id=[0-9a-zA-Z]\+") -gt 0 ] ; then
            modified_filename=$(echo ${modified_filename} | sed -ru 's/(stream[.]mp3)[?]client_id=[0-9A-Za-z]+/\1/')
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "FILENAME FORMAT(8) FIXED: $modified_filename"
            fi
        fi
    fi

    # Audioboo Filename Cleanup.
    # Enclosure URLs hav "?keyed=true&amp;source=rss" appended to them.  This fix removes that string.
    # It should work for Audioboo podcasts and others with similar formating.
    if [ ! -z ${filename_formatfix9} ] && [ ${filename_formatfix9} -gt 0 ]; then
        if [ $(expr "${modified_filename}" : "[-_0-9A-z]\+[.][gmopv34]\+[?][%&;=0-9a-zA-Z]\+") -gt 0 ] ; then
            modified_filename=$(echo ${modified_filename} | sed -ru 's/([-_A-Za-z0-9]+[.][ogmpv3-4]+)[?][%&;=A-Za-z0-9]+/\1/g')
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "FILENAME FORMAT(9) FIXED: $modified_filename"
            fi
        fi
    fi

    # MP3 on Apple ITunes
    # Filenames are generally long strings of numbers and letters, with the actual episode name being defined after the '?'
    # This extracts the episode name and uses it for the filename.
    if [ ! -z ${filename_formatfix10} ] && [ ${filename_formatfix10} -gt 0 ]; then
        if [ $(expr "${modified_filename}" : "[-0-9A-Za-z_]\+[.][MmPp3]\+[?][-0-9A-Za-z%=]\+%26episodeName%3D[-0-9A-Za-z%.*]\+%26episodeKind%3D") -gt 0 ] ; then
            modified_filename=$(echo ${modified_filename} | sed -ru 's/.*%26episodeName%3D([-._%A-Za-z0-9*]+)%26episodeKind[-%&;=A-Za-z0-9]+/\1.mp3/g' | sed -ru 's/%2B/_/g;s/%25[0-9ACF]{2}//g;s/[*]//g')
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "FILENAME FORMAT(10) FIXED: $modified_filename"
            fi
        fi
    fi

    # Fix improperly formated filenames (fixes filename.mp3?123456 to filename123456.mp3)
    if [ ! -z ${filename_formatfix} ] && [ ${filename_formatfix} -gt 0 ] ; then
        if [ $(expr "${modified_filename}" : ".*\.mp3..*$") -gt 0 ] ; then
            modified_filename=$(echo ${modified_filename} | sed 's/\.mp3\(.*\)/\1.mp3/')
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "FILENAME FORMAT FIXED: $modified_filename"
            fi
        fi
    fi


    # Test for filename modifications.
    if [ ! -z ${modify_filename} ] && [ ${modify_filename} -gt 0 ] ; then
        for character in ${filename_badchars} ; do
            modified_filename=$(echo "$modified_filename" | sed -e "s/[\\${character}]/${filename_replacechar}/g")
        done
        if [ ${VERBOSITY} -ge 3 ] ; then
            echo "MODIFIED FILENAME: $modified_filename"
        fi
    fi

    # Pass the modified filename back to the calling variable.
    eval "${var_return}='${modified_filename}'"

    # close without error
    return 0
}

function PLAYLIST_ConvertToASX() {
    local DIR_Library=${1}
    local M3U_PlaylistName=${2}
    ASX_LOCATION="\\SD Card\\POD\\"
    ASX_PlaylistName=`basename ${DIR_Library}/${M3U_PlaylistName} .m3u`.asx
    sed --silent -e '/TEXT_ASX_BEGINNING$/,/^TEXT_ASX_BEGINNING/p' "$0" |
      sed -e '/TEXT_ASX_BEGINNING/d' > ${DIR_Library}/${ASX_PlaylistName}

    while read line ; do
      local fixed_entry=$(echo ${line} | sed 's/\//\\/g')
      echo '    <ENTRY>' >> ${DIR_Library}/${ASX_PlaylistName}
      echo "        <ref href = \"${ASX_Location}${fixed_entry}\" />" >> ${DIR_Library}/${ASX_PlaylistName}
      echo "        <ref href = \".\\${fixed_entry}\" />" >> ${DIR_Library}/${ASX_PlaylistName}
      echo '    </ENTRY>' >> ${DIR_Library}/${ASX_PlaylistName}
    done < ${DIR_library}/${M3U_PlaylistName}

    sed --silent -e '/TEXT_ASX_END$/,/^TEXT_ASX_END/p' "$0" |
      sed -e '/TEXT_ASX_END/d' >> ${DIR_Library}/${ASX_PlaylistName}

    unix2dos -d ${DIR_Library}/${ASX_PlaylistName}

}

function PLAYLIST_Sort() {
    local DIR_Library=${1}
    local M3U_PlaylistName=${2}
    local realPlaylistName="$DIR_Library/$M3U_PlaylistName"

    # Sort Playlist
    unset tempPlaylistName
    local tempPlaylistName=$(mktemp 2>/dev/null)
    # Test if 'mktemp' was able to create the temporary file name,
    # if not use 'tempfile'
    if [ -z "${tempPlaylistName}" ]; then
        local tempPlaylistName=$(tempfile 2>/dev/null)
    fi
    # Test if temporary file name is set, if not skip sorting.
    if [ -z "${tempPlaylistName}" ]; then
        echo "Error: Niether mktemp or tempfile found.  Unable to sort playlist."
    else
        cp -p "$realPlaylistName" "$tempPlaylistName" && sort -o "$realPlaylistName" "$tempPlaylistName" && rm "$tempPlaylistName"
    fi

    unset realPlaylistName tempPlaylistName
}

function COMPARE_StringInString() {
    echo "Enter Compare ..."
    echo "1 == ${1}"
    echo "2 == ${2}"
    case "${2}" in
        *"${1}" )
            echo "Found!"
            return 0
            ;;
    esac
    return 1
}


#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Version  (Update with changes!)                                                                                                {{{

version=0.6.18
repver=0

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Parse command line                                                                                                             {{{
unset cmdl_library

while [ $# -ge 1 ] ; do
	case ${1} in
        -c | --config               ) config_core=${2}                                  ; shift ; shift           ;;
        -C | --cleanup              ) cleanup_only=1 ; cleanup=1                        ; shift                   ;;
        --cleanup_days              ) cleanup_days_cmdl=${2}                            ; shift ; shift           ;;
        --cleanup_simulate          ) cleanup_sim_cmdl=1 ; cleanup_only=1 ; cleanup=1   ; shift                   ;;
        -d | --dir_config           ) dir_config=${2}                                   ; shift ; shift           ;;
             --dir_session          ) cmdl_session=${2}                                 ; shift ; shift           ;;
        -f | --force                ) cmdl_force=1                                      ; shift                   ;;
             --import_opml          ) import_opml=${2}                                  ; shift ; shift           ;;
             --export_opml          ) export_opml=${2}                                  ; shift ; shift           ;;
             --import_pcast         ) import_pcast=${2}                                 ; shift ; shift           ;;
        -l | --library              ) cmdl_library=${2}                                 ; shift ; shift           ;;
        -n | --no-playlist          ) cmdl_noplaylist=1                                 ; shift                   ;;
        -p | --playlist-asx         ) cmdl_asx=1                                        ; shift                   ;;
             --playlist-per-podcast ) CMDL_PlaylistPerPodcast=1                         ; shift                   ;;
        -r | --recent               ) cmdl_most_recent=${2}                             ; shift ; shift           ;;
             --serverlist           ) cmdl_serverlist=${2}                              ; shift ; shift           ;;
        -s | --silent               ) silent=1 ; VERBOSITY=0                            ; shift                   ;;
        -V | --version              ) VERBOSITY=2 ; repver=1                            ; shift                   ;;
		-v                          ) VERBOSITY=1                                       ; shift                   ;;
		-vv                         ) VERBOSITY=2                                       ; shift                   ;;
		-vvv                        ) VERBOSITY=3                                       ; shift                   ;;
		-vvvv                       ) VERBOSITY=4                                       ; shift                   ;;
        --verbosity                 ) VERBOSITY=${2}                                    ; shift ; shift           ;;
		*                           ) display_shelp                                     ; exit ${err_displayhelp} ;;
	esac
done

if [ -n "$cmdl_serverlist" ] ; then
    config_serverlist=$cmdl_serverlist
fi

if [ ${VERBOSITY} -ge 2 ] ; then
    echo "podget"
fi

if [ ${repver} -eq 1 ]; then
    echo "Version: ${version}"
    exit 0
fi

if [ ${VERBOSITY} -ge 3 ] ; then
    echo "Parsing Config file."
    echo -e "Config directory:\t\t${dir_config}"
    echo -e "Config file:\t\t${config_core}"
    echo -e "Server List:\t\t${config_serverlist}"
fi

if [ ! -z "${cmdl_noplaylist+set}" ]; then
    if [ ! -z "${cmdl_asx+Set}" ]; then
        echo "Conflicting playlist options."
        exit 1
    fi
fi

# for testing
#echo "Verbosity: ${VERBOSITY}"
#exit 0

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Test for existing configuration directory, if missing install it.                                                              {{{

if [ ! -d "${dir_config}" ] ; then
    echo "  Configuration directory not found.  Creating \"${dir_config}\""
    mkdir "${dir_config}"
    EXITSTATUS=$?
    if [ ${EXITSTATUS} -ne 0 ]; then
        echo "  Failed to create \"${dir_config}\""
        exit 1
    fi
    install_session=1
fi

if [ ! -f "${dir_config}/${config_core}" ] ; then
    echo "  Installing default user configuration files."
    sed --silent -e '/TEXT_DEFAULT_CONFIG$/,/^TEXT_DEFAULT_CONFIG/p' "$0" |
        sed -e '/TEXT_DEFAULT_CONFIG/d' |
        sed -e "s|@HOME@|${HOME}|" -e "s/@VERSION@/${version}/" -e "s/@SERVERLIST@/${config_serverlist}/"> "${dir_config}"/${config_core}
    EXITSTATUS=$?
    if [ ${EXITSTATUS} -ne 0 ]; then
        echo "  Failed to create \"${dir_config}/${config_core}\""
        exit 1
    fi
    install_session=1
fi

if [ ! -f "${dir_config}/${config_serverlist}" ] ; then
    echo "  Installing default server list configuration."
    sed --silent -e '/TEXT_DEFAULT_SERVERLIST$/,/^TEXT_DEFAULT_SERVERLIST/p' "$0" |
        sed -e '/TEXT_DEFAULT_SERVERLIST/d' > "${dir_config}"/${config_serverlist}
    EXITSTATUS=$?
    if [ ${EXITSTATUS} -ne 0 ]; then
        echo "  Failed to install \"${dir_config}/${config_serverlist}\""
        exit 1
    fi
    install_session=1
fi

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Configuration                                                                                                                  {{{


# Parse config file
while read line ; do
    if [ ${VERBOSITY} -ge 3 ] ; then
        echo -e "\nConfig line --> $line"
    fi
    testindex=$(expr "$line" : "\(^[ ]*#\)")
    if [ "A${testindex}" != "A" ]; then
        if [ ${VERBOSITY} -ge 4 ] ; then
            echo "Discarding comment."
        fi
        continue
    fi
    if [[ $(expr "$line" : ".*=") > 0 ]]; then
        if [ ${VERBOSITY} -ge 3 ] ; then
            echo " Found config line."
        fi
        var2set=$(echo $line | sed -n -e 's/^\([^=]\+\)=.*$/\1/p')
        set2var=$(echo $line | sed -n -e 's/^[^=]\+=\(.*\)$/\1/p')
        if [ ${VERBOSITY} -ge 4 ]; then
            echo " VAR2SET=${var2set}, SET2VAR=${set2var}"
        fi

        if [ ${var2set} == "config_serverlist" ] && [ ! -z ${cmdl_serverlist} ]; then
            echo "Serverlist set on command line, skipping from configuration file."
        elif [ ${var2set} == "no_playlist" ]; then
            if [ ! -z ${cmdl_noplaylist} ]; then
                echo "NO PLAYLIST set on command line, skipping from configuration file."
            fi
            if [ ${set2var} -eq 1 ]; then
                # Disable Playlist Creation
                no_playlist=1
            else
                # Enable Playlist Creation
                no_playlist=0
            fi
        else
            if [ "${var2set}" != "filename_badchars" ]; then
                # This allows spaces in ${set2var}
                eval "export ${var2set}='${set2var}'"
            else
                # This allows quote characters in filename_badchars
                export ${var2set}=${set2var}
            fi
        fi
    fi
done < "${dir_config}"/$config_core

if [ ${install_session} -gt 0 ] ; then
    echo "  Downloading a single item from each default server to test configuration."
    echo
    most_recent=1
    VERBOSITY=3
fi

if [ ${VERBOSITY} -ge 3 ] ; then
    echo "LIBRARY DIR:  ${dir_library}"
fi

if [ -n "${cmdl_library}" ] ; then
    dir_library=${cmdl_library}
fi

if [ ${VERBOSITY} -ge 3 ] ; then
    echo "LIBRARY DIR:  ${dir_library}"
fi

if [ -n "${cmdl_session}" ] ; then
    dir_session=${cmdl_session}
fi

# Added so old configuration files (that were created before this option was added) still work.
if [ -z ${dir_session} ] ; then
    dir_session=/tmp/podget
fi

if [ ${VERBOSITY} -ge 3 ] ; then
    echo "SESSION DIR:  ${dir_session}"
fi

if [ -z ${dir_library} ] ; then
    echo "ERROR - Library directory not defined." 1>&2
    exit ${err_libnotdef}
fi

if [ ! -z ${cleanup_days_cmdl} ] ; then
    cleanup_days=${cleanup_days_cmdl}
fi

if [ ! -z ${cleanup_sim_cmdl} ] ; then
    cleanup_simulate=${cleanup_sim_cmdl}
fi

if [ -z $dir_log ] ; then
    dir_log=${dir_library}/.LOG
fi

if [ -n "${cmdl_asx}" ] ; then
    asx_playlist=${cmdl_asx}
fi

if [ ! -z ${CMDL_PlaylistPerPodcast+set} ]; then
    PLAYLIST_PerPodcast=1
fi

if [ ${VERBOSITY} -ge 3 ]; then
    echo "WGet options: ${wget_baseopts}"
fi

if [ -n "${cmdl_force}" ] ; then
    force=${cmdl_force}
    wget_baseopts=$(echo ${wget_baseopts} | sed -e 's/-c //')
    if [ ${VERBOSITY} -ge 3 ]; then
        echo "WGet options: ${wget_baseopts}"
    fi
fi


if [ -n "${cmdl_most_recent}" ] ; then
    most_recent=${cmdl_most_recent}
fi

if [ ${VERBOSITY} -le 1 ] ; then
        wget_options="-q ${wget_baseopts}"
elif [ ${VERBOSITY} -eq 2 ] ; then
    wget_options="-nv ${wget_baseopts}"
elif [ ${VERBOSITY} -eq 3 ] ; then
    wget_options="${wget_baseopts} --progress=dot:mega"
else
    wget_options="${wget_baseopts} --progress=bar"
fi

if [ ! -z ${filename_badchars} ] ; then
    # insert a space between all characters and remove tailing space.
    filename_badchars=$(echo ${filename_badchars} | sed -e 's/\([^ ]\)/\1 /g' -e 's/[*]/\\*/g' -e 's/ $//')

    if [ ${VERBOSITY} -ge 3 ] ; then
        echo -e "\nFilename Bad Characters: ${filename_badchars}"
        echo "Filename Replace Character: ${filename_replacechar}"
    fi

    modify_filename=1
fi

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Test for another session.                                                                                                      {{{
# Moved below the configuration reading so that the dir_session could be configurable.

# Test that session directory exists (useful when placed on a tmpfs filesystem).
if [ ! -d ${dir_session} ]; then
    if [ ${VERBOSITY} -ge 2 ] ; then
        echo -e "\nSession directory not found, creating"
    fi
    mkdir -p ${dir_session}
fi

test_session=0
for file in $(ls -1 "${dir_session}"/podget.[0-9]* 2>/dev/null) ; do
    if [ "$(stat -c %u ${file})" == "${UID}" ]; then
        if [ ${VERBOSITY} -ge 2 ] ; then
            echo "Session file found: ${file} (that my user owns)"
        fi
        test_session=1
        while read line ; do
            testindex=$(expr "$line" : "\sfile:")
            if [ "A${testindex}" != "A" ]; then
                test_file=$(echo $line | sed -n -e 's/^[^:]\+:\s\(.*\)$/\1/p')
                if [ "$test_file" == "$config_core" ] ; then
                    session_pid=$(echo ${file} | sed -n -e 's/^podget_session.\([0-9]*\)$/\1/p')
                    if [ ${VERBOSITY} -ge 2 ] ; then
                        echo "  Testing PID ${session_pid} to determine if its still running."
                    fi
                    if ps -p ${session_pid} &> /dev/null ; then
                        echo "Another session with config file ${config_core} found running.  Killing session." 1>&2
                        exit ${err_runningsession}
                    else
                        if [ ${VERBOSITY} -ge 2 ] ; then
                            echo "  Session PID ${session_pid} is not running, removing lock file"
                        fi
                        rm -f ${file}
                    fi
                fi
            fi
        done < $file
    fi
done
if [ ${VERBOSITY} -ge 2 ] ; then
    if [ $test_session -gt 0 ] ; then
        echo -e "\nOld Session file(s) found and removed.  Creating new one."
    else
        echo -e "\nSession file not found.  Creating."
    fi
fi

# Set session file.  Stores the configuration file used so that multiple sessions can be run per user simultaneously as
# long as they each have different configuration files.
# An example would be two sessions running as:
#       podget -c podgetrc.1
#       podget -c podgetrc.2
# As long as the two configuration files called different serverlists then they would not conflict.
echo -e "Config file: $config_core" > "${dir_session}"/podget.$$

#                                                                                                                               }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Loop over servers on list                                                                                                      {{{

if [ $cleanup_only -eq 0 ] && [ -z $import_opml ] && [ -z $export_opml ] && [ -z $import_pcast ] ; then
    if [ ${VERBOSITY} -ge 3 ] ; then
        echo -e "\nMain loop."
        echo "SERVER LIST FILE: $config_serverlist"
        echo "WGET OPTIONS: $wget_options"
        if [ ${no_playlist} -eq 0 ]; then
            echo "Playlist Creation Enabled."
        else
            echo "Playlist Creation Disabled."
        fi
        if [ ! -z "${PLAYLIST_PerPodcast+set}" ]; then
            echo "PLAYLIST_PerPodcast: ${PLAYLIST_PerPodcast} (Enabled)"
        fi
    fi

    mkdir -p $dir_log
    touch $dir_log/$log_fail $dir_log/$log_comp


    if [ ${no_playlist} -eq 0 ] && [ -z  ${PLAYLIST_PerPodcast+set} ]; then
        playlist_name="${playlist_namebase:=NEW-}$(date $date_format).m3u"

        counter=2
        while [[ -e ${dir_library}/${playlist_name} ]] ; do
            playlist_name="${playlist_namebase:=NEW-}$(date $date_format).r$counter.m3u"
            counter=$((counter+1))
        done

        if [ ${VERBOSITY} -ge 3 ]; then
            echo "Playlist name: ${playlist_name}"
        fi
    fi

    # UTF-8/16 handling
    for filetype in utf8 utf16 ; do
        if [ ${VERBOSITY} -ge 3 ] ; then
            echo
            case $filetype in
                'utf8')
                    echo "UTF-8 Loop running." ;;
                'utf16')
                    echo "UTF-16 Loop running." ;;
            esac
        fi
        case $filetype in
            'utf8')
                current_serverlist=""${dir_config}"/${config_serverlist}" ;;
            'utf16')
                BINARY_ICONV=$(which iconv)
                if [ -z ${BINARY_ICONV} ] ; then
                    echo "Can't find iconv binary, is libc6 installed?" 1>&2
                    echo "Exiting UTF16 loop, unable to convert file to UTF8" 1>&2
                    exit $err_libc6notinstalled
                fi
                current_serverlist=""${dir_config}"/${config_serverlist}.utf16" ;;
            *)
                echo "Unknown Filetype: $filetype"
        esac
        if [ ! -f $current_serverlist ] ; then
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "No config file found, exiting loop."
            fi
            continue
        fi

        while read feed_url feed_category feed_name ; do
            if [ ${VERBOSITY} -ge 3 ] ; then
                echo -e "\nServer/Feed URL --> $feed_url"
            fi

            if   [[ $(expr index "# " "$feed_url") > 0 ]] && [[ $(expr index "# " "$feed_url") < 2 ]] || [[ $feed_url == "" ]] ; then
                if [ ${VERBOSITY} -ge 3 ] ; then
                    echo "  Discarding line (comment or blank line)."
                fi
                continue
            fi

            feed_category=$(echo ${feed_category} | sed -e "s#%YY%#`date +%Y`#" -e "s#%MM%#`date +%m`#" -e "s#%DD%#`date +%d`#" )

            if [ $(expr "${feed_name}" : ".*PASS:[^ $]\+.*") -gt 0 ] ; then
                PASSWORD=$(echo ${feed_name} | sed -e 's/.*\(PASS:[^ $]\+\).*/\1/' -e 's/PASS:\(.*\)/\1/')
                feed_name=$(echo ${feed_name} | sed -e 's/\(.*\)PASS:[^ $]\+\(.*\)/\1\2/')
            fi
            if [ $(expr "${feed_name}" : ".*USER:[^ $]\+.*") -gt 0 ] ; then
                USERNAME=$(echo ${feed_name} | sed -e 's/.*\(USER:[^ $]\+\).*/\1/' -e 's/USER:\(.*\)/\1/')
                feed_name=$(echo ${feed_name} | sed -e 's/\(.*\)USER:[^ $]\+\(.*\)/\1\2/')
            fi
            # Remove any residual trailing spaces from ${feed_name}
            if [ $(expr "${feed_name}" : ".*[ ]\+$") -gt 0 ]; then
                feed_name=${feed_name%[ ]*}
            fi

            # Add Username and Password to wget options if found
            if [ -n "${USERNAME}" ]; then
                wget_options="${wget_options} --user==${USERNAME}"
            fi

            if [ -n "${PASSWORD}" ]; then
                wget_options="${wget_options} --password=${PASSWORD}"
            fi

            # If configured to create individual playlists for each podcast, set playlist name here.
            # White-Space in feed name will be converted to underscores.
            if [ ${no_playlist} -eq 0 ] && [ ! -z  ${PLAYLIST_PerPodcast+set} ]; then
                playlist_name="${playlist_namebase:=NEW-}$(date $date_format)-$(echo ${feed_name} | sed -e "s#\s#_#g").m3u"

                counter=2
                while [[ -e "${dir_library}/${playlist_name}" ]] ; do
                    playlist_name="${playlist_namebase:=NEW-}$(date $date_format)-$(echo ${feed_name} | sed -e "s#\s#_#g").r$counter.m3u"
                    counter=$((counter+1))
                done
            fi

            if [ ${VERBOSITY} -ge 2 ] ; then
                echo -e "\n-------------------------------------------------"
                echo -e "Category: $feed_category\t\tName: $feed_name"
                if [ -n "${USERNAME}" ]; then
                    echo -e "\t\t\tUsername: ${USERNAME}"
                fi
                if [ ${VERBOSITY} -ge 4 ] ; then
                    if [ -n "${PASSWORD}" ]; then
                        # Password is stored in the serverlist file in plain text so displaying it here is a small risk but can be
                        # useful for debugging connection issues.
                        echo -e "\t\t\tPassword: ${PASSWORD}"
                    fi
                    echo "WGET OPTIONS: ${wget_options}"
                fi
                if [ ${no_playlist} -eq 0 ] && [ ! -z  ${PLAYLIST_PerPodcast+set} ]; then
                    echo "Individual Podcast Playlist Name: ${playlist_name}"
                fi

                echo
                echo "Downloading feed index from $feed_url"
            fi

            case $filetype in
                'utf8')
                    indexfile=$(wget $wget_options -O - $feed_url  | sed -e 's/\r/\n/g' -e 's/<\([^/]\)/\n<\1/g' | \
                        sed -n -e :a -e 's/.*<enclosure.*url\s*=\s*"\([^"]\+\)".*/\1/Ip' -e 't' \
                                     -e "s/.*<enclosure.*url\s*=\s*'\([^']\+\)'.*/\1/Ip" \
                                     -e '/<enclosure\s*/{N;s/ *\n/ /;ba;}' | \
                        sed -e "s/'/%27/g" -e 's/\&apos;/%27/g' -e 's/\&amp;/\&/g') ;;
                'utf16')
                    indexfile=$(wget $wget_options -O - $feed_url | ${BINARY_ICONV} -f UTF-16 -t UTF-8  | \
                        sed -e 's/\r/\n/g' -e 's/<\([^/]\)/\n<\1/g' | \
                        sed -n -e :a -e 's/.*<enclosure.*url\s*=\s*"\([^"]\+\)".*/\1/Ip' -e 't' \
                                     -e "s/.*<enclosure.*url\s*=\s*'\([^']\+\)'.*/\1/Ip" \
                                     -e '/<enclosure\s*/{N;s/ *\n/ /;ba;}' | \
                        sed -e "s/'/%27/g" -e 's/\&apos;/%27/g' -e 's/\&amp;/\&/g') ;;
            esac

            if [ -n "$indexfile" ] ; then
                if [ $most_recent -gt 0 ] ; then
                    fullindexfile=$indexfile
                    indexfile=$(echo ${indexfile} | cut -d \  -f -${most_recent})
                fi

                if [ ${VERBOSITY} -ge 3 ] ; then
                    if [ $most_recent -gt 0 ] ; then
                        echo -e "Modified Index List:\n${indexfile}"
                        echo -e "Full Index List:\n${fullindexfile}"
                    else
                        echo -e "Index List:\n${indexfile}"
                    fi
                fi

                for url in $indexfile
                do
                    if [ ${VERBOSITY} -ge 2 ] ; then
                        echo
                    fi

                    url_filename=$(echo $url | sed -e 's/.*\/\([^\/]\+\)/\1/' -e 's/%20/ /g')
                    url_base=$(echo $url | sed -e 's/\(.*\/\)[^\/]\+/\1/')

                    # Test for available space on library partition
                    avail_space=$(df -kP ${dir_library} | tail -n 1 | awk '{print $4}')
                    if [ ${avail_space} -le ${min_space} ] ; then
                        echo -e "\nAvailable space on Library partition has dropped below allowed.\nStopping Session." 1>&2
                        exit ${err_liblowspace}
                    fi

                    # Filename format fixes and character substitutions.
                    # Return value stored in variable ${mod_filename}, called here as a string to be used as the name of the
                    # variable.
                    filenameFixFormat mod_filename "${url_filename}"

                    # Fix where filename part of URI is constant
                    # This fix is known to cause issues with in filenames when it is not needed.  Disabled by default.
                    if [ ! -z ${filename_formatfix4} ] && [ ${filename_formatfix4} -gt 0 ] ; then
                        if [ -z "$mod_filename" ] ; then
                            mod_filename=${url_filename}
                        fi
                        mod_prefix="${url_base%%/}"
                        mod_prefix="${mod_prefix##*/}"
                        mod_filename="${mod_prefix##*/}_${mod_filename}"
                        if [ ${VERBOSITY} -ge 3 ] ; then
                            echo "FILENAME FORMAT(4) FIXED: $mod_filename"
                        fi
                    fi

                    mkdir -p "$dir_library/$feed_category/$feed_name"

                    dtest=$(fgrep $url $dir_log/$log_comp)

                    if [ -z "${dtest}" ] || [ ${force} -ne 0 ] ; then
                        if [ ${VERBOSITY} -ge 2 ] ; then
                            if [ $modify_filename -gt 0 ] || [ $filename_formatfix -gt 0 ] ||
                               [ $filename_formatfix2 -gt 0 ]; then
                                echo -e "Downloading $mod_filename from $url_base"
                            else
                                echo -e "Downloading $url_filename from $url_base"
                            fi
                        fi

                        if [ -n "$mod_filename" ] ; then
                            wget $wget_options -O "$dir_library/$feed_category/$feed_name/$mod_filename" $url
                        else
                            wget $wget_options -P "$dir_library/$feed_category/$feed_name/" $url
                        fi

                        if [ $? -eq 0  ] ; then
                            echo "$url" >> $dir_log/$log_comp
                            if [ ${no_playlist} -eq 0 ]; then
                                # if creating playlists, then add to file.
                                # Suggested fix from https://sourceforge.net/tracker/?func=detail&aid=2170298&group_id=133382&atid=727035
                                if [ -n "$playlist_name" ] ; then
                                    if [ -n "$mod_filename" ] ; then
                                        echo "${feed_category}/${feed_name}/${mod_filename}" >> "${dir_library}/${playlist_name}"
                                        if [ ${VERBOSITY} -ge 2 ]; then
                                            echo "PLAYLIST: Adding ${feed_category}/${feed_name}/${mod_filename} to ${dir_library}/${playlist_name}"
                                        fi
                                    else
                                        echo "${feed_category}/${feed_name}/${url_filename}" >> "${dir_library}/${playlist_name}"
                                        if [ ${VERBOSITY} -ge 2 ]; then
                                            echo "PLAYLIST: Adding ${feed_category}/${feed_name}/${url_filename} to ${dir_library}/${playlist_name}"
                                        fi
                                    fi
                                fi
                            fi
                        else
                            echo $url >> $dir_log/$log_fail
                        fi
                    else
                        if [ ${VERBOSITY} -ge 2 ] ; then
                            if [ ${VERBOSITY} -ge 3 ] ; then echo ; fi
                            if [ $modify_filename -gt 0 ] || [ $filename_formatfix -gt 0 ] ||
                               [ $filename_formatfix2 -gt 0 ]; then
                                echo "Already downloaded ${mod_filename}."
                            else
                                echo "Already downloaded ${url_filename}."
                            fi
                        fi
                    fi
                done
                if [ $most_recent -ne 0 -a $install_session -eq 0 ] ; then
                    for url in $fullindexfile
                    do
                        dtest=$(fgrep $url $dir_log/$log_comp)
                        if [ -z "${dtest}" ] ; then
                            url_filename=$(echo $url | sed -e 's/.*\/\([^\/]\+\)/\1/' -e 's/%20/ /g')
                            if [ ${VERBOSITY} -ge 2 ] ; then
                                #if [ -n "$mod_filename" ] ; then
                                #    echo "Marking as already downloaded $mod_filename."
                                #else
                                    echo "Marking as already downloaded $url_filename."
                                #fi
                            fi
                            echo $url >> $dir_log/$log_comp
                        fi
                    done
                fi

                # If doing individual playlists for each podcast Sort new playlist
                if [ -e "$dir_library/$playlist_name" ]  && [ ! -z  ${PLAYLIST_PerPodcast+set} ]; then
                    PLAYLIST_Sort ${dir_library} "${playlist_name}"

                    # If doing individual playlists for each podcast, Create ASX Playlist
                    if [ ${asx_playlist} -gt 0 ] ; then
                        PLAYLIST_ConvertToASX ${dir_library} "${playlist_name}"
                    fi

                    # Done with playlist, unset name.
                    unset playlist_name
                fi

                if [ ${VERBOSITY} -ge 4 ] ; then
                    echo
                    echo "Cleanup Loop vars:"
                fi
                unset USERNAME
                unset PASSWORD

                wget_options=$(echo ${wget_options} | sed -e 's/\(.*\) --user=[^ ]*\(.*\)/\1\2/' -e 's/\(.*\) --password=[^ ]*\(.*\)/\1\2/')
                if [ ${VERBOSITY} -ge 4 ] ; then
                    echo -e "\tWGET OPTIONS: ${wget_options}"
                fi
            else
                if [ ${VERBOSITY} -ge 1 ] ; then
                    echo "  No enclosures in feed: $feed_url"
                fi
                echo $feed_url >> $dir_log/$log_fail
            fi
        done < $current_serverlist
    done

    # If doing one combined playlist for all podcasts, Sort new playlist
    if [ -z "${playlist_name+set}" ]; then
        if [ -e "$dir_library/$playlist_name" ] ; then
            PLAYLIST_Sort ${dir_library} "${playlist_name}"

            # If doing one combined playlist for all podcasts, Create ASX Playlist
            if [ ${asx_playlist} -gt 0 ] ; then
                PLAYLIST_ConvertToASX ${dir_library} "${playlist_name}"
            fi
        fi
    fi
fi

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Cleanup loop                                                                                                                   {{{

if [ -z $import_opml ] && [ -z $export_opml ]  && [ -z $import_pcast ] ; then
    if [ $cleanup -ne 0 ] || [ $cleanup_only -ne 0 ] ; then
        if [ ${VERBOSITY} -ge 2 ] ; then
            if [ $cleanup_simulate -gt 0 ] ; then
                echo "Simulating cleanup, the following files will be removed when you run cleanup."
            else
                echo -e "\n-------------------------------------------------\nCleanup old tracks."
            fi
        fi
        filelist=$(find $dir_library/ -maxdepth 1 -type f -name "*.m3u" -mtime +${cleanup_days})
        for file in $filelist ; do
            if [ ${VERBOSITY} -ge 2 ] ; then
                echo "Deleting tracks from $file:"
            fi
            while read line ; do
                if [ $cleanup_simulate -gt 0 ] ; then
                    echo "File:  $dir_library/$line"
                else
                    if [ ${VERBOSITY} -ge 2 ] ; then
                        rm -v "$dir_library/$line"
                    else
                        rm -f "$dir_library/$line"
                    fi
                fi
            done < $file
            if [ $cleanup_simulate -gt 0 ] ; then
                echo "Removing playlist: $file"
            else
                if [ ${VERBOSITY} -eq 0 ] ; then
                    rm -f "$file"
                else
                    rm -fv "$file"
                fi
            fi
        done
    fi
fi

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# OPML import loop:                                                                                                              {{{

if [ ! -z $import_opml ] ; then
    if [ ${VERBOSITY} -ge 2 ] ; then
        echo -e "\nImport servers from OPML file: $import_opml"
    fi

    new_category="OPML_Import_$(date ${date_format})"

    if [[ $import_opml == http:* ]] || [[ $import_opml == ftp:* ]] ; then
        if [ ${VERBOSITY} -ge 2 ] ; then
            echo "Getting opml list."
        fi
        opml_list=$(wget ${wget_options} -O - ${import_opml})
    else
        opml_list=$(cat ${import_opml})
    fi

    new_list=$(echo ${opml_list} | sed -e 's/\(\/>\)/\1\n/g' | sed -e :a -n -e 's/<outline\([^>]\+\)\/>/\1/Ip;/<outline/{N;s/\n\s*/ /;ba;}')

    if [ -n "$new_list" ] ; then

        OLD_IFS=$IFS
        IFS=$'\n'

        for data in ${new_list} ; do
            if [ ${VERBOSITY} -ge 1 ] ; then
                echo -e "\n---------------"
            fi

            new_label=$(echo $data | sed -n -e 's/.*text="\([^"]\+\)".*/\1/Ip' | sed -e 's/^\s*[0-9]\+\.\s\+//' -e "s/[:;'\".,!/?<>\\|]//g")
            new_url=$(echo $data | sed -n -e 's/.*[xml]*url="\([^"]\+\)".*/\1/Ip' | sed -e 's/ /%20/g')

            if [ ${VERBOSITY} -ge 3 ] ; then
                echo "LABEL:  ${new_label}"
                echo "URL:    ${new_url}"
            fi

            test=$(grep ${new_url} "${dir_config}"/${config_serverlist})
            if [ -z $test ] ; then
                echo "${new_url} ${new_category} ${new_label}" >> "${dir_config}"/${config_serverlist}
            elif [ ${VERBOSITY} -ge 2 ] ; then
                echo "Feed ${new_label} is already in the serverlist"
            fi
        done

        IFS=$OLD_IFS
    else
        if [ ${VERBOSITY} -ge 2 ] ; then
            echo "  OPML Import Error $import_opml" 1>&2
        fi
        echo OPML Import Error: $import_opml >> $dir_log/$log_fail
        exit ${err_importopml}
    fi
fi

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# OPML export loop:                                                                                                              {{{

if [ ! -z $export_opml ] ; then
    if [ ${VERBOSITY} -ge 2 ] ; then
        echo -e "\nExport serverlist to OPML file: $export_opml"
    fi

    if [ ! -e $export_opml ]; then
        echo '<?xml version="1.0" encoding="utf-8" ?>
<opml version="1.0">
<head/>
<body>' > $export_opml

	while read feed_url feed_category feed_name ; do
            if   [[ $(expr index "# " "$feed_url") > 0 ]] && [[ $(expr index "# " "$feed_url") < 2 ]] || [[ $feed_url == "" ]] ; then
                if [ ${VERBOSITY} -ge 3 ] ; then
                    echo "  Discarding line (comment or blank line)."
                fi
                continue
            fi

	    if [ ${VERBOSITY} -ge 3 ] ; then
	             echo "  Writing out feed $feed_name in category $feed_category with url $feed_url"
	    fi
            echo '<outline text="'${feed_category}'"><outline text="'${feed_name}'" type="rss" xmlUrl="'${feed_url}'" /></outline>' >> $export_opml
        done < "${dir_config}"/${config_serverlist}

	echo '</body>
</opml>' >> $export_opml
    else
        echo OPML Export Error: $export_opml >> $dir_log/$log_fail
        exit ${err_exportopml}
    fi
fi

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# PCAST import:                                                                                                                  {{{

if [ ! -z $import_pcast ] ; then
    if [ ${VERBOSITY} -ge 2 ] ; then
        echo -e "\nImport server from PCAST file: $import_pcast"
    fi

    if [[ $import_pcast == http:* ]] || [[ $import_pcast == ftp:* ]] ; then
        if [ ${VERBOSITY} -ge 2 ] ; then
            echo "Getting pcast file."
        fi
        pcast_data=$(wget ${wget_options} -O - ${import_pcast})
    else
        pcast_data=$(cat ${import_pcast})
    fi

    new_link=$(echo ${pcast_data} | sed -n -e 's/.*\(href\|url\)="\([^"]\+\)".*/\2/Ip' | sed -e 's/ /%20/g')
    new_category=$(echo ${pcast_data} | sed -n -e 's/.*<category>\([^<]\+\)<.*/\1/Ip' | sed -e 's/ /_/g;s/\&quot;/\&/g;s/\&amp;/\&/g')
    new_title=$(echo ${pcast_data} | sed -n -e 's/.*<title>\([^<]\+\)<.*/\1/Ip')

    if [ ${VERBOSITY} -ge 2 ] ; then
        echo "LINK: ${new_link}"
        echo "CATEGORY: ${new_category}"
        echo "TITLE: ${new_title}"
    fi

    test=$(grep ${new_link} "${dir_config}"/${config_serverlist})
    if [ -z "$test" ] ; then
        echo "${new_link} ${new_category} ${new_title}" >> "${dir_config}"/${config_serverlist}
    elif [ ${VERBOSITY} -ge 2 ] ; then
        echo "Feed ${new_title} is already in the serverlist"
    fi
fi


#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Close session and clean up:                                                                                                    {{{

if [ ${VERBOSITY} -ge 2 ] ; then
    echo -e "\nClosing session and removing lock file."
fi
rm -f "${dir_session}"/podget.$$

#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# Notes:                                                                                                                         {{{
# 1.  Best viewed in Vim (http://vim.sf.net) with the AutoFold plugin and the
#     Relaxedgreen colorscheme (vimscripts #925 and #791).
# 2.  Known Bug:  If the same filename is downloaded for multiple items on a
#     single feed, wgets continue fuction will cause them to append or error.
#                                                                                                                                }}}
# ----------------------------------------------------------------------------------------------------------------------------------
# vim:tw=132:ts=4:sw=4
