#!/bin/bash

######################################################################
# This script is an adaptation of one produce by                     #
# Glutanimate and called yad_wget 0.2 2014                           #
# LICENSE: GNU GPLv3                                                 #
# Author:  clareoldie <clareoldie@gmail.com>                         #
# Date:	   July2017; Feb2018; July2019; Aug2019; Dec2019; June2023   #
# Version:   0.3;      1.0;      1.2;     2.0;   3.0->3.2            #
# Depends on yad, wget                                               #
######################################################################

set -x

Setup() {
##################################################
# Set up storage & icons to use
##################################################
	mkdir -p $HOME/.GetPclos
	TMP=$HOME/.GetPclos
	cd $HOME/.GetPclos
	TITLE="PCLinuxOS ISO Downloader v.3.2"                          # dialog title
	IMAGE="/usr/share/icons/GetPCLOS/mini-black-bull.png"           # image in window
	ICON="/usr/share/icons/GetPCLOS/download-black-bull.png"        # window icon
	AGAIN=0
	IFSHOLDER="$IFS"
}

#
TestNet() {
##################################################
# Test for network connection:
##################################################
	YADTXT="\n\n\n        <b>Testing your internet connection to the PCLinuxOS server</b>   \n\n"
	yad --center --window-icon "$ICON" --width=700 --height=100 \
		--text=$"$YADTXT" --title "$TITLE" --window-icon "$ICON" \
		--image "$IMAGE" --no-buttons --timeout 2
	wget -q --tries=1 --timeout=2 --delete-after "http://ftp.nluug.nl/"
	Foo="$?"
	if [[ $Foo -ne 0 ]]
	then
		YADTXT="\n\n\n        <b>Testing your internet connection to the PCLinuxOS server</b>   \n\n"
		yad --center --window-icon "$ICON" --width=700 --height=100 \
			--text=$"$YADTXT" --title "$TITLE" --window-icon "$ICON" \
			--image "$IMAGE" --no-buttons --timeout 2
		wget -q --tries=3 --timeout=10 --delete-after "http://ftp.nluug.nl/"
		Foo="$?"
		if [[ $Foo -ne 0 ]]
		then
			YADTXT="\n        <b>We failed to get a connection to the chosen"
			YADTXT=$YADTXT"PCLinuxOS mirror.</b>   \n \n               This "
			YADTXT=$YADTXT"utility will now close.     Please try again a little later.   "
			`yad --on-top --center --window-icon "$ICON" --width=700 --height=100 \
				--text=$"$YADTXT" --title "$TITLE" --window-icon "$ICON" --image "$IMAGE" \
				--button=OK:0`
			CleanUp
		fi
	fi
}

#
MyMirror() {
##################################################
# Get Mirror URL
##################################################
    YADTXT="\n      Please wait while we connect to your default/selected server\n"
    YADTXT=$YADTXT"                                               to list the ISOs. \n\n"
    YADTXT=$YADTXT"                                This might take a minute or so.  \n"
    yad --title "$TITLE" --information --center --width=600 --window-icon "$ICON" \
		--no-buttons --timeout=60 --timeout-indicator=bottom \
		--text="$YADTXT" &
	yad_pid=$(echo $!)

##################################################
# Get a stored URL for preferred mirror
##################################################
	Mirror=$(cat $TMP/mirror)
	if [ "$Mirror" = "" ]
	then
# Get the mirror URL selected in Synaptic and edit it for isos.
		Mirror=$(cat /etc/apt/sources.list | grep -v '#' | cut -d ' ' -f2 | \
					sed 's|apt|iso|')
		echo $Mirror
# If the mirror URL does not begin with "http:" then ignore it and use NLUUG instead
		TEST=$(echo $Mirror | sed '/^[^http:]/ d')
		if [ "$TEST" = "" ]
		then
			Mirror="http://ftp.nluug.nl/os/Linux/distr/pclinuxos/pclinuxos/iso/"
			echo "$Mirror" > $TMP/mirror
		fi
	fi
}

