planime: Avoid infinite loop in -A.
[utils.git] / planime
1 #!/bin/bash
2
3 isnum() {
4     grep -xq '[0-9]\+' <<<"$1"
5 }
6
7 scorefile() {
8     if [ "${1##*.}" = mkv ]; then
9         echo 10
10     elif [ "${1##*.}" = ogm ]; then
11         echo 5
12     else
13         echo 0
14     fi
15 }
16
17 findbase() {
18     if [ -r aliases ]; then
19         while read alias rest; do
20             if [ "$alias" = "$1" ]; then
21                 echo "$rest"
22                 return
23             fi
24         done <aliases
25     fi
26     echo "$1"
27 }
28
29 findfile() {
30     if [ -n "$debug" ]; then echo "finding base='$1', ep='$2', qual='$3'" >&2; fi
31     local base file tail eq eqt m matches max score
32     matches=()
33     base="$(findbase "$1")"
34     for file in "$base"*; do
35         tail="${file#"$base"}"
36         eq="${tail%.*}"
37         m=n
38         if [ "${eq%% *}" -eq "$2" ] 2>/dev/null; then
39             if [[ "$eq" == *\ * ]]; then
40                 eqt="${eq#* }"
41             else
42                 eqt=
43             fi
44             m=y
45         elif [ "${eq:0:${#2}}" = "$2" ]; then
46             eqt="${eq:${#2}}"
47             if [ "${eqt:0:1}" = " " -o -z "$eqt" ]; then
48                 eqt="${eqt# }"
49                 m=y
50             fi
51         fi
52         if [ "$m" = y ]; then
53             if [ "$eqt" = "$3" -o "$eqt" = "($3)" ]; then
54                 matches=("${matches[@]}" "$file")
55             fi
56         fi
57     done
58     if [ ${#matches[@]} -lt 1 ]; then return 1; fi
59     max=
60     for m in "${matches[@]}"; do
61         score="$(scorefile "$m")"
62         if [ -n "$debug" ]; then echo "found \`$m': score $score" >&2; fi
63         if [ -z "$max" ] || [ "$score" -gt "$max" ]; then
64             max="$score"
65             file="$m"
66         fi
67     done
68     if [ -n "$debug" ]; then echo "using \`$file'" >&2; fi
69     echo "$file"
70     return 0
71 }
72
73 origargs=("$0" "$@")
74 cmdline=(mplayer -fs -ass)
75 debug=
76 unset pretend printfile
77
78 while [ "${1:0:1}" = - ]; do
79     a="$1"
80     shift
81     case "$a" in
82         -h)
83             echo "usage: planime [-fdhtC] [-A PLAYER-ARGS... ;] [-s PAR VAL] [--] [NAME-QUAL] [EP|.] [TYPE-QUAL]" >&2
84             exit 0
85             ;;
86         -d)
87             debug=y
88             ;;
89         -t)
90             cmdline=("${cmdline[@]}" -ao oss:/dev/dsp1)
91             ;;
92         -C)
93             pretend=y
94             ;;
95         -A)
96             while :; do
97                 if [ $# -lt 1 ]; then
98                     echo "planime: unterminated argument list" >&2
99                     exit 1
100                 fi
101                 a="$1"
102                 shift
103                 if [ "$a" = \; ]; then
104                     break;
105                 fi
106                 cmdline=("${cmdline[@]}" "$a")
107             done
108             ;;
109         -s)
110             savepar="$1"
111             shift
112             saveval="$1"
113             shift
114             ;;
115         -f)
116             printfile=y
117             ;;
118         --)
119             break
120             ;;
121         *)
122             echo "planime: unknown option \`$a'"
123             exit 1
124             ;;
125     esac
126 done
127
128 dirbase="$(basename "$(pwd)")"
129 base=.
130 nextep=n
131 file=
132 tqual=
133 if [ $# -eq 0 ]; then
134     nextep=y
135 elif [ $# -eq 1 ]; then
136     if [ -r "$1" ]; then
137         file="$1"
138     else
139         base=
140         ep="$1"
141     fi
142 elif [ $# -eq 2 ]; then
143     if findfile "$dirbase - " "$1" "$2" >/dev/null; then
144         base=""
145         ep="$1"
146         tqual="$2"
147     else
148         base="$1"
149         ep="$2"
150     fi
151 else
152     base="$1"
153     ep="$2"
154     tqual="$3"
155 fi
156 if [ "$ep" = . ]; then nextep=y; fi
157 if [ "$nextep" = y -a -r nextep ]; then
158     ep="$(<nextep)"
159     if ! isnum "$ep"; then
160         echo "planime: nextep is non-numeric" >&2
161         exit 1
162     fi
163 fi
164 if [ -z "$file" ]; then
165     if [ "$base" = . ]; then
166         if [ -r curser ]; then
167             curser="$(<curser)"
168         else
169             curser=
170         fi
171     else
172         curser="$(findbase "$base")"
173     fi
174     if [ -n "$curser" ]; then
175         file="$(findfile "$dirbase $curser - " "$ep" "$tqual")" || \
176             file="$(findfile "$curser - " "$ep" "$tqual")"
177     else
178         file="$(findfile "$dirbase - " "$ep" "$tqual")"
179     fi
180 fi
181
182 if [ -z "$file" -o ! -r "$file" ]; then
183     echo "planime: no matching file found" >&2
184     exit 1
185 fi
186
187 case "${file##*.}" in
188     ogm)
189         aid=1
190         sid=0
191         ;;
192     mkv)
193         alang=jpn
194         slang=eng
195         ;;
196 esac
197
198 ifile=".${file}.info"
199
200 if [ -n "$savepar" ]; then
201     if [ -r "$ifile" ]; then
202         egrep -v "^${savepar} " "$ifile" >"$ifile.new"
203         mv -f "$ifile.new" "$ifile"
204     fi
205     echo "$savepar $saveval" >>"$ifile"
206     exit 0
207 fi
208
209 unset delay
210
211 if [ -r "$ifile" ]; then
212     exec 3<&0
213     exec 0<"$ifile"
214     while read par arg; do
215         if [ "$par" = delay ]; then
216             cmdline=("${cmdline[@]}" -delay "$arg")
217         elif [ "$par" = aspect ]; then
218             cmdline=("${cmdline[@]}" -aspect "$arg")
219         elif [ "$par" = volmod ]; then
220             cmdline=("${cmdline[@]}" -af volume="$arg")
221         elif [ "$par" = alang ]; then
222             unset alang aid
223             alang="$arg"
224         elif [ "$par" = aid ]; then
225             unset alang aid
226             aid="$arg"
227         elif [ "$par" = slang ]; then
228             unset slang sid
229             slang="$arg"
230         elif [ "$par" = sid ]; then
231             unset slang sid
232             sid="$arg"
233         fi
234     done
235     exec 0<&3
236     exec 3<&-
237 fi
238
239 if [ -n "$alang" ]; then
240     cmdline=("${cmdline[@]}" -alang "$alang")
241 elif [ -n "$aid" ]; then
242     cmdline=("${cmdline[@]}" -aid "$aid")
243 fi
244 if [ -n "$slang" ]; then
245     cmdline=("${cmdline[@]}" -slang "$slang")
246 elif [ -n "$sid" ]; then
247     cmdline=("${cmdline[@]}" -sid "$sid")
248 fi
249
250 if [ "`hostname`" = pc6 -o "`hostname`" = pc7 -a "$DISPLAY" = :1 ]; then chwp=y; fi
251
252 if [ -n "$pretend" ]; then
253     echo "${cmdline[@]}" "$file"
254 elif [ -n "$printfile" ]; then
255     echo "$file"
256 else
257     if [ "$chwp" = y ]; then (sleep 2; randomwp) & fi
258     "${cmdline[@]}" "$file"
259     
260     if [ "$nextep" = y ]; then
261         echo "0. Save and continue (or Space)"
262         echo "1. Continue without saving"
263         echo "2. Save and exit (or Enter)"
264         echo "3. Exit without saving (or any key)"
265         IFS= read -sn1 c
266         save=n
267         cont=n
268         case "$c" in
269             0|" ")
270                 save=y
271                 cont=y
272                 ;;
273             1)
274                 cont=y
275                 ;;
276             2|"")
277                 save=y
278                 ;;
279         esac
280         if [ "$save" = y ]; then
281             let ep++
282             echo "$ep" >nextep
283         fi
284         if [ "$cont" = y ]; then
285             exec "${origargs[@]}"
286         else
287             echo "nextep is $ep"
288         fi
289     fi
290 fi