#!/bin/sh

##########################################################################

# please read the copyright notice before you change anything 

copyright_notice() {
 echo "$displayName"
 echo ""
 echo "$supportMeLink"
 echo ""
 echo "Copyleft 2007 Ricardo Birmann"
 echo ""
 echo "This is free software and is distributed under the terms of"
 echo "the GNU General Public Liscence. You are encouraged to change"
 echo "and/or distribute it under the terms of such liscence, which"
 echo -e "can be found at: http://www.gnu.org/copyleft/gpl.html\n"
 echo -e "For bug reports, my email is available at ricardobirmann.com\n"
 echo "I'd be happy to see any modifications you've made to this"
 echo "program, so please email me if you have changed it..."
}


displayName="Fred"
supportMeLink="http://ricardobirmann.com/projects/fred"
# current version is
version="0.2.5.2"

# see the version log / to-do list at end of this file

help_me() {
    echo -e "usage: $0 [-h|-v|-c|[-g][-i configsFile]]\n"
    echo "Where the options mean:"
    echo "    -h this help text"
    echo "    -c copyright and contact information"
    echo "    -v current version"
    echo "    -g generate the configurations file ($configsfile if not overridden with -i)"
    echo "    -i use configsFile as the configurations file"
    echo ""
}

##########################################################################

# auxiliar file for configs - should exist on running directory
configsfile="configs.$displayName"

pubDate='YET UNDEFINED'

nanosecs=`date +%s%N`

lineNumForNewEntry=0

add_conf() {
# parameters: prompt text,  default value
    answer=
    echo -n "$1 [default: $2]: " 
    read answer
    if test "$answer" = "" ; then
	answer=$2
    fi
    echo "$answer" >> $configsfile
}

generate_configuration_file() {
    echo "Generating configuration file"
    answer=
    read -p "File to create [default: $configsfile]: " answer
    if test "$answer" != ""; then configsfile=$answer; fi
    if [ -f "$configsfile" ]; then
	echo "$configsfile exists and its contents may be lost."
 	read -p "Continue? [Y/n] " answer
	echo ""
	if  test "$answer" = "n" -o "$answer" = "N" ; then
	    echo "aborting..."
	    exit 0
	fi
	echo "If this file had already been generated by $displayName, you can"
	echo "use the previous configurations as default values. This is specially"
	echo "useful if you want to change one or two configs only... you won't"
	echo "have to type ALL of them again!"
	read -p "Try to get origianl configurations from this file? [Y/n] " answer
	echo ""
	if  test "$answer" = "n" -o "$answer" = "N" ; then
	    get_default_config_values
	else
	    read_all_configs
	fi
	rm $configsfile
    else
	get_default_config_values
    fi
    
    touch $configsfile
    
    # when adding config options change here, at get_default_config_values() and at read_all_configs()

    echo ""
    add_conf 'Feed file' "$feedFile"
    echo -e "Please pick a date format for all date information on the RSS file. It is highly recommended that you use \'%a, %d %b %Y %H:%M:%S %z\', since this will produce RFC-822 compliant dates, which is required by the RSS 2.0 specification"
    add_conf 'Date format' "$datefmt"
    add_conf 'Feed title' "$feedTitle"
    add_conf 'Feed Description' "$feedDescription"
    add_conf 'Feed Link' "$feedLink"
    echo -e "\nLater on, when using $displayName to add entries to your feed, you will be prompted for a Title, an Author, a Link and a Description for each post. You can configure a default author, in case you don't feel like typing it in everytime."
    add_conf 'Default Author (a valid email address)' "$defaultAuthor"
    echo -e "\nYou can also add a default prefix for all post links, such as http://mydomain.com/, since all links have to be valid URLs, this helps you preventing spelling errors."
    add_conf 'Prefix for post links (including http://)' "$postLinkPrefix"
    echo -e "\nAt last, you can choose a text editor of your choice to enter the description of each post (its main content). If you do not want to use an editor, leave it blank, you will be prompted for the descriptions."
    add_conf 'Editor for descriptions (leave blank for manual input)' "$editor"
    echo ""

    echo "" >> $configsfile
    # WARNING: regenerate configs files when this has changed
    
    echo "Configurations file succesfully created at $configsfile"
}

