51646b7bafda975bf701cedff6d5b47133393cca
[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 alsa:device=hw=3.7)
91             DISPLAY=:1
92             chwp=y
93             ;;
94         -C)
95             pretend=y
96             ;;
97         -A)
98             while :; do
99                 if [ $# -lt 1 ]; then
100                     echo "planime: unterminated argument list" >&2
101                     exit 1
102                 fi
103                 a="$1"
104                 shift
105                 if [ "$a" = \; ]; then
106                     break;
107                 fi
108                 cmdline=("${cmdline[@]}" "$a")
109             done
110             ;;
111         -s)
112             savepar="$1"
113             shift
114             saveval="$1"
115             shift
116             ;;
117         -f)
118             printfile=y
119             ;;
120         --)
121             break
122             ;;
123         *)
124             echo "planime: unknown option \`$a'"
125             exit 1
126             ;;
127     esac
128 done
129
130 dirbase="$(basename "$(pwd)")"
131 base=.
132 nextep=n
133 file=
134 tqual=
135 if [ $# -eq 0 ]; then
136     nextep=y
137 elif [ $# -eq 1 ]; then
138     if [ -r "$1" ]; then
139         file="$1"
140     else
141         base=
142         ep="$1"
143     fi
144 elif [ $# -eq 2 ]; then
145     if findfile "$dirbase - " "$1" "$2" >/dev/null; then
146         base=""
147         ep="$1"
148         tqual="$2"
149     else
150         base="$1"
151         ep="$2"
152     fi
153 else
154     base="$1"
155     ep="$2"
156     tqual="$3"
157 fi
158 if [ "$ep" = . ]; then nextep=y; fi
159 if [ "$nextep" = y -a -r nextep ]; then
160     ep="$(<nextep)"
161     if ! isnum "$ep"; then
162         echo "planime: nextep is non-numeric" >&2
163         exit 1
164     fi
165 fi
166 if [ -z "$file" ]; then
167     if [ "$base" = . ]; then
168         if [ -r curser ]; then
169             curser="$(<curser)"
170         else
171             curser=
172         fi
173     else
174         curser="$(findbase "$base")"
175     fi
176     if [ -n "$curser" ]; then
177         file="$(findfile "$dirbase $curser - " "$ep" "$tqual")" || \
178             file="$(findfile "$curser - " "$ep" "$tqual")"
179     else
180         file="$(findfile "$dirbase - " "$ep" "$tqual")"
181     fi
182 fi
183
184 if [ -z "$file" -o ! -r "$file" ]; then
185     echo "planime: no matching file found" >&2
186     exit 1
187 fi
188
189 case "${file##*.}" in
190     ogm)
191         aid=1
192         sid=0
193         ;;
194     mkv)
195         alang=jpn
196         slang=eng
197         ;;
198 esac
199
200 ifile=".${file}.info"
201
202 if [ -n "$savepar" ]; then
203     if [ -r "$ifile" ]; then
204         egrep -v "^${savepar} " "$ifile" >"$ifile.new"
205         mv -f "$ifile.new" "$ifile"
206     fi
207     echo "$savepar $saveval" >>"$ifile"
208     exit 0
209 fi
210
211 unset delay
212
213 if [ -r "$ifile" ]; then
214     exec 3<&0
215     exec 0<"$ifile"
216     while read par arg; do
217         if [ "$par" = delay ]; then
218             cmdline=("${cmdline[@]}" -delay "$arg")
219         elif [ "$par" = aspect ]; then
220             cmdline=("${cmdline[@]}" -aspect "$arg")
221         elif [ "$par" = volmod ]; then
222             cmdline=("${cmdline[@]}" -af volume="$arg")
223         elif [ "$par" = alang ]; then
224             unset alang aid
225             alang="$arg"
226         elif [ "$par" = aid ]; then
227             unset alang aid
228             aid="$arg"
229         elif [ "$par" = slang ]; then
230             unset slang sid
231             slang="$arg"
232         elif [ "$par" = sid ]; then
233             unset slang sid
234             sid="$arg"
235         fi
236     done
237     exec 0<&3
238     exec 3<&-
239 fi
240
241 if [ -n "$alang" ]; then
242     cmdline=("${cmdline[@]}" -alang "$alang")
243 elif [ -n "$aid" ]; then
244     cmdline=("${cmdline[@]}" -aid "$aid")
245 fi
246 if [ -n "$slang" ]; then
247     cmdline=("${cmdline[@]}" -slang "$slang")
248 elif [ -n "$sid" ]; then
249     cmdline=("${cmdline[@]}" -sid "$sid")
250 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