#!/bin/bash
#########################################################################################
#
# Job manager for RSS feed media downloader.
#
#
# © Copyright 2012 Arto Jääskeläinen <temp001(at)pp.inet.fi>
# Part of Auto DL software package. All rights reserved.
# The program is distributed under the terms of the GNU General Public License
#
#    Auto DL is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    Auto DL is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with Auto DL.  If not, see <http://www.gnu.org/licenses/>.
#
#
# V1.02 2012-09-15
# V1.1  2012-10-16 Language detection & logging
# V1.2  2013-08-09 Load monitoring
#
#########################################################################################
version="1.2"

daemon_name="auto_dld"

autodld()
{
get_conf()
{
path_file="$1"
conf_par="$2"
if [ -f "$path_file" ] && [ -n "$conf_par" ]; then
	line=$(cat "$path_file" | sed 's/^#.*//g' | grep -wi "$conf_par")
	if [ -n "$line" ]; then
	response=$(echo ${line##*=})
	else
	response=""
	fi
else
	return 1 
fi
}

get_system_conf()
{
local system_conf_path="/etc/autodl.conf"
if [ "$1" = "" ]; then
return 1
fi
get_conf "$system_conf_path" "$1"
if [ $? = "0" ] && [ -n "$response" ]; then 
conf=$response
else
conf=""
return 1
fi
}

get_os_conf()
{
local system_conf_path="$1"
if [ "$1" = "" ]; then
return 1
fi
get_conf "$system_conf_path" "$2"
if [ $? = "0" ] && [ -n "$response" ]; then 
conf=$response
else
conf=""
return 1
fi
}

define_setting()
{
local var_name="$1"	
local default="$2"	
get_system_conf "$var_name"
if [ $? = "0" ]; then
setting=$conf 
eval echo -e "$(date "+%F %T %z") System defined $var_name=$setting" $pipe_to_log
else
setting="$default"
if [ -z "$setting" ]; then show_setting="no"; else show_setting=$setting; fi
eval echo -e "$(date "+%F %T %z") Default $var_name=$show_setting" $pipe_to_log 
fi
}

set_default_language()
{
get_os_conf "/etc/default/locale" "LANG"
os_conf=$conf
if [ -n "$os_conf" ]; then 
default_language="$os_conf"
else
default_language="en_US.UTF-8"
fi
}

set_language()
{
set_default_language
define_setting "LANG" "$default_language"
}	

logging()
{
sw=$1
if [ $(echo ${sw,,}) = "on" ]; then
pipe_to_log=" | tee -a $logs_dir/$log_file"
else
if [ $(echo ${sw,,}) = "off" ]; then
pipe_to_log=""
fi
fi	
}
	
close_all()
{
pass_error="$*"
terminate_jobs
echo
echo "$(date "+%F %T %z") Job manager closed" | tee -a $logs_dir/$log_file
cd /tmp
if [ "${#work_dir}" -gt 15 ] && [ -d "$work_dir" ] ; then
rm -rf $work_dir 2>/dev/null
fi
rm /var/run/$daemon_name.pid &>/dev/null
cd /
killall loadmon	
exit $pass_error
}

init()
{
logging on
echo $BASHPID >/var/run/$daemon_name.pid	
mkdir -p $data_root
if [ ! -d $data_root ]; then
echo "Failed to find data root." | tee -a $data_root/logs/$log_file 
close_all 64  
fi 	
mkdir -p $logs_dir
touch $logs_dir/$log_file
if [ ! -f $logs_dir/$log_file ] ; then
	echo
	echo "$(date "+%F %T %z") Failed to find log file." | tee -a $logs_dir/$log_file
	close_all 65
fi
rm -rf $data_root/.live_data/* &>/dev/null
mkdir -p $data_root/.live_data/$BASHPID
if [ ! -d $data_root/.live_data/$BASHPID ] ; then
	echo
	echo "$(date "+%F %T %z") Failed to find work directory." | tee -a $data_root/logs/$log_file
	close_all 66
fi
work_dir=$data_root/.live_data/$BASHPID
mkdir -p $data_root/jobs_done
if [ ! -d $data_root/jobs_done ]; then
echo "$(date "+%F %T %z") Failed to find $data_root/jobs_done" | tee -a $data_root/logs/$log_file
close_all 68
fi
rm -rf $run_dir/* &>/dev/null
cd $work_dir
trap close_all HUP INT USR1 USR2 TERM
}
	

idle()
{
time=30	
for (( i=$(($time)); i>0; i-- )) do
echo -ne "\rIdle...$((i*1)) s   "
sleep 1
done
echo -ne "\r                   \r"	
}

close_job()
{
job="$*"	
my_pid=$(ls "$run_dir/$job/")
rss_link=$(echo $job | sed 's/|/\//g')
pid_match_par=$(cat /proc/$my_pid/cmdline | tr '\0' ' ' | grep -c "$rss_link")
if [ "$pid_match_par" != "0" ]; then 
	echo "$(date "+%F %T %z") Shutting down service, pid=$my_pid" | tee -a $logs_dir/$log_file
	kill $my_pid
	rm -rf $run_dir/$job
	return 0   
else
	echo "$(date "+%F %T %z") pid mismatch $start_par | $job  " | tee -a $logs_dir/$log_file
	return 1
fi
}

terminate_jobs()
{
echo
echo "$(date "+%F %T %z") Terminating all jobs..." | tee -a $logs_dir/$log_file	
if [ -n "$(ls -A "$run_dir")" ]; then	#Anything in run_dir
	for pathfile in $run_dir/*
	do
		if [ -n "$(echo $pathfile | grep "http:||")" ]; then
			job_name=$(echo $pathfile | sed 's/\(.*\)\(http:.*\)/\2/g')
			close_job $job_name
			echo "$(date "+%F %T %z") Closed job $job_name" | tee -a $logs_dir/$log_file
		fi
	done
echo "$(date "+%F %T %z") All jobs terminated" | tee -a $logs_dir/$log_file	
fi
}

start_job()
{
job_to_start="$1"	
link_to_pass="$2"
home_dir="$3"
($inst_dir/$s_name "$link_to_pass" "$home_dir" &>/dev/null) &  
if [ -n "$!" ]; then		#Sure started by us ?
	mkdir -p $run_dir/$job_to_start 
	touch $run_dir/$job_to_start/$! 
	echo "$(date "+%F %T %z") Started, pid=$!, job=$job_to_start  $home_dir" | tee -a $logs_dir/$log_file
	return 0
	else
	echo "$(date "+%F %T %z") Failed to start job $job_to_start  $home_dir" | tee -a $logs_dir/$log_file
	return 1
fi
}

find_all_jobs()
{
rm -rf $inst_dir/all_jobs/*	
find /home/*/.auto_dl/adl_jobs/* 2>/dev/null | sed 's/\(.*\)\(http:.*\)/\2/g' \
| xargs -r -n 1 -I{} mkdir -p $inst_dir/all_jobs/{}	
}
	
inst_dir=/opt/auto_dl
data_root=$inst_dir/.auto_dl
logs_dir=$inst_dir/logs
run_dir=$data_root/running
log_file="auto_dld.log"
s_name="get_feed"   
init
started=$(date "+%F %T %z")
echo -e "\n----------------------------------------------------------"
echo "$(date "+%F %T %z") Auto DL Job Manager V$version started" | tee -a $logs_dir/$log_file
echo -e "----------------------------------------------------------"
set_language
$inst_dir/loadmon &
while : 
do
found=""
for pathfile in /home/*/.auto_dl/adl_jobs/*  
do
if [ $pathfile != '/home/*/.auto_dl/adl_jobs/*' ]; then
	rss_link=$(echo $pathfile | sed 's/|/\//g; s/\(.*\)\(http:.*\)/\2/g')
	home_path=$(echo $pathfile | cut -d "/" -f1-3)   
	username=$(echo ${home_path##*/})
	new_job=$(echo ${pathfile##*/})
	
	if [ ! -d "$run_dir/$new_job" ]; then 
		echo "$(date "+%F %T %z") Starting a job for user $username" | tee -a $logs_dir/$log_file
		start_job "$new_job" "$rss_link" "$home_path"
		found="true"
		sleep 0.5 
	fi
fi
done
if [ -z "$found" ]; then
	echo "No new jobs."
fi
	
found=""
for pathfile in $run_dir/*
do
if [ $pathfile != $run_dir/'*' ]; then
	job=$(echo $pathfile | sed 's/\(.*\)\(http:.*\)/\2/g')  
	find_all_jobs
	if [ ! -d "$inst_dir/all_jobs/$job" ]; then
		echo "$(date "+%F %T %z") Closing expired job $job" | tee -a $logs_dir/$log_file
		close_job $job
		echo "Done."
		found="true"
	fi
fi
done
if [ -z "$found" ]; then
	echo "  No deleted jobs."
fi
idle
done  
terminate_jobs
close_all 0
}
run_mode="daemon"
[[ "$@" = "--foreground" ]] && run_mode="foreground"
if [ "$(pgrep -c $daemon_name)" -lt 2 ]; then 
	if [ $run_mode = "daemon" ]; then
		exec 2>&- 1>&- 0>&-  
		(autodld &) &
	else
		autodld
	fi
fi