get_default_config_values() {
    # assing default values
    feedFile='feed.xml'
    datefmt='%a, %d %b %Y %H:%M:%S %z'
    feedTitle='My Feed'
    feedDescription='no description provided'
    feedLink='http://'
    defaultAuthor='unkown@unkown.com'
    postLinkPrefix='http://'
    editor=''
}

# we will use these small functions to read the configs from the input file
returnedConfig=""
configCounter=1
configAt() { # receives a number N and returns the Nth config in $configsfile
    returnedConfig=`head -n+$1 < $configsfile | tail -1` 
}
nextConfig() { # calls configAt with configCounter as parameter and increments it
    configAt $configCounter
    configCounter=`expr $configCounter + 1`
}
read_all_configs() { # reads all configurations from file in the order defined in generate_configuration_file
    nextConfig; feedFile=$returnedConfig
    nextConfig; datefmt=$returnedConfig
    nextConfig; feedTitle=$returnedConfig
    nextConfig; feedDescription=$returnedConfig
    nextConfig; feedLink=$returnedConfig
    nextConfig; defaultAuthor=$returnedConfig
    nextConfig; postLinkPrefix=$returnedConfig
    nextConfig; editor=$returnedConfig

    pubDate=`date +"$datefmt"`

}    

add_entry_to_feed_file() {
    # generate the entry

    title=$1; link=$2; author=$3

    create_feed_header
    
    lineNumForNewEntry=`grep -m 1 -n '<item>' $feedFile | sed s/:.*//`
    
    if [ "$lineNumForNewEntry" = '' ]  ; then
    	lineNumForNewEntry=`grep -m 1 -n '</channel>' $feedFile | sed s/:.*//`
    fi
    
    guid="$nanosecs$displayName$version $title"
    
    echo -e "$feedHeader" > $tmpFile
    
    # the following lines could be extracted to a subroutine - addXmlElementToEntry
    echo -e "\n\t<item>" >> $tmpFile
    echo -e "\t\t<title>$title</title>" >> $tmpFile
    echo -e "\t\t<link>$link</link>" >> $tmpFile
    echo -e "\t\t<description><![CDATA[$description]]></description>" >> $tmpFile
    echo -e "\t\t<author>$author</author>" >> $tmpFile
    echo -e "\t\t<pubDate>$pubDate</pubDate>" >> $tmpFile
    echo -e "\t\t<guid isPermaLink=\"false\">$guid</guid>" >> $tmpFile
    echo -e "\t</item>\n" >> $tmpFile

    tail -n+$lineNumForNewEntry $feedFile >> $tmpFile
    
    mv $tmpFile $feedFile
}

get_description() {
    enterManually=0
    # description is a 'global' variable
    
    if test "$editor" != ""; then
	echo -e "\nUsing $tmpFile as temporary file."
	if [ -f $tmpFile ] ; then rm $tmpFile ; fi  # just to make sure
	touch $tmpFile
	echo "Issuing command \`$editor $tmpFile\`, save and quit editor to proceed"
	answer=
	read -p "Type X to abort, E to use a different editor or anything else to continue..." answer
	echo ""
	if  test "$answer" != "x" -a "$answer" != "X" ; then
	    if  test "$answer" = "E" -o "$answer" = "e" ; then
		read -p "Command to use (filename will be appended):" editor
	    fi
	    $editor $tmpFile
	    description=`cat $tmpFile | sed -e 's/$/<br\/>/g'`
	else
	    enterManually=1
	fi
    else
	enterManually=1
    fi
    
    if [ $enterManually = 1 ]; then
	read -p "Description: " description
    else
	echo -e "Description:\n$description"
    fi
}
  
