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