#!/bin/bash
#
# Bash script for playing Live streams of Olympic Games.
#
# Thanks to: Martin Beránek (mousehouse) - providing URL extraction method
#            hikikomori82 - compatible sed with older version
#            Jakub Lucký - various code enhancements (dumpstream)
#            Marián Kyral - Generate token, store it in ~/.zoh.token
#
#  Copyright (c) 2010 Radek Novacek
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation
# files (the "Software"), to deal in the Software without
# restriction, including without limitation the rights to use,
# copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following
# conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.

# Replace with your favorite player
COMMAND="smplayer -playlist"

TOKEN_FILE=~/.zoh.token

DOWNLOADER=$(which curl 2>/dev/null)
[ -z "$DOWNLOADER" ] &&  DOWNLOADER=$(which wget 2>/dev/null)

if [ -z "$DOWNLOADER" ]
then
  echo "Error: No curl or wget binary found. Please install at least one"
  exit 1
fi

help() {
    echo "$1" 
    echo
    echo "Usage: zohd.sh VIDEO [mplayer | dump [outfile]]"
    echo "       zohd.dh ARCHIVE URL [mplayer | dump [outfile]]"
    echo
    echo "VIDEO: CT2OH, CT4OH, CTHD, ZOH1, ZOH2, ZOH3, ZOH4, ZOH5, ZOH6"
    echo  
    exit 1
}

getHTML() {

  HEADER="Content-Type: text/xml; charset=utf-8"
  COOKIE=$(mktemp)
  DPROG=$(basename $DOWNLOADER)
  URL="$1"

  if [ "$2" ]
  then
    if [ "$DPROG" = "curl" ]
    then
        curl -H "$HEADER" -H "SOAPAction: \"http://ivysilani.visual.cz/services/GetPlaylistUrl\"" -L -c $COOKIE -d "@$2" "$URL"
    else
        wget --output-document=- --save-cookies=$COOKIE --load-cookies=$COOKIE --keep-session-cookies --header="$HEADER" --header="SOAPAction: \"http://ivysilani.visual.cz/services/GetPlaylistUrl\"" --post-file=$2 "$URL"
    fi
  else
    if [ "$DPROG" = "curl" ]
    then
        curl -H "$HEADER" -L -c $COOKIE "$URL"
    else
        wget --output-document=- --save-cookies=$COOKIE --load-cookies=$COOKIE --keep-session-cookies --header="$HEADER" "$URL"
    fi
  fi

  rm -f $COOKIE
}

getToken() {
  TOKEN=$(echo $(getHTML http://zoh.ct24.cz/live.asp 2>/dev/null |grep  -i token |sed  's/^.*token=\([^,]*\).*$/\1/'))
  [ "$TOKEN" ] && echo "TOKEN=\"$TOKEN\"" > "$TOKEN_FILE"
  echo $TOKEN
}

getArchiveVideo() {
  URL=$1
  VIDEO="$(getHTML "$URL" |grep "video=" |sed 's/,/\n/g' | grep video |sed 's/video=//')"
  echo $VIDEO
}

getPlaylist() {
TEMP=$(mktemp)

TOKEN="$1"
ID="$2"

if [ "$ID" = "CTHD" ]
then
  QUALITY=WHD
else
  QUALITY=WH
fi

TYPE="Live"

if [ "$(echo "$ID" | cut -c 1-3 )" = "ZOH" ]
then
  if [ "$(echo "$ID" | cut -c 4-)" -gt 6 ]
  then
    TYPE="Archive"
  fi
fi

EXPIRE=`date +%FT%T.%N%:z --date="4 hours"`

cat << EOF > $TEMP
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <GetPlaylistUrl xmlns="http://ivysilani.visual.cz/services">
            <request>
                <Format>$QUALITY</Format>
                <ClientAddress>$TOKEN</ClientAddress>
                <Expiration>$EXPIRE</Expiration>
                <Playlist>
                    <PlaylistItem>
                        <Type>$TYPE</Type>
                        <Identifier>$ID</Identifier>
                    </PlaylistItem>
                </Playlist>
            </request>
        </GetPlaylistUrl>
   </soap:Body>
</soap:Envelope>
EOF


echo $(getHTML http://ctdir.visual.cz/ivysilani/services/streaming/slp.asmx "$TEMP" \
     | sed 's/</\n</g' | grep GetPlaylistUrlResult | sed 's/>/\n/' | grep http)

rm -f $TEMP

}

loadToken() {
  if [ -f "$TOKEN_FILE" ]
  then
    . "$TOKEN_FILE"
  else
    TOKEN=$(getToken)
  fi
  echo $TOKEN
}

playChanel() {
  TOKEN=$(loadToken)
  echo "====================================================="
  echo "Using token $TOKEN"
  echo

  PLAYLIST=$(getPlaylist "$TOKEN" "$ID" )

  echo "===================================================================================="
  echo "Playlist: $PLAYLIST"
  echo "===================================================================================="
  echo

  if [ -z "$PLAYLIST" ]
  then
    echo "Error: Playlist url is incorrect"
    return 1
  else
    $COMMAND "$PLAYLIST"
  fi

}

if [ $# -lt 1 ];
then
  help
fi

# parse command line options
i=1
while [ "$1" ]
do

  if [ $i -eq 1 ]
  then
    if [ $(echo "$1" |egrep -c "CT4OH|CT2OH|ZOH1|ZOH2|ZOH3|ZOH4|ZOH5|ZOH6|CTHD|ARCHIVE") -gt 0 ]
    then
      ID=$1;
      if [ "$ID" = "ARCHIVE" ]
      then
        shift
        ARCHIVE_URL="$1"
      fi
    else
      help "Error: Missing argument!"
    fi
  elif [ $i -eq 2 ]
  then
    if [ "$1" = "dump" ]
    then
      COMMAND="mplayer -dumpstream -playlist "
    elif [ -n "$2" ]
    then
      COMMAND="mplayer -dumpfile $2 -dumpstream -playlist "
    elif [ "$1" = "mplayer" ]
    then
      COMMAND="mplayer -playlist"
    else
      help
    fi
  fi

  (( i = i + 1 ))
  shift
done


if [ "$ID" = "ARCHIVE" -a -z "$ARCHIVE_URL" ]
then
  help "Error: Missing Archive URL"
fi

if [ "$ID" = "ARCHIVE" -a  $(echo "$ARCHIVE_URL" |grep -c "^http") -eq 0 ]
then
  help "Error: Invalid Archive URL: $ARCHIVE_URL"
fi

if [ "$ARCHIVE_URL" ] 
then
  ID=$(getArchiveVideo "$ARCHIVE_URL")
  echo "ARCHIVE_ID: $ID"
  if [ -z "$ID" ]
  then
    echo "Sorry, cannot download the archive ID"
    exit 1
  fi
fi

playChanel
if [ $? -gt 0 ]
then
  echo "Generating new token..."
  TOKEN=$(getToken)
  playChanel
  if [ $? -gt 0 ]
  then
    echo "Sorry, cannot fetch playlist"
  fi
fi

