#!/bin/bash
#variables
version=2.1 Beta
installdir="/usr/local/share/iptv-check"
sname=$0
wfile="$installdir/updated.m3u"
strmvld=""
downtime="2"
online="0"

#setup colors
cyan='\e[0;36m'
green='\033[92m'
red='\e[1;31m'
yellow='\e[0;33m'
orange='\e[38;5;166m'

function chknet () {
echo -e "GET http://google.com HTTP/1.0\n\n" | nc google.com 80 > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo -e "$red""- Not connected to Internet"
echo -e "$green""(This tool requires Internet Connection)"
exit 1
fi	
}

# Install to /usr/local/sbin and create fixed working directories
if [[ ! -d "$installdir" ]]
then
mkdir -p "$installdir/temp" >/dev/null 2>&1
cp $0 /usr/local/sbin/$0 >/dev/null 2>&1
chmod +x /usr/local/sbin/$0 >/dev/null 2>&1
echo -e "$green""- Iptv-check $version was installed on your system"
echo -e "$green""  From now on you can run it from any place on your shell"
echo -e "$green""  To run it just write :$cyan iptv-check " 
echo -ne "$yellow" "Press ENTER Key to continue"
read -r continue
fi

# Clean any files from previous run in temp folder
rm -rf $installdir/temp/* >/dev/null 2>&1

# Warning is a simple message that will display every 40 checks on streams to explain user how to quit
warn() {
if [[ $i -gt $wrn ]]
then
wrn=$((wrn+40))
else
if [[ $i == "$wrn" ]]
then
echo ""
echo -e "$red""Press CTRL+C To Stop or Abort IPTV list check"
echo ""
fi
fi
}

#Ctrl+C Interrupt to stop the script
trap ctrl_c INT
function ctrl_c() {
if [[ -f "$installdir/temp/pid.tmp" ]]
then	
pid=$(sed -n 1p < "$installdir/temp/pid.tmp")
rpid=$(ps -p "$pid" -o pid= | awk '{print$1}')
if [[ "$rpid" == "$pid" ]]
then
kill $pid >/dev/null 2>&1
exit 1
else
exit 1
fi	
else
exit 1
fi

}

logo() {
echo -e "$green" "IPTV-Check Tool $version"
echo -e "$yellow" "-------------------------------------"
echo -e "$blue" "http://github.com/peterpt"
echo -e "$yellow" "-------------------------------------"
chknet
echo -e "$red" "       NOTE"
echo -e "$green""This tool will download $downtime seconds of each stream to check"
echo -e "if every link in m3u file is valid , so , it may take a while"
echo -e "$yellow" "-------------------------------------"
echo ""

# checkig for wget if it is installed
which wget > /dev/null 2>&1
      if [ "$?" -eq "1" ]; then
   echo -e "$red" "Wget Missing"
echo ""
echo -e "$yellow" "Try : apt-get install wget"
exit 1
fi 
which ffmpeg > /dev/null 2>&1
      if [ "$?" -eq "1" ]; then
   echo -e "$red" "ffmpeg Missing"
echo ""
echo -e "$yellow" "Try : apt-get install ffmpeg"
exit 1
fi 
which tesseract > /dev/null 2>&1
      if [ "$?" -eq "1" ]; then
   echo -e "$red" "OCR Missing"
echo ""
echo -e "$yellow" "Try : apt-get install tesseract-ocr libtesseract-dev tesseract-ocr-eng"
exit 1
fi 
}

# The difference between writefile and writefile2 is that (writefile2) is to process the output from m3u files based in xml codes 
# while function (writefile) is to process in output file the conventional m3u files without xml codes in it
function writefile2() {
if [[ -f "$wfile" ]]
then
gturlline=$(grep -n "\<$chkf\>"<$installdir/temp/2 | tr ":" "\n" | sed -n 1p)
stdata=$(sed -n "$gturlline p"< $installdir/temp/2 | awk '{$1=""; print $0}')
echo "#EXTINF:-1 ,$stdata" >> "$wfile"
echo "$chkf" >> "$wfile"
echo "" >> "$wfile"
else
echo "#EXTM3U" > "$wfile"
echo "" >> "$wfile"
gturlline=$(grep -n "\<$chkf\>"<$installdir/temp/2 | tr ":" "\n" | sed -n 1p)
stdata=$(sed -n "$gturlline p"< $installdir/temp/2 | awk '{$1=""; print $0}')
echo "#EXTINF:-1 ,$stdata" >> "$wfile"
echo "$chkf" >> "$wfile"
echo "" >> "$wfile"
fi
}


function writefile() {
# checks if tool already created previously an m3u file
if [[ -f "$wfile" ]]
then
#searchs for that specific url in original file and get line number
gturlline=$(grep -n "$chkf"<$installdir/temp/1 | tr ":" "\n" | sed -n 1p)
# This variavble will get the line number before the previous url (this is to get channel name)
defline=$((gturlline-1))
stdata=$(sed -n "$defline p"< $installdir/temp/1)
echo "$stdata" >> "$wfile"
echo "$chkf" >> "$wfile"
echo "" >> "$wfile"
else
echo "#EXTM3U" > "$wfile"
echo "" >> "$wfile"
gturlline=$(grep -n "$chkf"<$installdir/temp/1 | tr ":" "\n" | sed -n 1p)
defline=$((gturlline-1))
stdata=$(sed -n "$defline p"< $installdir/temp/1)
echo "$stdata" >> "$wfile"
echo "$chkf" >> "$wfile"
echo "" >> "$wfile"
fi
}

#Checking if valid streams are really valid or have a bad login
function ocr () {
ffmpeg -ss 00:00:02 -i "$installdir/temp/stream.mp4"  -frames:v 1 "$installdir/temp/stream.png"	
tesseract -l eng "$installdir/temp/stream.png" "$installdir/temp/test"
chktxt=$(grep -i "error" "$installdir/temp/test.txt")
if [[ -z "$chktxt" ]]
then
strmvld="1"
online=$((online+1))
else
strmvld="0"
fi
}	

# Function for m3u files with xml content
function xmlproc() {

# Find http links only and delete all the other xml codes in the file , this works with many tests i did , but it may need more filtering for m3u files with more xml funtions in it
grep -F "http" < $installdir/temp/1 | sed 's/<link>//g' | sed 's/^.*http/http/' | sed 's/&amp.*|//' | sed -e 's/\(.ts\).*\(=\)/\1\2/' | sed 's/=/ /g' | sed "s~</link>~ ~g" > $installdir/temp/2
srvnmb=$(wc -l "$installdir/temp/2" | awk '{print$1}')
rm -rf "$installdir/temp/stream.mp4" >/dev/null 2>&1
rm -rf "$installdir/temp/pid.tmp" >/dev/null 2>&1
echo ""
echo -e "$red""Press CTRL+C To Stop or Abort IPTV list check"
echo ""
for i in $(seq "$srvnmb")
do
chkf=$(sed -n "${i}p" < "$installdir/temp/2" | awk {'print$1}')
chkurl=$(echo "$chkf" | head -c 4)
case "$chkurl" in
http|rtmp|HTTP)
ffmpeg -t $downtime -i "$chkf" -vsync 0 -acodec copy -vcodec copy -tls_verify 0 "$installdir/temp/stream.mp4" 
if [[ ! -f "$installdir/temp/stream.mp4" ]]
then
echo -e "$yellow" "Error reading captured file"
else
stsz=$(wc -c "$installdir/temp/stream.mp4" | awk '{print$1}')
if [[ "$stsz" -le "500" ]]
then
echo -e "$green" "Link:$yellow $i$green of :$yellow$srvnmb$green is$red OFF"
else
ocr
if [[ "$strmvld" == "1" ]]
then
echo -e "$green" "Link:$yellow $i$green of :$yellow$srvnmb$green is$green ON"
writefile2
else
echo -e "$green" "Link:$yellow $i$green of :$yellow$srvnmb$green is$red OFF (Bad Login)"
strmvld=""
fi
fi
fi
;;
*)
;;
esac
rm -rf $installdir/temp/*.png >/dev/null 2>&1
rm -rf $installdir/temp/stream >/dev/null 2>&1
rm -rf $installdir/temp/*.txt >/dev/null 2>&1
rm -rf $installdir/temp/pid.tmp >/dev/null 2>&1
warn
done
if [[ "$exts" == "0" ]]
then
if [[ -f "$wfile" ]]
then
echo ""
echo -e "$green" "Job Finished"
echo ""
echo -e "$green" "Got $online Online Channels "
echo ""
echo -e "$yellow" "You can find your new iptv list in :"
echo -e "$orange" "$wfile"
exit 1
fi
else
echo ""
echo -e "$green" "Job Finished"
echo ""
echo -e "$green" "Got $online Online Channels "
echo ""
echo -e "$yellow" "Your iptv list was update in :"
echo -e "$orange" "$wfile"
exit 1
fi
}	

# Function that will download for specific time the test stream
function teststream() {
wrn="0"
# Checks if tool already created a previous m3u file
if [[ -f "$wfile" ]]
then
exts="1"
else
exts="0"
fi

# checks if m3u file have xml content
ckf=$(grep "<item>" <$installdir/temp/1)
if  [[ ! -z "$ckf" ]]
then
xmlproc
fi 
#checks for the http links in m3u file
glnk=$(grep -F "http" < "$installdir/temp/1" | sed '/EXTINF/d' | sed '/EXTVLCOPT/d' | sed '/EXTM3U/d' | awk '!a[$0]++' | sed '/^$/d')

#Write all the http links only to a new file so they can be checked ahead
echo "$glnk" | tr " " "\n" > "$installdir/temp/2"
# Counts how many links must be checked
srvnmb=$(wc -l "$installdir/temp/2" | awk '{print$1}')
# removes any previous temp pid files and stream captures from previous run
rm -rf "$installdir/temp/stream.mp4" >/dev/null 2>&1
rm -rf "$installdir/temp/pid.tmp" >/dev/null 2>&1
echo ""
echo -e "$red""Press CTRL+C To Stop or Abort IPTV list check"
echo ""

# Starts the stream checks
for i in $(seq "$srvnmb")
do
chkf=$(sed -n "${i}p" < "$installdir/temp/2")
# To avoid errors in previous filter , it checks if the link starts with http , rtmp or HTTP
chkurl=$(echo "$chkf" | head -c 4)
case "$chkurl" in
http|rtmp|HTTP)
# start the stream download with wget , creates a file with the pid from wget
ffmpeg -t $downtime -i "$chkf" -vsync 0 -acodec copy -vcodec copy -tls_verify 0 "$installdir/temp/stream.mp4"

# checks if downloaded stream file it is in temp directory
if [[ ! -f "$installdir/temp/stream.mp4" ]]
then
echo -e "$green" "Link:$yellow $i$green of :$yellow$srvnmb$green is$red OFF"
else
# checks the size of the stream file
stsz=$(wc -c "$installdir/temp/stream.mp4" | awk '{print$1}')
# In case stream file is less than 500 bytes then it is not valid
if [[ "$stsz" -le "500" ]]
then
echo -e "$green" "Link:$yellow $i$green of :$yellow$srvnmb$green is$red OFF"
else
ocr
if [[ "$strmvld" == "1" ]]
then
echo -e "$green" "Link:$yellow $i$green of :$yellow$srvnmb$green is$green ON"
writefile
else
echo -e "$green" "Link:$yellow $i$green of :$yellow$srvnmb$green is$red OFF (Bad Login)"
strmvld=""
fi
fi
fi
;;
*)
;;
esac
rm -rf $installdir/temp/*.png >/dev/null 2>&1
rm -rf $installdir/temp/stream.mp4 >/dev/null 2>&1
rm -rf $installdir/temp/*.txt >/dev/null 2>&1
rm -rf $installdir/temp/pid.tmp >/dev/null 2>&1
warn
done
if [[ "$exts" == "0" ]]
then
if [[ -f "$wfile" ]]
then
echo ""
echo -e "$green" "Job Finished"
echo ""
echo -e "$green" "Got $online Online Channels "
echo ""
echo -e "$yellow" "You can find your new iptv list in :"
echo -e "$orange" "$wfile"
exit 1
fi
else
echo ""
echo -e "$green" "Job Finished"
echo ""
echo -e "$green" "Got $online Online Channels "
echo ""
echo -e "$yellow" "Your iptv list was update in :"
echo -e "$orange" "$wfile"
exit 1
fi
}	

# Case user m3u file is remote (http) then run this function
function remotef() {
# will download the remote m3u file to temp folder and will check its size
wget --no-check-certificate --user-agent="Mozilla/10.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" "$file" -O "$installdir/temp/1" >/dev/null 2>&1
flsz=$(wc -c "$installdir/temp/1" | awk '{print$1}')
if [[ "$flsz" -le "10" ]]
then
echo -e "$yellow" "The remote link is down or the file size of it"
echo -e "$yellow" "     is too small to be an m3u iptv list file"
echo ""
exit 0
fi
teststream
}

# Local m3u file is loaded here
function localf(){
if [[ ! -f "$file" ]]
then
echo -e "$yellow" "The file you specified does not exist"
echo -e "$yellow" "in :$green $file "
echo ""
echo -e "$yellow" "Make sure you wrote the right path of it"
exit 1
fi
cp "$file" "$installdir/temp/1" >/dev/null 2>&1
flsz=$(wc -c "$installdir/temp/1" | awk '{print$1}')
if [[ "$flsz" -le "10" ]]
then
echo -e "$yellow" "The file you specified is too small to be an m3u iptv file"
exit 0
fi
teststream
}
if [[ -z $1 ]] 
then
echo -e "$green" "IPTV-Check Tool $version"
echo -e "$yellow" "-------------------------------------"
echo -e "$blue" "http://github.com/peterpt"
echo -e "$yellow" "-------------------------------------"
echo ""
echo -e "$orange" "Example for remote list to check :"
echo -e "$green" "iptv-check http://someurl/somelist.m3u"
echo ""
echo -e "$orange" "Example for local list to check :"
echo -e "$green" "iptv-check /root/mylist.m3u"
echo ""
echo -e "$red" "       NOTE"
echo -e "$green""This tool will download $downtime seconds of each stream to check"
echo -e "if every link in m3u file is valid , so , it may take a while"
echo -e "$yellow" "-------------------------------------"
echo ""
exit 1
fi
# If a null file name is not found then executes the script again deflecting wget errors to dev/null
if [[ ! -f $installdir/null ]]
then
echo "0" > $installdir/null
exec $sname $1 2>/dev/null
exit 1
fi
# here it means that script already was loaded and restarted , so delete the null file for the next start
rm -rf $installdir/null >/dev/null 2>&1
logo
file="$1"
#check if user input is a remote or local file by searching for http word in the user input variable
chkfl=$(echo "$file" | grep "http")
if [ ! -z "$chkfl" ]
then
remotef
else
localf
fi
