#!/bin/sh

#-CW-PARAMETERS-----------------------------------
CWCHANNEL=912
CHAR_WPM=12
AVG_WPM=12
CALLSIGN=
GRIDSQUARE=
#-NEWS-SOURCE_PARAMETERS--------------------------
RSS_NEWS_FEED=news.bbc.co.uk/rss/newsonline_uk_edition/world/rss.xml
CHECK_FRESH_NEWS_EVERY=300	#seconds
#-------------------------------------------------



# Get an RSS XML file (passed in $1), extract the news, "morsify" them, compare
# them with already fetched news, and return a new news item in $NEWS. Returns
# 0 (TRUE) if a new news has been found, 1 (FALSE) if not.
function rss_news_to_cw
{
  IFS_SAVE=$IFS
  IFS=\|

  NEW_NEWS=(`curl -stderr=/dev/null $1 | sed -e 's/\(<[^>]*>\)/\1\n/g' |\
	awk '								\
	/<item>/ {in_item=1}						\
	/<title>/ && in_item {in_title=1;title=""}			\
	in_title {title=sprintf("%s %s",title,$0)}			\
	/<\/title>/ && in_item						\
		{in_title=0;gsub(/<\/*title>/,"",title)}		\
	/<description>/ && in_item {in_desc=1;desc=""}			\
	in_desc {desc=sprintf("%s %s",desc,$0)}				\
	/<\/description>/ && in_item					\
		{in_desc=0;gsub(/<\/*description>/,"",desc)}		\
	/<\/item>/							\
	{								\
	  in_item=0;							\
	  sub(/^[\t ]*/,"",title);					\
	  sub(/[\t \r\n]*$/,"",title);					\
	  sub(/^[\t ]*/,"",desc);					\
	  sub(/[\t \r\n]*$/,"",desc);					\
	  news=sprintf("%s [BT] %s",title,desc);			\
	  gsub(/\t/," ",news);						\
	  gsub(/ +/," ",news);						\
	  								\
	  v=gensub(/^.*&#([[:digit:]]*);.*$/,"\\1",1,news);		\
	  while(v!=news)						\
	  {								\
	    gsub(/^0*/,"",v);						\
	    i=v+0;							\
	    v=sprintf("%c",i);						\
	    news=gensub(/^(.*)&#[[:digit:]]*;(.*)$/,"\\1"v"\\2",1,news);\
	    v=gensub(/^.*&#([[:digit:]]*);.*$/,"\\1",1,news);		\
	  }								\
									\
	  printf("%s|",news)						\
	 }' | html2text`)

  # At the first call, return just the first news
  if [ "$PREV_NEWS_EXIST" != 1 ];then
    I=-1
    for NN in ${NEW_NEWS[*]};do
      if [ $I -ge 0 ];then
        PREV_NEWS[$I]=$NN
      fi
      let I=I+1
    done
    PREV_NEWS_EXIST=1
  fi

  # Remove all deprecated previous news items (i.e. those that don't appear in
  # the new news
  NEW_PREV_NEWS_I=0
  NEW_PREV_NEWS=()
  for NP in ${PREV_NEWS[*]};do
    NEWS_ITEM_IS_KNOWN=0
    for NN in ${NEW_NEWS[*]};do
      if [ "$NN" = "$NP" ];then
        NEWS_ITEM_IS_KNOWN=1
        break
      fi
    done

    if [ $NEWS_ITEM_IS_KNOWN = 1 ];then
      NEW_PREV_NEWS[$NEW_PREV_NEWS_I]="$NN"
      let NEW_PREV_NEWS_I=NEW_PREV_NEWS_I+1
    fi
  done
  
  # Find the first new news item that isn't already present in the previous news
  # and add it to the new news
  NEW_NEWS_ITEM=""
  for NN in ${NEW_NEWS[*]};do
    NEWS_ITEM_IS_KNOWN=0
    for NP in ${NEW_PREV_NEWS[*]};do
      if [ "$NP" = "$NN" ];then
        NEWS_ITEM_IS_KNOWN=1
        break
      fi
    done

    # New news item : add it to the previous news and return it
    if [ $NEWS_ITEM_IS_KNOWN = 0 ];then
      NEW_NEWS_ITEM="$NN"
      NEW_PREV_NEWS[$NEW_PREV_NEWS_I]="$NN"
      break
    fi
  done

  PREV_NEWS=(${NEW_PREV_NEWS[*]})

  IFS=$IFS_SAVE

  if [ "$NEW_NEWS_ITEM" ];then
    NEWS="$NEW_NEWS_ITEM"
    return 0
  else
    return 1
  fi
}



# Function to encode prosigns in plain text into high-8th-bit ASCII suitable
# for send_cw, in a news item.
function encode_prosigns
{
  NEWS=`echo $NEWS | awk '{	gsub(/\[AR\]/,	"\200");		\
				gsub(/\[AS\]/,	"\201");		\
				gsub(/\[BK\]/,	"\202");		\
				gsub(/\[BT\]/,	"\203");		\
				gsub(/\[KA\]/,	"\204");		\
				gsub(/\[CL\]/,	"\205");		\
				gsub(/\[KN\]/,	"\206");		\
				gsub(/\[VA\]/,	"\207");		\
				gsub(/\[VE\]/,	"\210");		\
				gsub(/\[GR\]/,	"\211");		\
				gsub(/\[HM\]/,	"\212");		\
				gsub(/\[IX\]/,	"\213");		\
				gsub(/\[IMI\]/,	"\214");		\
				gsub(/\[INT\]/,	"\215");		\
				gsub(/\[SOS\]/,	"\216");		\
				printf($0)}'`
}



# Main program
LAST_NEWS_FETCH=0
FORCE_NEWS_RESEND=0

while [ 1 ];do
  echo "[REJECT INCOMING MESSAGES]"
  CURTIME=`date +%s`
  let TDIFF=CURTIME-LAST_NEWS_FETCH

  if [ $TDIFF -ge $CHECK_FRESH_NEWS_EVERY ];then
    if rss_news_to_cw $RSS_NEWS_FEED;then
      NEWS="[KA] $NEWS [AR]"
      echo "New newsbrief : $NEWS" 1>&2
      encode_prosigns
      FORCE_NEWS_RESEND=1
    fi
    LAST_NEWS_FETCH=`date +%s`
    TDIFF=0
  fi

  if [ $FORCE_NEWS_RESEND = 1 ];then
    echo -e $NEWS							\
	|./send_cw ascii $CWCHANNEL $CHAR_WPM $AVG_WPM			\
	"$CALLSIGN" "$GRIDSQUARE"
    FORCE_NEWS_RESEND=0
  fi

  echo "[ACCEPT INCOMING MESSAGES]"
  let REMAINING_TO_WAIT=CHECK_FRESH_NEWS_EVERY-TDIFF
  if read -r -t $REMAINING_TO_WAIT BOTNICK SENDER MSG;then
    if CWFRAME_PARAMS=`echo "$MSG" | ./decode_cw_frame`;then
      if [ "`echo $CWFRAME_PARAMS | awk '{c=$3;gsub(/cwchannel=/,"",c);	\
		print c}'`" = $CWCHANNEL ];then
        FORCE_NEWS_RESEND=1
        echo "Last newsbrief rerun requested by $SENDER." 1>&2
      fi
    fi
  fi
done
