#!/bin/bash
#Name: dl2.sh
Description="SaveTV-Download-Script v"
#Dependencies: curl, bc, sleep, ps, tail, mv, let, tr, (screen)
#Author: Thomas Jungbauer
#Author-e-Mail: thomas@jungbauer-online.net
#License: WTFPL
#License-Text-Url: http://sam.zoy.org/wtfpl/COPYING
Version="2.11.4"
#Relase-Date: 02.06.2011
#Last-change-Date: 18.08.2012
########
#Config
########
TEMPDIR="./.tmp-savetv"
LOOPSLEEP="2"
LOCKFILE="/tmp/dl-savetv.pid"
DLLINKSFILE="./download.txt"
MAXDONWLOADS="2"
KUNDENNUMMER="_123456789"
SPEED="250k"
DOWNLOADDIR="."
CURLWAITTIME="100"
DF="/mnt/smb/savetv/debug.txt"
########
#Funktionen: Hier kommen die Funktionen, welche später benutzt werden.
########
function exit_all {
#Diese Funktion wird bei STRG+C ausgeführt.
#Hier wird aufgeräumt und die CURL-Prozesse beendet.
echo "Heruntergeladen aufnahmen:"
cat $TEMPDIR/Logs/Last-Download.txt 2>/dev/null ||echo "-"
echo "Download-Script wird vorzeitig beendet!"
PID=`cat $LOCKFILE`
for CPID in `ps h --ppid $PID -o pid`; do
#CPID von 1. Child Prozess (dl2.sh)
for CURLPID in `ps h --ppid $CPID -o pid`; do
kill -9 $CURLPID 2>/dev/null
done
kill -9 $CPID 2>/dev/null
done
exit 0
}
trap exit_all SIGINT
function create_temp_dirs {
#Diese Funktion erstellt die Temp-Ordner
TEMPSUBFOLDERS="01-New-Jobs 02-Queue 03-Queue2 04-Download 05-Finish 11-Retry-Later 12-Duplicate Logs DownloadTemp"
for SUBDIR in $TEMPSUBFOLDERS ; do
if [ ! -d $TEMPDIR/$SUBDIR ]; then
mkdir --parents $TEMPDIR/$SUBDIR
fi
done
}
function jobs_back_to_queue {
#Diese Funktion verschiebt die unvollendeten Jobs zurück in die Warteschlange.
if [ `ls -1 $TEMPDIR/04-Download/*.job 2>/dev/null |wc -l` != 0 ]; then
mv $TEMPDIR/04-Download/*.job $TEMPDIR/03-Queue2/
fi
}
function add_jobs_to_queue {
#Diese Funktion teilt die $DLLINKFILE in einzeile Jobs auf.
count=0
if [ -f $DLLINKSFILE ]; then
for LINK in `cat $DLLINKSFILE`; do
echo $LINK >$TEMPDIR/01-New-Jobs/`date +%Y%m%d-%H%M%S`-$count.job
let count=count+1
rm $DLLINKSFILE
touch $DLLINKSFILE
done
else
touch $DLLINKSFILE
fi
echo $count "Jobs wurden der Download-Warteschlange hinzugefügt."
}
function filter_duplicate {
#Hier werden die Duplicate nach 12-Duplicate aussortiert.
#Die andern Job kommen nach 03-Queue2
if [ `ls -1r $TEMPDIR/02-Queue/*.job 2>/dev/null |wc -l` != 0 ]; then
FILE=`ls -1r $TEMPDIR/02-Queue/*.job | tail -n 1`
#URL=`cat $FILE |grep http:`
URL=`tail -n 1 $FILE `
DUPLICATE=`cat $TEMPDIR/03-Queue2/*.job $TEMPDIR/04-Download/*.job $TEMPDIR/05-Finish/*.job 2>/dev/null | grep $URL | wc -l`
if [ $DUPLICATE != 0 ]; then
#Duplicat: Datei wird nach 12-Duplicate verschoben
echo "Bereits heruntergeladen:" `sed -n '2p' $FILE` >>$TEMPDIR/Logs/Last-Download.txt
mv $FILE $TEMPDIR/12-Duplicate
else
#Kein Duplicat: Datei wir nach 03-Queue2 verschoben
mv $FILE $TEMPDIR/03-Queue2
fi
fi
}
function add_filname_to_job {
#Diese Funktion fügt den Dateinamen dem Jobfile hinzu
#Manchmal bekommt man keinen Namen, dann wird der
#Job später nochmal probiert
URL=`cat $1 |grep http`
curl -s -g --head $URL >$TEMPDIR/headertmp.txt 2>/dev/null
FNAME=`cat $TEMPDIR/headertmp.txt | grep Content-Disposition | awk -F '[=\r]' '{print $2}'`
FSIZE=`cat $TEMPDIR/headertmp.txt | grep Content-Length | cut -c 17- `
FDATE=`cat $TEMPDIR/headertmp.txt | grep Last-Modified | cut -c 16- `
FETAG=`cat $TEMPDIR/headertmp.txt | grep Etag | cut -c 7- | xargs `
rm $TEMPDIR/headertmp.txt
#Umlaute un komische Zeichen werden durch _ Ersetzt
FNAME=`echo $FNAME | tr '\200'-'\377' _ `
#Kundennummer wird entfernt
FNAME=`echo ${FNAME//$KUNDENNUMMER/""}`
FNAMELENGTH=`echo $FNAME | wc -m`
#echo $FNAME
if [ $FNAMELENGTH -ge 3 ]; then
#Die while-Schleifen sorgen dafür, das keine vorhandene Datei
#überschrieben wird.
#In seltenen Fällen kommt es vor, das 2 unterschiedliche
#URLs den gleichen Dateinamen ergeben.
while [ -e $TEMPDIR/DownloadTemp/$FNAME ]; do
FNAME=`echo $FNAME-1.avi`
done
while [ -e $DOWNLOADDIR/$FNAME ]; do
FNAME=`echo $FNAME-2.avi`
done
#TODO: Hier müssen noch die Dateinamen von den Jobs in der Warteschlange
###### überprüft werden. (02-Queue und 03-Queue2)
#Zeile 1: URL
#Zeile 2: Filename
#Zeile 3: Dateigröße
#Zeile 4: Dateidatum
#Zeile 5: Etag
echo $FNAME >>$1
echo $FSIZE >>$1
echo $FDATE >>$1
echo $FETAG >>$1
mv $1 $TEMPDIR/02-Queue/
else
mv $1 $TEMPDIR/11-Retry-Later/
fi
}
function get_filenames {
#Hohlt die Dateinamen vom Server.
#Pro Aufruf wir nur 1 Datei bearbeitet!!!
#Benötigt die folgenden Funktionen
#add_filname_to_job
if [ `ls -1r $TEMPDIR/01-New-Jobs/*.job 2>/dev/null |wc -l` != 0 ]; then
FILE=`ls -1r $TEMPDIR/01-New-Jobs/*.job | tail -n 1`
#Dateiname wird dem Job hinzugefügt
add_filname_to_job $FILE
else
#Es werden die Retrys zurück in den Ausgangsordner kopiert
mv $TEMPDIR/11-Retry-Later/*.job $TEMPDIR/01-New-Jobs/ 2>/dev/null
fi
}
function start_download_file {
#Hier wird 1 Download-Job gestartet (Als Background-Job)
FILE=`ls -1r $TEMPDIR/03-Queue2/*.job | tail -n 1`
URL=`cat $FILE|grep http`
#FILENAME=`cat $FILE| tail -n 1`
FILENAME=`sed -n '2p' $FILE`
FDATE=`sed -n '4p' $FILE`
mv $FILE $TEMPDIR/04-Download
FILE=`echo ${FILE//"03-Queue2"/"04-Download"}`
while $stat ; do
curl -C - --limit-rate $SPEED $URL --output $TEMPDIR/DownloadTemp/$FILENAME 2>$TEMPDIR/Logs/$FILENAME.txt && stat=false || sleep $CURLWAITTIME
done
touch -d "$FDATE" $TEMPDIR/DownloadTemp/$FILENAME 2>/dev/null
mv $TEMPDIR/DownloadTemp/$FILENAME $DOWNLOADDIR
mv $FILE $TEMPDIR/05-Finish
echo $FILENAME >>$TEMPDIR/Logs/Downloaded-Files.txt
echo $FILENAME >>$TEMPDIR/Logs/Last-Download.txt
}
function start_download {
#Downloads werden bei Bedarf gestartet
AKTIVEDL=`ls -1 $TEMPDIR/04-Download/*.job 2>/dev/null |wc -l `
QUEUEDL=`ls -1 $TEMPDIR/03-Queue2/*.job 2>/dev/null |wc -l `
clear
cat $TEMPDIR/Logs/Status.txt 2>/dev/null
if [ $QUEUEDL != 0 ]; then
if [ $AKTIVEDL -lt $MAXDONWLOADS ]; then
#Es wird 1 Download gestartet
start_download_file &
sleep 1
fi
fi
}
function gen_status {
STATUSFILE="$TEMPDIR/Logs/Status.txt"
AKTIVEDL=`ls -1 $TEMPDIR/04-Download/*.job 2>/dev/null |wc -l `
QUEUEDL=`ls -1 $TEMPDIR/03-Queue2/*.job 2>/dev/null |wc -l `
FREEDLDIRBYTES=`df --portability --block-size=1 $DOWNLOADDIR |tail -1 |xargs |cut -d ' ' -f 4`
FREEDLDIRHR=`df -h --portability $DOWNLOADDIR |tail -1 |xargs |cut -d ' ' -f 4`
QUEUEBYTES="0"
for QUEUEJOB in $TEMPDIR/03-Queue2/*.job
do
if [ -f $QUEUEJOB ]; then
JOBBYTES=`sed -n '3p' $QUEUEJOB |tr -d [:cntrl:]`
if [ $JOBBYTES -ge 1 ]; then
QUEUEBYTES=`echo -n $QUEUEBYTES"+"$JOBBYTES`
fi
fi
done
echo $QUEUEBYTES >$TEMPDIR/bc.tmp
QUEUEBYTES=`cat $TEMPDIR/bc.tmp |bc`
rm $TEMPDIR/bc.tmp
ADLBYTES="0"
for ADLJOB in $TEMPDIR/04-Download/*.job
do
if [ -f $ADLJOB ]; then
JOBBYTES=`sed -n '3p' $ADLJOB |tr -d [:cntrl:]`
if [ $JOBBYTES -ge 1 ]; then
ADLBYTES=`echo -n $ADLBYTES"+"$JOBBYTES`
fi
fi
done
echo $ADLBYTES >$TEMPDIR/bc.tmp
ADLBYTES=`cat $TEMPDIR/bc.tmp |bc`
rm $TEMPDIR/bc.tmp
echo $ADLBYTES"+"$QUEUEBYTES"-"`du -sb $TEMPDIR/DownloadTemp |cut -f1` >$TEMPDIR/bc.tmp
TODLBYTES=`cat $TEMPDIR/bc.tmp |bc`
rm $TEMPDIR/bc.tmp
echo $FREEDLDIRBYTES"-"$TODLBYTES >$TEMPDIR/bc.tmp
FREEAFTERDLBYTES=`cat $TEMPDIR/bc.tmp |bc`
rm $TEMPDIR/bc.tmp
echo $FREEAFTERDLBYTES"/1024/1024" >$TEMPDIR/bc.tmp
FREEAFTERDLMB=`cat $TEMPDIR/bc.tmp |bc`
rm $TEMPDIR/bc.tmp
echo $TODLBYTES"/1024/1024" >$TEMPDIR/bc.tmp
TODLMB=`cat $TEMPDIR/bc.tmp |bc`
rm $TEMPDIR/bc.tmp
echo $QUEUEBYTES"/1024/1024" >$TEMPDIR/bc.tmp
QUEUEMB=`cat $TEMPDIR/bc.tmp |bc`
rm $TEMPDIR/bc.tmp
#clear
echo $Description$Version >$STATUSFILE
echo -n "Aktive Downloads: "$AKTIVEDL >>$STATUSFILE
echo " Wartende Downloads: "$QUEUEDL >>$STATUSFILE
echo -n "Frei Speicher:" $FREEDLDIRHR >>$STATUSFILE
echo " Freier Speicher bei Downloadende: "$FREEAFTERDLMB "MiB" >>$STATUSFILE
echo -n "Zum Download: "$TODLMB "MiB" >>$STATUSFILE
echo " Warteschlange: "$QUEUEMB "MiB" >>$STATUSFILE
#echo "TODLBYTES:" $TODLBYTES Bytes >>$STATUSFILE
#echo "QUEUEBYTES:" $QUEUEBYTES Bytes >>$STATUSFILE
#echo "ADLBYTES:" $ADLBYTES Bytes >>$STATUSFILE
#echo "FREEDLDIRBYTES:" $FREEDLDIRBYTES Bytes>>$STATUSFILE
#echo "FREEAFTERDLBYTES:" $FREEAFTERDLBYTES Bytes>>$STATUSFILE
echo >>$STATUSFILE
echo "Laufende Downloads:" >>$STATUSFILE
for DLFILES in `ls -1 $TEMPDIR/DownloadTemp/* 2>/dev/null `;do
TMP=`du -h $DLFILES 2>/dev/null`
TMP=`echo ${TMP//$TEMPDIR/""}`
TMP=`echo ${TMP//DownloadTemp/""}`
TMP=`echo $TMP | tr -d '/' `
echo $TMP >>$STATUSFILE
done
echo >>$STATUSFILE
echo "Fertige Downloads:" >>$STATUSFILE
cat $TEMPDIR/Logs/Last-Download.txt >>$STATUSFILE 2>/dev/null ||echo "-" >>$STATUSFILE
}
#######
#Ab hier werden die Funktionen von oben aufgerufen
#######
#######
# Init: Hier wird die Umgebung geprüft
#######
#Mehrfach-Start überprüfen
#Lockfile setzen
#FIRSTSTART: Variable in der gespeichert wird, ob das Script schonmal gestartet wurde
#0 = script läuft noch nicht, 1 script läuft bereits
FIRSTSTART=0
if [ -f $LOCKFILE ]; then
#LOCKFILE ist vorhanden
PID=`cat $LOCKFILE`
SCRIPTNAME=`echo $0`
TMP=`ps h -p $PID |grep $SCRIPTNAME |grep $PID |wc -l `
if [ $TMP != 0 ]; then
#Prozess läuft
FIRSTSTART=1
else
#Prozess läuft nicht
FIRSTSTART=0
echo $$ >$LOCKFILE
fi
else
#LOCKFILE nicht vorhanden, Prozess läuft nicht
echo $$ >$LOCKFILE
FIRSTSTART=0
fi
######
#INIT1: Nur bei erneutem Starten der Anwendung
######
if [ $FIRSTSTART = 1 ];then
#Job 1: Weiter Jobs hinzufügen
#Links splitten und in Warteschlange schieben.
#Später müssten Duplicate entfernt werden.
add_jobs_to_queue
#Job 2: Allgemein Informationen ausgeben
echo $0 läuf bereits.
echo Die Links von $DLLINKSFILE wurden der Warteschlange hinzugefügt.
#ENDE!!! (keine Weitere Ausführung)
exit 0
fi
######
#INIT2: Nur bei erststart der Anwendung
######
if [ $FIRSTSTART = 0 ];then
#Job 1: Temp-Verzeichnisse bei bedarf anlegen
create_temp_dirs
#Job 2: Jobs von "In-Arbeit" zurück in die Warteschlange schieben
jobs_back_to_queue
#Job 3: Weiter Jobs hinzufügen
#Links splitten und in Warteschlange schmeißen
#(Später müssten Duplicate entfernt werden)
#Input-Daten bereinigen / Löschen
add_jobs_to_queue
#Löschen der Last-Download-Log.txt
rm $TEMPDIR/Logs/Last-Download.txt 2>/dev/null
#Danach wird der Loop ausgeführt
fi
########
# Main-Loop (läuft solange, wie Download arbeiten)
# Hier sind nur die Sachen, welche immer wieder ausgfeführt werden müssen
# Wird nur ausgeführt, wenn das Script noch nicht läuft
########
if [ $FIRSTSTART = 0 ];then
RUNLOOP=true
while $RUNLOOP ; do
#JOB 1: Dateiname ermitteln (Warteschlange erstellen)
get_filenames
#Job 2: Dublikat-Check
filter_duplicate
#JOB 3: Download-Jobs starten (bei bedarf)
#Generieren von Status-Anzeige wird hier auch noch erledigt
gen_status
start_download
#Job 5: Ermitteln, ob alle Aufgaben erledigt sind, und das Script beendet werden kann
ls -1 $TEMPDIR/0[1-4]*/*.job >/dev/null 2>/dev/null ||RUNLOOP=false
if [ $RUNLOOP = false ]; then
echo "Warten auf Jobs"
wait
echo "Heruntergeladen aufnahmen:"
cat $TEMPDIR/Logs/Last-Download.txt 2>/dev/null
fi
sleep $LOOPSLEEP
done
fi
exit 0
Schreibe einen Kommentar
Du musst angemeldet sein, um einen Kommentar abzugeben.