#
GetISOs(){
# Variables for the two specific locations for ISOs on the servers
	Mirror64="$Mirror"
    touch $TMP/isos_pcl
# Get the ISOs at the selected location and put their names in the specified file
	curl -s $Mirror64 | grep -oP '(?<=href=")[^"]*' | \
		grep .iso | \
		sed "s|^|$Mirror64|g" | \
		grep -v -i ".md5" > $TMP/isos_pcl
#
# Replace the GetCommunityISOs function with this
    MirrorComm="$Mirror"community/
    curl -s $MirrorComm | grep -oP '(?<=href=")[^"]*' | \
        grep .iso | \
        sed "s|^|$MirrorComm|g" | \
        grep -v -i ".md5" >> $TMP/isos_pcl
#
    save_LC_ALL=$LC_ALL
    export LC_ALL=C				 # set language to English for command output
    rm -f $TMP/isos_pcl_new
    touch $TMP/isos_pcl_new
    while read iline
    do
        wget --spider $iline -o $TMP/flen
        filelen=$(grep -e "^Length:" $TMP/flen | awk '{print $3}')
        echo "$iline$filelen" >> $TMP/isos_pcl_new
    done < $TMP/isos_pcl
    export LC_ALL=$save_LC_ALL
# Take out space before Size to divide dirname & basename and then 
# introduce space after .iso - apply the list to $ISOS
# Variable
    ISOS=$( for i in $(cat $TMP/isos_pcl_new | sed 's| ||g')
            do
                echo $(dirname $i)/" "$(basename $i | sed 's|\.iso|.iso |g')
            done)
# File
    for i in $(cat $TMP/isos_pcl_new | sed 's| ||g')
    do
        echo $(dirname $i)/" "$(basename $i | sed 's|\.iso|.iso |g')
    done > $TMP/ISOS
}
#
Selection() {
	foo="4"
	IFS="$IFSHOLDER"
	while [ "$foo" = "4" ]
	do
# Add :HD after column text to hide the column from the display if required
		Selected1=$(yad --on-top --center --window-icon "$ICON" --image "$IMAGE" \
						--text "$Mirror" --title "$TITLE" --width 700 --height 500 \
						--list `echo $ISOS` \
						--column "           Path to ISO":HD \
						--column "  Select an ISO and click the Download ISO button to Download it" \
						--column "Size" \
						--separator=  --sep-value=".iso" --buttons-layout=center \
						--button="Download ISO":0 \
						--button="New Mirror":3 \
						--button="Quit Application":1)
		foo=$?
		echo "$Selected1" > $TMP/selected
		if [[ $foo -eq 1 ]]
		then
			echo "Line 157"
			CleanUp
        elif [[ $foo -eq 252 ]]
        then
			echo "Line 160"
			CleanUp
        elif [[ $foo -eq 3 ]]
		then
			SelectNewMirror
        elif [[ $foo -eq 0 ]]
        then
			echo "Continue the script"
        fi
    done
}

#
SelectNewMirror() {
	AllMirrors=$(cat /etc/apt/sources.list | \
					sed 's|# ||' | \
					sed 's|rpm ||' | \
					grep "http://" | \
					cut -d " " -f1 | \
					sed 's|apt|iso|' )

	Mirror=$(	yad --center --window-icon "$ICON" --image "$IMAGE" --title "$TITLE" \
					--text "        Select a Server" --width 735 --height 300 \
					--list `echo $AllMirrors` \
					--column "Current List of Servers - Make your selection" \
					--button="Select Server":0)
	Mirror=$(echo $Mirror | cut -d '|' -f1)
	echo ""
	echo "$Mirror" > $TMP/mirror
	Mirror64="$Mirror"
# Generate a new list
	UpDateList
# Call Selection again
	Selection
}

#
UpDateList() {
# In case of mirror change this is required
	GetISOs
# Copy ISOs from source file to working file
#	cat $TMP/isos_pcl > $TMP/isos_names
	sleep 1
    kill $yad_pid
}

########################################
#### Set up target folder etc
########################################
ISOandFolder() {
# Correct the name to give a valid path.
#	Strip size info leaving valid URL for download
	Selected=$(cat $TMP/selected | sed 's|\.iso.*|.iso|g')
# Strip extension from 'Selected', leaving 'path & filename' as $ISONAME
	ISONAME=${Selected%.*}
# Strip remaining part path from ISO to give the directory name
	DirName=$(basename $ISONAME)

# Import stored Target directory from last use and 'cd' to it
	Target=$(cat $TMP/target)
	cd $Target
# Get user selected download directory
    Target=$(	yad --center --window-icon "$ICON" --image "$IMAGE" --width=875 --height=500 \
					--file-selection \
					--button=OK:0 \
					--button="Quit Application":1 \
					--directory --title "$TITLE" \
					--text="\n            <b>Select the Download target Directory for     $DirName</b>")
	if [[ $? -ne 0 ]]
	then
		CleanUp
	fi
# Store selected Target directory for next use
	echo $Target > $TMP/target
# Create a unique directory for the download if it does not exist.
    if ! test -d $Target/$DirName
    then
		mkdir -p $Target/$DirName
    fi
# CD to DirName Directory
	cd $Target/$DirName
}

