planime: Use getopts for argument parsing.
[utils.git] / planime
... / ...
CommitLineData
1#!/bin/bash
2
3isnum() {
4 grep -xq '[0-9]\+' <<<"$1"
5}
6
7scorefile() {
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
17findbase() {
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
29findfile() {
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)" -o "${eqt:0:2}" = "- " ]; 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
73origargs=("$0" "$@")
74cmdline=(mpv -fs)
75debug=
76log=y
77unset pretend printfile
78
79usage() {
80 echo "usage: planime [-fdhtCL] [-A PLAYER-ARGS... ;] [-s PAR=VAL] [--] [NAME-QUAL] [EP|.] [TYPE-QUAL]"
81}
82
83while getopts hdtCLA:s:fv opt; do
84 case "$opt" in
85 h)
86 usage
87 exit 0
88 ;;
89 d)
90 debug=y
91 ;;
92 t)
93 cmdline=("${cmdline[@]}" -audio-device 'alsa/hdmi:CARD=PCH,DEV=0')
94 DISPLAY=:1
95 chwp=y
96 ;;
97 C)
98 pretend=y
99 ;;
100 L)
101 log=
102 ;;
103 A)
104 while [ "$OPTARG" != \; ]; do
105 cmdline+=("$OPTARG")
106 if [ "$OPTIND" -gt $# ]; then
107 echo "planime: unterminated argument list" >&2
108 exit 1
109 fi
110 OPTARG="${!OPTIND}"
111 let OPTIND++
112 done
113 ;;
114 s)
115 p="$(expr index "$OPTARG" =)"
116 if [ "$p" -le 0 ]; then
117 usage >&2
118 exit 1
119 fi
120 savepar="${OPTARG:0:p}"
121 let p++
122 saveval="${OPTARG:p}"
123 ;;
124 f)
125 printfile=y
126 ;;
127 v)
128 cmdline+=(-v)
129 ;;
130 *)
131 usage >&2
132 exit 1
133 ;;
134 esac
135done
136shift $((OPTIND - 1))
137
138dirbase="$(basename "$(pwd)")"
139base=.
140nextep=n
141file=
142tqual=
143if [ $# -eq 0 ]; then
144 nextep=y
145elif [ $# -eq 1 ]; then
146 if [ -r "$1" ]; then
147 file="$1"
148 else
149 base=
150 ep="$1"
151 fi
152elif [ $# -eq 2 ]; then
153 if findfile "$dirbase - " "$1" "$2" >/dev/null; then
154 base=""
155 ep="$1"
156 tqual="$2"
157 else
158 base="$1"
159 ep="$2"
160 fi
161else
162 base="$1"
163 ep="$2"
164 tqual="$3"
165fi
166if [ "$ep" = . ]; then nextep=y; fi
167if [ "$nextep" = y -a -r nextep ]; then
168 ep="$(<nextep)"
169 if ! isnum "$ep"; then
170 echo "planime: nextep is non-numeric" >&2
171 exit 1
172 fi
173fi
174if [ -z "$file" ]; then
175 if [ "$base" = . ]; then
176 if [ -r curser ]; then
177 curser="$(<curser)"
178 else
179 curser=
180 fi
181 else
182 curser="$(findbase "$base")"
183 fi
184 if [ -n "$curser" ]; then
185 file="$(findfile "$dirbase $curser - " "$ep" "$tqual")" || \
186 file="$(findfile "$curser - " "$ep" "$tqual")"
187 else
188 file="$(findfile "$dirbase - " "$ep" "$tqual")"
189 fi
190fi
191
192if [ -z "$file" -o ! -r "$file" ]; then
193 echo "planime: no matching file found" >&2
194 exit 1
195fi
196
197case "${file##*.}" in
198 ogm)
199 aid=1
200 sid=0
201 ;;
202 mkv)
203 alang=jpn
204 slang=eng
205 ;;
206esac
207
208ifile=".${file}.info"
209
210if [ -n "$savepar" ]; then
211 if [ -r "$ifile" ]; then
212 egrep -v "^${savepar} " "$ifile" >"$ifile.new"
213 mv -f "$ifile.new" "$ifile"
214 fi
215 echo "$savepar $saveval" >>"$ifile"
216 exit 0
217fi
218
219unset delay
220
221if [ -r "$ifile" ]; then
222 exec 3<&0
223 exec 0<"$ifile"
224 while read par arg; do
225 if [ "$par" = delay ]; then
226 cmdline=("${cmdline[@]}" -delay "$arg")
227 elif [ "$par" = aspect ]; then
228 cmdline=("${cmdline[@]}" -aspect "$arg")
229 elif [ "$par" = volmod ]; then
230 cmdline=("${cmdline[@]}" -af volume="$arg")
231 elif [ "$par" = alang ]; then
232 unset alang aid
233 alang="$arg"
234 elif [ "$par" = aid ]; then
235 unset alang aid
236 aid="$arg"
237 elif [ "$par" = slang ]; then
238 unset slang sid
239 slang="$arg"
240 elif [ "$par" = sid ]; then
241 unset slang sid
242 sid="$arg"
243 fi
244 done
245 exec 0<&3
246 exec 3<&-
247fi
248
249if [ -n "$alang" ]; then
250 cmdline=("${cmdline[@]}" -alang "$alang")
251elif [ -n "$aid" ]; then
252 cmdline=("${cmdline[@]}" -aid "$((aid + 1))")
253fi
254if [ -n "$slang" ]; then
255 cmdline=("${cmdline[@]}" -slang "$slang")
256elif [ -n "$sid" ]; then
257 cmdline=("${cmdline[@]}" -sid "$((sid + 1))")
258fi
259
260if [ -n "$pretend" ]; then
261 echo "${cmdline[@]}" "$file"
262elif [ -n "$printfile" ]; then
263 echo "$file"
264else
265 if [ "$chwp" = y ]; then (sleep 2; randomwp) & fi
266 if [ "$log" = y ]; then
267 if [ -d $HOME/.anime ]; then
268 echo "$(date) $(basename "$file")" >>$HOME/.anime/plog
269 fi
270 fi
271 "${cmdline[@]}" "$file"
272
273 if [ "$nextep" = y ]; then
274 echo "0. Save and continue (or Space)"
275 echo "1. Continue without saving"
276 echo "2. Save and exit (or Enter)"
277 echo "3. Exit without saving (or any key)"
278 IFS= read -sn1 c
279 save=n
280 cont=n
281 case "$c" in
282 0|" ")
283 save=y
284 cont=y
285 ;;
286 1)
287 cont=y
288 ;;
289 2|"")
290 save=y
291 ;;
292 esac
293 if [ "$save" = y ]; then
294 let ep++
295 echo "$ep" >nextep
296 fi
297 if [ "$cont" = y ]; then
298 exec "${origargs[@]}"
299 else
300 echo "nextep is $ep"
301 fi
302 fi
303fi