new_entry() {
    
    goodToGoFlag=0

    title='untitled'
    link=''
    author=$defaultAuthor
    description=''
    
    until [ $goodToGoFlag = 1 ] ; do
	# the following lines could be extracted to a subroutine - readXmlElement
	answer=
	read -p "Title [$title]: " answer
	if test "$answer" != "" ; then title=$answer ; fi
	
	answer=
	if [ "$link" = "" ] ; then
	    read -p "Link [$postLinkPrefix]: $postLinkPrefix" answer
	else
	    
	    read -p "Link [$link]: $postLinkPrefix" answer
	fi
	
	link="$postLinkPrefix$answer"
	
	answer=
	read -p "Author [$author]: " answer
	if test "$answer" != "" ; then author=$answer; fi
	
	get_description 
	
	echo ""
	
	if [ "$title" = "" -o "$link" = "" -o "$author" = "" -o "$description" = "" ] ; then
	    echo -e "One or more required field left blank!\n"
	else
	    read -p "Confirm posting with data above? [y/N] " answer
	    echo ""
	    if  test "$answer" = "y" -o "$answer" = "Y" ; then
		goodToGoFlag=1
	    fi
	fi
	
    done
    
    add_entry_to_feed_file "$title" "$link" "$author"
}

create_feed_header(){
    
    feedHeader="<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
    feedHeader="$feedHeader<rss version=\"2.0\">\n"
    feedHeader="$feedHeader\t<channel>\n"
    feedHeader="$feedHeader\t<title>$feedTitle</title>\n"
    feedHeader="$feedHeader\t<description>$feedDescription</description>\n"
    feedHeader="$feedHeader\t<link>$feedLink</link>\n"
    feedHeader="$feedHeader\t<lastBuildDate>$pubDate</lastBuildDate>\n"
    feedHeader="$feedHeader\t<pubDate>$pubDate</pubDate>\n"
    feedHeader="$feedHeader\t<generator>$displayName v$version $supportMeLink</generator>\n"
}

create_feed_file(){
    if [ -f "$feedFile" ]; then
	echo "ERROR: $feedFile already exists!"
	exit 1
    fi
    create_feed_header
    echo -e "$feedHeader" > $feedFile
   
    echo -e "\t</channel>\n</rss>\n" >> $feedFile
    

}

######################################################################
######################################################################
######################################################################

# temporary file with unique name
tmpFile="/tmp/$displayName$nanosecs"

newEntryFlag=1

while getopts hvci:gn opt
  do
  case "$opt" in
      h)  # show help text and exit
	  help_me
	  exit 0 ;;
      v)  # show version and exit
	  echo "$version"
	  exit 0 ;;
      c)  # show copyright information and exit
	  copyright_notice
	  exit 0 ;;
      i)  # use OPTARG as the configsfile instead of default
	  configsfile=$OPTARG ;;
      g)  # generate the configurations file
	  generate_configuration_file
	  newEntryFlag=0
	  exit 0 ;;
      n)  # do not create a new entry
	  newEntryFlag=0 ;;
      [?]) 
      help_me
      exit 1;;
  esac
done

shift `expr $OPTIND - 1` # shift $1 until end of options

# check for input file
if [ ! -f "$configsfile" ]; then
    echo "$configsfile does not exist, create it with:"
    echo "  $0 -g"
    exit 1
fi

read_all_configs

# check for input file
if [ ! -f "$feedFile" ]; then
    read -p "$feedFile does not exist, create it? [Y/n]" answer
    echo ""
    if  test "$answer" != "n" -a "$answer" != "N" ; then
	create_feed_file
    else
	echo "We need $feedFile... Aborting... "
	exit 1
    fi
fi


if test $newEntryFlag = 1; then
    new_entry
fi
    
exit 0



##########################################################################

# VERSION LOG
# (to-do list in the case of future versions; current version marked with <- )
#
# OBS.: UPDATE VARIABLE $version WHEN VERSION CHANGES
#
# http://feedvalidator.org
#
# 1.0
#   support for all optional RSS tags available
#   manages existing rss file (preserves header, etc..)
#   support enclosures
#
# 0.3
#   option -e to edit last entry
#   ensure utf-8 encoding
#
# 0.2.8
#   option -d to delete last entry
#
# 0.2.5.2 <-
#   compatibility issues
#
# 0.2.5.1
#   small bugs fixed
#
# 0.2.5 
#   end the 12 lines header thing
#   
# 0.2 
#  <guid> tags
#
# 0.1 
#   valid feed
#   options -c, -v, -h
#   -g generate the config file
#   -n no entry
#   

# KNOWN BUGS
#
# - the default value for $link is lost from previous unconfirmed attempt