*.deb extraction utility (also *.dsc by wrapping “dpkg-source -x”)
[shellsnippets/shellsnippets.git] / mksh / mpcabber
1 #!/usr/bin/env mksh
2 # $MirOS: contrib/code/Snippets/mpcabber,v 1.16 2009/12/01 19:28:45 tg Exp $
3 #-
4 # Copyright (c) 2008, 2009
5 #       Thorsten Glaser <tg@mirbsd.org>
6 #
7 # Provided that these terms and disclaimer and all copyright notices
8 # are retained or reproduced in an accompanying document, permission
9 # is granted to deal in this work without restriction, including un-
10 # limited rights to use, publicly perform, distribute, sell, modify,
11 # merge, give away, or sublicence.
12 #
13 # This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
14 # the utmost extent permitted by applicable law, neither express nor
15 # implied; without malicious intent or gross negligence. In no event
16 # may a licensor, author or contributor be held liable for indirect,
17 # direct, other damage, loss, or other issues arising in any way out
18 # of dealing in the work, even if advised of the possibility of such
19 # damage or existence of a defect, except proven that it results out
20 # of said person’s immediate fault when using the work as intended.
21 #-
22 # mpg123-0.59r-MirPorts-6 to mcabber-0.9.7 FIFO gateway
23 # mplayer and mppdec-static SV7 1.95e also work
24 # Requires mksh R34 or above
25 #
26 # User Tunes strings are courtesy of Jonathan Schleifer (my personal
27 # XEP to German gateway ☺)
28
29 # Configuration
30 integer usestate=1      # use Away Status
31 integer usetunes=1      # use User Tunes (XEP #0118)
32
33
34 x=0
35 if [[ $KSH_VERSION = @(\@\(#\)MIRBSD KSH R)+([0-9])\ +([0-9])/+([0-9])/+([0-9])?(\ *) ]]; then
36         set -A x -- ${KSH_VERSION#* R}
37         (( x[0] < 39 )) && x=0
38         (( x[0] == 39 )) && [[ ${x[1]} < "2009/12/01" ]] && x=0
39 fi
40 (( x )) || { echo mksh too old; exit 1; }
41
42 set -U
43 set -A vistable -- [0xEF7F]=-1 \
44     0x20AC 0x278A 0x201A 0x0192 0x201E 0x2026 0x2020 0x2021 \
45     0x02C6 0x2030 0x0160 0x2039 0x0152 0x278B 0x017D 0x278C \
46     0x278D 0x2018 0x2019 0x201C 0x201D 0x2022 0x2013 0x2014 \
47     0x02DC 0x2122 0x0161 0x203A 0x0153 0x278E 0x017E 0x0178 \
48     0x00A0 0x00A1 0x00A2 0x00A3 0x00A4 0x00A5 0x00A6 0x00A7 \
49     0x00A8 0x00A9 0x00AA 0x00AB 0x00AC 0x00AD 0x00AE 0x00AF \
50     0x00B0 0x00B1 0x00B2 0x00B3 0x00B4 0x00B5 0x00B6 0x00B7 \
51     0x00B8 0x00B9 0x00BA 0x00BB 0x00BC 0x00BD 0x00BE 0x00BF \
52     0x00C0 0x00C1 0x00C2 0x00C3 0x00C4 0x00C5 0x00C6 0x00C7 \
53     0x00C8 0x00C9 0x00CA 0x00CB 0x00CC 0x00CD 0x00CE 0x00CF \
54     0x00D0 0x00D1 0x00D2 0x00D3 0x00D4 0x00D5 0x00D6 0x00D7 \
55     0x00D8 0x00D9 0x00DA 0x00DB 0x00DC 0x00DD 0x00DE 0x00DF \
56     0x00E0 0x00E1 0x00E2 0x00E3 0x00E4 0x00E5 0x00E6 0x00E7 \
57     0x00E8 0x00E9 0x00EA 0x00EB 0x00EC 0x00ED 0x00EE 0x00EF \
58     0x00F0 0x00F1 0x00F2 0x00F3 0x00F4 0x00F5 0x00F6 0x00F7 \
59     0x00F8 0x00F9 0x00FA 0x00FB 0x00FC 0x00FD 0x00FE 0x00FF
60 typeset -i1 vistable
61 function toutf8 {
62         local intext="$*" outtext=''
63         typeset -i i=0 n=${#intext}
64         typeset -i1 c
65         typeset -Uui16 -Z5 x
66
67         while (( i < n )); do
68                 c=1#${intext:(i++):1}
69                 if (( (c & 0xFF80) == 0xEF80 )); then
70                         outtext=${outtext}${vistable[c]#1#}
71                 elif (( c < 32 || c == 1#% )); then
72                         let x=c
73                         outtext=${outtext}%${x#16#}
74                 elif (( c > 0x7E && c < 0xA0 )); then
75                         outtext=${outtext}�
76                 else
77                         outtext=${outtext}${c#1#}
78                 fi
79         done
80
81         print -nr -- "$outtext"
82 }
83
84 function settitle {
85         typeset title=$(toutf8 "$*")
86
87         # Debugging
88         #print -ru2 -- "setting title: $title"
89
90         if [[ -n $title ]]; then
91                 titlemsg="♫ $title"
92                 titlexml="<title>$(sed \
93                     -e "s/&/\&#38;/g" \
94                     -e "s/</\&#60;/g" \
95                     -e "s/>/\&#62;/g" \
96                     -e "s/'/\&#39;/g" \
97                     <<<"$title")</title>"
98         else
99                 titlemsg=∅
100                 titlexml=
101         fi
102
103         # Is mcabber running and listening on the FIFO?
104         [[ -p ~/.etc/mcabber/mcabber.fifo ]] || return
105
106         # Away Status
107         (( usestate )) && print -r -- "/status message $titlemsg" \
108             >~/.etc/mcabber/mcabber.fifo
109
110         # Give the mcabber FIFO some rest, will ya?
111         if (( usestate && usetunes )); then
112                 sleep 1
113                 # Is mcabber _still_ running and listening on the FIFO?
114                 [[ -p ~/.etc/mcabber/mcabber.fifo ]] || return
115         fi
116
117         # User Tunes
118         (( usetunes )) && print -r -- '/rawxml send <iq type="set"><pubsub' \
119             'xmlns="http://jabber.org/protocol/pubsub"><publish' \
120             'node="http://jabber.org/protocol/tune"><item id="0"><tune' \
121             'xmlns="http://jabber.org/protocol/tune">'"${titlexml}</tune></item></publish></pubsub></iq>" \
122             >~/.etc/mcabber/mcabber.fifo
123 }
124
125
126 integer rv gotintr=0
127 curdir=
128
129 trap 'gotintr=1' INT
130
131 exec 3>&1
132 exec 0>&3
133 if [[ $1 = - ]]; then
134         shift
135         "$@" <&3 |&
136 else
137         "$@" <&3 2>&1 |&
138 fi
139 subpid=$!
140
141 while :; do
142         IFS= read -pr line
143         rv=$?
144         if (( gotintr )); then
145                 gotintr=0
146                 kill -INT $subpid
147                 continue
148         fi
149         (( rv )) && break
150         print -r -- "$line"
151         case $line {
152         (@(ICY metadata:)*)
153                 curdir=
154                 title=${line/*StreamTitle=\'}
155                 title=${title/@(\';StreamUrl=)*}
156                 title=${title%%?(\');}
157                 ;;
158         (@(Directory: http://)*)
159                 curdir=${line#Directory: }
160                 continue
161                 ;;
162         (@(Playing MPEG stream from )*)
163                 title=$(sed -e 's/^Playing MPEG stream from \(.*\) ...$/\1/' \
164                     <<<"$line")
165                 [[ $title = $line ]] && continue        # sanity
166                 [[ -n $curdir ]] && title=$curdir$title
167                 curdir=
168                 ;;
169         (@(decoding of file )*)
170                 title=${line##decoding of file ?(\')}
171                 title=${title%\'}
172                 curdir=
173                 ;;
174         (@(Playing )*.)
175                 title=${line#Playing }
176                 title=${title%.}
177                 curdir=
178                 ;;
179         (*)
180                 continue
181                 ;;
182         }
183         title=${title##+([       ])}
184         title=${title##[Nn]?(ow )[Pp]?(laying):}
185         title=${title##+([       ])}
186         title=${title%%+([       ])}
187         [[ $title = *://* ]] || title=${title%%.@([Mm][Pp][234CcPp]|[Mm]4[Aa]|[Aa][Vv][Ii]|[Mm][Kk][Vv]|[Ff][Ll][Aa][Cc]|[Ff][Ll][Vv]|[Oo][Gg][Gg]|[Ww][Aa][Vv])}
188         title=${title%%+([       ])}
189         [[ -n $title ]] || continue
190         settitle "$title" &
191 done
192
193 settitle # empty
194 exit 0