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