####################### Working Section #############################
#### Do download set up then download the chosen files
#####################################################################
DownLoad() {
# Set Yadbars empty for each run
	YADBARS=""
# set maximum number of simultaneous downloads.
	MAXDLS="2"
# Provide the filenames to download
	URILIST="$Selected $ISONAME.md5sum "
	sleep 0.5
	USAGE="$0 <space-delimited URLs>"
# Setup GUI variables
	TEXT="<b>Downloads</b> in progress:"        # dialog text
# Check for provided URIs
	if [[ -z "$URILIST" ]]
	then
		echo "Error: No arguments provided"
		echo "Usage: $USAGE"
		exit 1
	fi
#
# Call 'downloadISO' to download file and extract progress, speed and ETA from wget
	downloadISO
#
# compose list of bars for yad progress display
	for URI in $URILIST
	do                     						# iterate through all URIs
		FILENAME="${URI##*/}"					# extract last field of URI as filename
		YADBARS="$YADBARS --bar=$FILENAME:NORM"	# add filename to the list of URIs
	done
#
	IFS=" "
	COUNTER="1"
	DYNAMIC_COUNTER="1"
#
# Main:- Go through all URIs, download them in the background and
# pipe all output simultaneously to yad
	for URI in $URILIST
	do
		if [[ "$DYNAMIC_COUNTER" = "$MAXDLS" ]]	# only download n files at a time
		then
			downloadISO "$URI" "$COUNTER"		# if limit reached wait until wget complete
			DYNAMIC_COUNTER="1"					# before proceeding (by not sending downloadISO() to bg)
		else
			downloadISO "$URI" "$COUNTER" &		# pass URI and URI number to downloadISO()
			DYNAMIC_COUNTER="$[$DYNAMIC_COUNTER+1]"
		fi
		COUNTER="$[$COUNTER+1]"					# increment counter
		sleep 1
	done | \
				yad --width=715 --center --multi-progress --auto-kill $YADBARS \
					--text "$TEXT" \
					--title "$TITLE" --window-icon "$ICON" --image "$IMAGE" \
					--auto-close
# ↑ launch yad multi progress-bar window
}

########################################
#### Display download progress etc
########################################
downloadISO(){
# Download file and extract progress, speed and ETA from wget
    wget -c "$1" 2>&1 | sed -u \
    "s/.* \([0-9]\+%\)\ \+\([0-9,.]\+.\) \(.*\)/$2:\1\n$2:# Downloading at \2b\/s, ETA \3/"
    RET_WGET="${PIPESTATUS[0]}"             # get return code of wget
    if [[ "$RET_WGET" = 0 ]]                # check return code for errors
      then
          echo "$2:100%"
          echo "$2:#Download completed."
      else
          echo "$2:#Download error."
    fi
}


CheckMD5sum() {
# Check MD5sum and prompt user with result.
	md5sum -c $DirName.md5sum 2>&1 | \
		yad --on-top --center --button=Close:1 --window-icon "$ICON" --image "$IMAGE" \
			--form --width=665 \
			--text="    ...  Checking ISO MD5sum  ...  Please Wait for the Result  ..." \
			--field="" --title "$TITLE"
}

CleanUp() {
	rm -f $TMP/isos_pcl $TMP/isos_pcl_new $TMP/selected $TMP/flen $TMP/ISOS
	exit 0
}

##################################################
############ Call the functions ##################
##################################################
	Setup                   # Set up variables
#
	TestNet                 # Test connection to internet
#
	MyMirror                # Get default user server/mirror
#
	UpDateList              # Create combined ISO list & store it
#
# If a second run required then start here
	AGAIN=0
	while [ $AGAIN -eq 0 ]
	do
		Selection
		ISOandFolder
		DownLoad
		CheckMD5sum
		yad --center --window-icon "$ICON" --image "$IMAGE" --title "$TITLE" \
			--text "\n       Do You Wish To Download Another ISO? \n\n" \
			--buttons-layout=center --width=525 --window-icon "$ICON" \
			--button="Quit Application":1 \
			--button="Download Another ISO":0
		AGAIN="$?"
	done
	CleanUp
	exit
