Find next ep more flexibly.
[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 ! findcurep; then
131                 echo "no more episodes to download from $tag"
132                 touch disabled
133             fi
134         fi
135     fi
136     rm -f "$outfile"
137     rm -f "$HOME/dc/autodl/run/$tag"
138 }
139
140 for dir in $HOME/dc/autodl{,/cur,/run}; do
141     if [ -e "$dir" ]; then
142         if [ ! -d "$dir" ]; then
143             echo "$dir is not a directory, please remedy and restart" >&2
144             exit 1
145         fi
146     else
147         mkdir "$dir" || exit 1
148     fi
149 done
150
151 while [ $# -gt 0 ]; do
152     arg="$1"
153     shift
154     case "$arg" in
155         -k)
156             pid="$(cat "$HOME/dc/autodl/run/master")"
157             if [ -z "$pid" ]; then
158                 echo "autodlctl: could not read a PID from $HOME/dc/autodl/run/master" >&2
159                 exit 1
160             fi
161             kill "$pid"
162             exit 0
163             ;;
164         *)
165             echo "autodlctl: unrecognized option: \"$arg\"" >&2
166             exit 1
167             ;;
168     esac
169 done
170
171 lastget=0
172 done=n
173 trap "done=y" INT QUIT TERM
174 echo $$ >"$HOME/dc/autodl/run/master"
175 while [ "$done" != y ]; do
176     for pidfile in $HOME/dc/autodl/run/*; do
177         if [ "$pidfile" = "$HOME/dc/autodl/run/*" ]; then break; fi
178         pid="`cat "$pidfile"`"
179         if [ -d /proc/1 -a ! -d "/proc/$pid" ]; then
180             echo "removing stale pidfile $pidfile"
181             rm -f "$pidfile"
182         fi
183     done
184     for p in "${paths[@]}"; do
185         for d in "$p"/*; do
186             if [ -d "$d/.autodl" -a ! -e "$d/.autodl/disabled" ]; then
187                 if [ -r "$d/.autodl/tag" ]; then
188                     tag="`cat "$d/.autodl/tag"`"
189                 else
190                     tag="`basename "$d"`"
191                 fi
192                 start=y
193                 if [ -e "$d/.autodl/disable" ]; then
194                     echo "disabling $tag per user request"
195                     start=n
196                     touch "$d/.autodl/disabled"
197                     rm -f "$d/.autodl/disable"
198                     if [ -r "$HOME/dc/autodl/run/$tag" ]; then
199                         pid="`cat "$HOME/dc/autodl/run/$tag"`"
200                         echo "sending SIGUSR1 to $pid"
201                         kill -USR1 "$pid"
202                     else
203                         echo "could not find pid for $tag"
204                     fi
205                 fi
206                 if [ -e "$d/.autodl/restart" ]; then
207                     echo "restarting $tag per user request"
208                     rm -f "$d/.autodl/restart"
209                     if [ -r "$HOME/dc/autodl/run/$tag" ]; then
210                         pid="`cat "$HOME/dc/autodl/run/$tag"`"
211                         echo "sending SIGUSR1 to $pid"
212                         kill -USR1 "$pid"
213                         while [ -e "$HOME/dc/autodl/run/$tag" ]; do
214                             echo "waiting for it to exit"
215                             sleep 1
216                         done
217                     else
218                         echo "could not find pid for $tag"
219                     fi
220                 fi
221                 if [ $start = y ]; then
222                     if [ ! -r "$d/.autodl/sexpr" ]; then
223                         touch "$d/.autodl/disabled"
224                         echo "$tag lacks sexpr" >&2
225                         echo "$tag" >>"$HOME/dc/autodl/faulty"
226                     else
227                         if [ ! -e "$HOME/dc/autodl/run/$tag" ]; then
228                             if [ $((`date +%s` - $lastget)) -gt 20 ]; then
229                                 getnext "$d" "$tag" &
230                                 lastget=`date +%s`
231                                 pid=$!
232                                 echo "$pid" >"$HOME/dc/autodl/run/$tag"
233                             fi
234                         fi
235                     fi
236                 fi
237             fi
238         done
239     done
240     sleep 10
241 done
242
243 for pidfile in $HOME/dc/autodl/run/*; do
244     if [ "$pidfile" = "$HOME/dc/autodl/run/*" ]; then break; fi
245     if [ "$(basename "$pidfile")" = master ]; then continue; fi
246     pid="`cat "$pidfile"`"
247     echo "sending SIGUSR1 to $pid for `basename "$pidfile"`"
248     kill -USR1 "$pid"
249 done
250
251 rm -f "$HOME/dc/autodl/run/master"