Fetch exit status and check for double eps.
[utils.git] / autodlctl
1 #!/bin/bash
2
3 paths=(/home/pub/video/anime $HOME/dc/autodl/cur)
4
5 function getnext
6 {
7     echo "checking $tag"
8     sexpr="`cat "$d/.autodl/sexpr"`"
9     unset badsizes
10     if [ -r "$d/.autodl/badlist" ]; then
11         read curep <"$d/.autodl/badlist"
12         echo "downloading bad files, curep $curep"
13         epfrom=badlist
14     elif [ -r "$d/.autodl/curep" ]; then
15         curep="`cat "$d/.autodl/curep"`"
16         echo "downloading series, curep $curep"
17         epfrom=curep
18     else
19         echo "no available episode of $tag" >&2
20         echo "$tag" >>"$HOME/dc/autodl/faulty"
21         return 1
22     fi
23     unset badsizesl
24     if [ -r "$d/.autodl/badsizes" ]; then
25         badsizesl="$(sed -n "s/^0*$curep \([^#]*\)\( *#.*\)\?$/\1/p" "$d/.autodl/badsizes")"
26     fi
27     if [ -n "$badsizesl" ]; then
28         read -a badsizes <<<"$badsizesl"
29         unset badsizesl
30         echo "found bad size list: ${badsizes[@]}"
31     fi
32     unset args
33     fsexpr="`printf "$sexpr" "$curep"`"
34     if [ "${#badsizes[@]}" -gt 0 ]; then
35         for badsize in "${badsizes[@]}"; do
36             fsexpr="$fsexpr & ! S=$badsize"
37         done
38     fi
39     infofile="$d/.autodl/rtinfo"
40     estatfile="$d/.autodl/estat"
41     args=(-e "$fsexpr" -t "$tag $curep" -I "$infofile" -E "$estat" -x "curep=$curep")
42     if [ -e "$d/.autodl/wait" ]; then
43         args=("${args[@]}" -w)
44     fi
45     if [ -r "$d/.autodl/uarg" ]; then
46         uarg="`cat "$d/.autodl/uarg"`"
47     elif [ -e "$d/.autodl/autouarg" ]; then
48         uarg="rename:$tag - %02i.avi:move:../autodl/cur/$tag"
49     fi
50     if [ -n "$uarg" ]; then
51         fuarg="`printf "$uarg" "$curep"`"
52         args=("${args[@]}" -a "$fuarg")
53     fi
54     outfile="$d/.autodl/output"
55     echo "trying to download -- autodl ${args[@]}"
56     intr=n
57     autodl "${args[@]}" >"$outfile" 2>&1 &
58     pid=$!
59     trap "intr=y; kill -INT $pid" USR1 INT
60     wait $pid
61     stat=$?
62     if [ -r "$estatfile" ]; then
63         estat="`cat "$estatfile"`"
64         rm -f "$estatfile"
65     fi
66     if [ "$intr" = y ]; then
67         echo "$tag interrupted"
68     else
69         if [ "$stat" -ne 0 ]; then
70             if [ "$stat" -eq 1 ]; then
71                 echo "Failure for $tag" >>"$HOME/dc/autodl/errorlog"
72                 tail -n 20 "$outfile" >>"$HOME/dc/autodl/errorlog"
73             elif [ "$stat" -eq 2 ]; then
74                 echo "Connection error on $tag"
75             elif [ "$stat" -eq 3 ]; then
76                 echo "Configuration error, disabling $tag"
77                 cp "$outfile" "$d/.autodl/conferr"
78                 touch "$d/.autodl/disabled"
79                 echo "$tag" >>"$HOME/dc/autodl/faulty"
80             fi
81         else
82             echo "episode $curep of $tag done (estat: \"$estat\")"
83             case "$epfrom" in
84                 badlist)
85                     echo -en "${tag}\n${curep}\n" >>"$HOME/dc/autodl/baddone"
86                     egrep -v "^$curep( |\$)" "$d/.autodl/badlist" >"$d/.autodl/newbadlist"
87                     mv -f "$d/.autodl/newbadlist" "$d/.autodl/badlist"
88                     if [ `wc -l <"$d/.autodl/badlist"` -eq 0 ]; then
89                         rm "$d/.autodl/badlist"
90                         if [ -r "$d/.autodl/curep" ]; then
91                             if [ -r "$d/.autodl/maxep" ] && [ "`cat "$d/.autodl/curep"`" -gt "`cat "$d/.autodl/maxep"`" ]; then
92                                 touch "$d/.autodl/disabled"
93                             fi
94                         else
95                             touch "$d/.autodl/disabled"
96                         fi
97                         echo "$tag has no more bad episodes"
98                         echo "$tag" >>"$HOME/dc/autodl/badmaxed"
99                     fi
100                     ;;
101                 curep)
102                     if [ "$estat" = dbl ]; then
103                         echo -en "${tag}\n${curep}\n" >>"$HOME/dc/autodl/done"
104                         echo -en "${tag}\n$((${curep} + 1))\n" >>"$HOME/dc/autodl/done"
105                         let curep+=2
106                     else
107                         echo -en "${tag}\n${curep}\n" >>"$HOME/dc/autodl/done"
108                         let curep++
109                     fi
110                     echo "$curep" >"$d/.autodl/curep"
111                     if [ -r "$d/.autodl/maxep" ]; then
112                         if [ "$curep" -gt "`cat "$d/.autodl/maxep"`" ]; then
113                             touch "$d/.autodl/disabled"
114                             echo "$tag has reached max"
115                             echo "$tag" >>"$HOME/dc/autodl/maxed"
116                         fi
117                     fi
118                     ;;
119             esac
120         fi
121     fi
122     rm -f "$outfile"
123     rm -f "$HOME/dc/autodl/run/$tag"
124 }
125
126 for dir in $HOME/dc/autodl{,/cur,/run}; do
127     if [ -e "$dir" ]; then
128         if [ ! -d "$dir" ]; then
129             echo "$dir is not a directory, please remedy and restart" >&2
130             exit 1
131         fi
132     else
133         mkdir "$dir" || exit 1
134     fi
135 done
136
137 while [ $# -gt 0 ]; do
138     arg="$1"
139     shift
140     case "$arg" in
141         -k)
142             pid="$(cat "$HOME/dc/autodl/run/master")"
143             if [ -z "$pid" ]; then
144                 echo "autodlctl: could not read a PID from $HOME/dc/autodl/run/master" >&2
145                 exit 1
146             fi
147             kill "$pid"
148             exit 0
149             ;;
150         *)
151             echo "autodlctl: unrecognized option: \"$arg\"" >&2
152             exit 1
153             ;;
154     esac
155 done
156
157 lastget=0
158 done=n
159 trap "done=y" INT QUIT TERM
160 echo $$ >"$HOME/dc/autodl/run/master"
161 while [ "$done" != y ]; do
162     for pidfile in $HOME/dc/autodl/run/*; do
163         if [ "$pidfile" = "$HOME/dc/autodl/run/*" ]; then break; fi
164         pid="`cat "$pidfile"`"
165         if [ -d /proc/1 -a ! -d "/proc/$pid" ]; then
166             echo "removing stale pidfile $pidfile"
167             rm -f "$pidfile"
168         fi
169     done
170     for p in "${paths[@]}"; do
171         for d in "$p"/*; do
172             if [ -d "$d/.autodl" -a ! -e "$d/.autodl/disabled" ]; then
173                 if [ -r "$d/.autodl/tag" ]; then
174                     tag="`cat "$d/.autodl/tag"`"
175                 else
176                     tag="`basename "$d"`"
177                 fi
178                 start=y
179                 if [ -e "$d/.autodl/disable" ]; then
180                     echo "disabling $tag per user request"
181                     start=n
182                     touch "$d/.autodl/disabled"
183                     rm -f "$d/.autodl/disable"
184                     if [ -r "$HOME/dc/autodl/run/$tag" ]; then
185                         pid="`cat "$HOME/dc/autodl/run/$tag"`"
186                         echo "sending SIGUSR1 to $pid"
187                         kill -USR1 "$pid"
188                     else
189                         echo "could not find pid for $tag"
190                     fi
191                 fi
192                 if [ -e "$d/.autodl/restart" ]; then
193                     echo "restarting $tag per user request"
194                     rm -f "$d/.autodl/restart"
195                     if [ -r "$HOME/dc/autodl/run/$tag" ]; then
196                         pid="`cat "$HOME/dc/autodl/run/$tag"`"
197                         echo "sending SIGUSR1 to $pid"
198                         kill -USR1 "$pid"
199                         while [ -e "$HOME/dc/autodl/run/$tag" ]; do
200                             echo "waiting for it to exit"
201                             sleep 1
202                         done
203                     else
204                         echo "could not find pid for $tag"
205                     fi
206                 fi
207                 if [ $start = y ]; then
208                     if [ ! -r "$d/.autodl/sexpr" ]; then
209                         touch "$d/.autodl/disabled"
210                         echo "$tag lacks sexpr" >&2
211                         echo "$tag" >>"$HOME/dc/autodl/faulty"
212                     else
213                         if [ ! -e "$HOME/dc/autodl/run/$tag" ]; then
214                             if [ $((`date +%s` - $lastget)) -gt 20 ]; then
215                                 getnext "$d" "$tag" &
216                                 lastget=`date +%s`
217                                 pid=$!
218                                 echo "$pid" >"$HOME/dc/autodl/run/$tag"
219                             fi
220                         fi
221                     fi
222                 fi
223             fi
224         done
225     done
226     sleep 10
227 done
228
229 for pidfile in $HOME/dc/autodl/run/*; do
230     if [ "$pidfile" = "$HOME/dc/autodl/run/*" ]; then break; fi
231     if [ "$(basename "$pidfile")" = master ]; then continue; fi
232     pid="`cat "$pidfile"`"
233     echo "sending SIGUSR1 to $pid for `basename "$pidfile"`"
234     kill -USR1 "$pid"
235 done
236
237 rm -f "$HOME/dc/autodl/run/master"