wok view sane-backends/stuff/tazpanel/sane.cgi @ rev 18239

Update tags for backup
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Jul 26 17:30:32 2015 +0200 (2015-07-26)
parents 140c18f428f0
children 1ed620c5ee23
line source
1 #!/bin/sh
2 #
3 # Scanner CGI interface - Scan documents via a browser
4 #
5 # (C) 2015 SliTaz GNU/Linux - BSD License
6 #
8 # Common functions from libtazpanel
9 . lib/libtazpanel
10 get_config
12 #------
13 # menu
14 #------
16 case "$1" in
17 menu)
18 TEXTDOMAIN_original=$TEXTDOMAIN
19 export TEXTDOMAIN='sane'
21 cat <<EOT
22 <li><a data-icon="text" href="sane.cgi"$(groups | grep -q scanner ||
23 echo ' data-root')>$(_ 'Scanner')</a></li>
24 EOT
25 export TEXTDOMAIN=$TEXTDOMAIN_original
26 exit
27 esac
29 TITLE="$(_ 'TazPanel - Hardware') - $(_ 'Scanner')"
31 inrange() {
32 local n=$1
33 [ $1 -lt $2 ] && n=$2
34 [ $1 -gt $3 ] && n=$3
35 echo $n
36 }
38 getgeometry() {
39 CMD=""
40 for i in l t x y ; do
41 j=$(inrange $(xPOST geometry_$i) $(xPOST ${i}_min) $(xPOST ${i}_max))
42 eval "geometry_$i=$j"
43 CMD="$CMD -$i $j"
44 # convert -crop XxY+L+T -resize XxY
45 done
46 for i in mode source contrast brightness ; do
47 [ "$(xPOST $i)" ] && CMD="$CMD --$i '$(xPOST $i)'"
48 done
49 resolution=${1:-0}
50 if [ $resolution -eq 0 ]; then
51 resolution=$(xPOST res_min)
52 width=$(GET width)
53 [ ${geometry_x:-0} -le 0 ] && geometry_x=$(xPOST x_max)
54 while [ $((${resolution:=150} * ${geometry_x%.*})) -lt ${width:-8192} ]; do
55 resolution=$(($resolution * 2))
56 done
57 fi
58 [ -d tmp ] || ln -s /tmp tmp
59 case "$device" in
60 fake*) echo "cat /usr/share/images/slitaz-background.jpg" ;;
61 *) echo "scanimage -d '$(echo $device | sed 's/,.*//')' --resolution '$(inrange $resolution $(xPOST res_min) $(xPOST res_max))dpi'$CMD"
62 esac
63 }
65 imgformat() {
66 tmp=$(mktemp -u -t tazsane.XXXXXX)
67 while read key name type exe pkg cmd ; do
68 case "$key" in
69 \#*) continue
70 esac
71 case "$1" in
72 list)
73 echo -n "<option value=\"$key\""
74 [ "$(which $exe 2> /dev/null)" ] ||
75 echo -n " disabled title=\"$exe not found: install $pkg\""
76 [ "$key" == "pnm" ] &&
77 echo -n " title=\"not supported by most browsers\""
78 echo ">$key" ;;
79 *)
80 case "$key" in
81 $(xPOST format)|'*')
82 case "$HTTP_USER_AGENT" in
84 # Tazweb has no download support
85 TazWe*) rm -f /tmp/$name
86 eval "$(getgeometry $(xPOST resolution)) $cmd >/tmp/$name" 2> $tmp.err
87 if [ -s /tmp/$name ]; then
88 info="Stored in /tmp/$name ($(stat -c %s /tmp/$name) bytes)."
89 else
90 error="$(sed 's|$|<br />|' $tmp.err)"
91 [ "$error" ] || error="I/O error"
92 fi
93 rm -f $tmp.* ;;
95 # Others should work
96 *) header "Content-Type: $type" \
97 "Content-Disposition: attachment; filename=$name" \
99 eval "$(getgeometry $(xPOST resolution)) $cmd"
100 rm -f $tmp.*
101 exit ;;
102 esac ;;
103 esac ;;
104 esac
105 done <<EOT
106 png tazsane.png image/png convert imagemagick > $tmp.pnm; convert $tmp.pnm png:-
107 jpeg tazsane.jpg image/jpeg convert imagemagick > $tmp.pnm; convert $tmp.pnm jpg:-
108 jpeg2000 tazsane.jp2 image/jpeg2000-image convert imagemagick > $tmp.pnm; convert $tmp.pnm jp2:-
109 tiff tazsane.tiff image/tiff convert imagemagick > $tmp.pnm; convert $tmp.pnm tiff:-
110 ps tazsane.ps application/postscript convert imagemagick > $tmp.pnm; convert -page A4+0+0 $tmp.pnm ps:-
111 pdf tazsane.pdf image/pdf convert imagemagick > $tmp.pnm; convert $tmp.pnm pdf:-
112 ocr1 tazsane-OCR1.txt text/plain gocr gocr | gocr -
113 ocr2 tazsane-OCR2.txt text/plain tesseract tesseract-ocr | tesseract stdin stdout
114 pnm tazsane.pnm image/pnm true slitaz
115 EOT
116 }
118 xPOST() {
119 [ "$preview" == "reset" ] || POST $@
120 }
122 tmpreview="$(POST tmpreview)"
123 find tmp/ -name 'tazsane*' -mmin +60 -prune -exec rm -f {} \;
125 device="$(POST device)"
126 preview="$(POST preview)"
127 info=""
128 error=""
130 case " $(POST) " in
131 *\ reset\ *)
132 unset device tmpreview
133 preview="reset" ;;
134 *\ preview\ *)
135 [ "$tmpreview" ] || tmpreview=$(mktemp -u -t tazsane.XXXXXX).png
136 tmp=$(mktemp -u -t tazsane.XXXXXX)
137 eval "$(getgeometry)" > $tmp.pnm 2> $tmp.err
138 if [ -s "$tmp.pnm" ]; then
139 convert $tmp.pnm $tmpreview > /dev/null 2>&1 ||
140 cp $tmp.pnm $tmpreview
141 else
142 error="$(sed 's|$|<br />|' $tmp.err)"
143 rm -f $tmpreview
144 fi
145 rm -f $tmp.pnm $tmp.err ;;
146 *\ scan\ *)
147 imgformat download ;;
148 esac
150 header
151 xhtml_header
152 [ -n "$error" ] && msg warn "$error"
153 [ -n "$info" ] && msg tip "$info"
154 [ "$(which convert 2> /dev/null)" ] ||
155 msg tip "$(_ "You should install %s to preview images." \
156 "<a href=\"/user/pkgs.cgi?info=imagemagick\">imagemagick</a>")"
157 if [ -z "$device" ]; then
158 [ -s sane-fake.log ] && all="$(sed 's/|/\n/g' sane-fake.log)" ||
159 all="$(scanimage -f '%d,%v %m|' | sed 's/|/\n/g')"
160 case "$(echo "$all" | wc -l)" in
161 1) if [ -z "$all" ]; then
162 msg warn 'No scanner found'
163 xhtml_footer
164 exit 0
165 fi
166 device="${all%|}" ;;
167 *) cat <<EOT
168 <section>
169 <header>
170 <form name="scanner" method="post">
171 Scanner
172 <select name="device" size=1>
173 EOT
174 echo "$all" | awk -F, '{ if (NF > 0) print "<option value=\"" $0 "\">" 1+i++ " - " $2 }'
175 cat <<EOT
176 </select>
177 <button data-icon="start">$(_ "Continue")</button>
178 </form>
179 </header>
180 </section>
181 EOT
182 xhtml_footer
183 exit 0 ;;
184 esac
185 fi
187 cat <<EOT
188 <section>
189 <form name="parameters" method="post">
190 <script language="JavaScript" type="text/javascript">
191 <!--
192 function new_width() {
193 document.parameters.action = "?width="+document.width
194 }
196 window.onresize = new_width
197 new_width()
198 -->
199 </script>
201 <header>
202 $(echo $device | sed 's/.*,//')
203 <div class="float-right">
204 <button name="scan" data-icon="start">$(_ "Scan")</button>
205 <button name="reset" data-icon="stop">$(_ "Reset")</button>
206 <button name="preview" data-icon="view">$(_ "Preview")</button>
207 </div>
208 </header>
210 <table class="wide" border="2" cellpadding="8" cellspacing="0">
211 <tr>
212 <td>Format
213 <select name="format" size=1>
214 $(imgformat list)
215 </select>
216 </td>
217 EOT
219 if [ "$(xPOST params)" ]; then
220 params="$(xPOST params | uudecode)"
221 else
222 params="$({
223 cat "$(echo $device | sed 's/,.*//').log" 2> /dev/null ||
224 scanimage --help -d "$(echo $device | sed 's/,.*//')"
225 } | awk '
226 function minmax()
227 {
228 if (match($2,"[0-9]")) {
229 i=$2; sub(/\.\..*/,"",i)
230 j=$2; sub(/.*\.\./,"",j)
231 sub(/\..*/,"",j); sub(/[dm%].*/,"",j)
232 k=$0; sub(/.* \[/,"",k); sub(/\].*/,"",k)
233 print $1 " " int(k) " " int(i) " " int(j)
234 }
235 }
237 function enum()
238 {
239 i=$0
240 if (index(i,"|")) {
241 sub(/^ *--*[a-z]* */,"",i)
242 sub(/dpi .*/,"",i); gsub(/ \[.*\].*/,"",i)
243 k=$0; sub(/.* \[/,"",k); sub(/\].*/,"",k)
244 gsub(/ /,"=",k)
245 print $1 " " k " enum " i
246 }
247 else minmax()
248 }
250 /Options specific to device/ { parse=1 }
251 {
252 if (parse != 1) next
253 if (/\[inactive\]/) next
254 if (match("-l-t-x-y", $1)) minmax()
255 if (match("--resolution--brightness--contrast--source--mode", $1)) enum()
256 }
257 ')"
258 fi
259 output="$(echo "$params" | while read name def min max ; do
260 name="${name##*-}"
261 def="${def//=/ }"
262 if [ "$min" == "enum" ]; then
263 res_min=1000000
264 res_max=0
265 echo "<td>$name"
266 echo -n "<select name=\"$name\" size=1"
267 [ "$name" == "resolution" ] && echo -n " onchange=showGeometry()"
268 echo ">"
269 IFS="|"; set -- $max ; unset IFS
270 while [ "$1" ]; do
271 echo -n "<option value=\"$1\""
272 [ "$(xPOST $name)" == "$1" ] && echo -n " selected"
273 [ -z "$(xPOST $name)" -a "$def" == "$1" ] && echo -n " selected"
274 echo ">$(_ "$1")"
275 if [ "$name" == "resolution" ]; then
276 [ $res_max -lt $1 ] && res_max=$1
277 [ $res_min -gt $1 ] && res_min=$1
278 fi
279 shift
280 done
281 echo "</select>"
282 else
283 [ "$(xPOST $name)" ] && def=$(xPOST $name)
284 [ $def -lt $min ] && def=$min
285 [ $def -gt $max ] && def=$max
286 f="$(_ "$name")<input name=\"$name\" value=\"$def\""
287 u=""
288 case "$name" in
289 x|y|l|t) cat <<EOT
290 :${name}_max=$max
291 <input type="hidden" name="${name}_min" value="$min">
292 <input type="hidden" name="${name}_max" value="$max">
293 EOT
294 while read name2 n2 id val; do
295 [ "$name" == "$name2" ] || continue
296 [ "$(xPOST geometry_$name)" ] &&
297 val="$(xPOST geometry_$name)"
298 f="$(_ "$n2")<input name=\"geometry_$name\" id=\"$id\" value=\"$val\""
299 u="&nbsp;mm"
300 break
301 done <<EOT
302 l X-Offset x 0
303 t Y-Offset y 0
304 x Width width $max
305 y Height height $max
306 EOT
307 [ "$newline" ] || echo "</tr><tr>"
308 newline=$name
309 esac
310 [ "$name" == "resolution" ] && f="$f onchange=showGeometry()"
311 echo "<td>$f type=\"text\" title=\"$min .. $max\" size=4 maxlength=4>$u"
312 res_min=$min
313 res_max=$max
314 fi
315 case "$name" in
316 resolution) cat <<EOT
317 <input type="hidden" name="res_min" value="$res_min">
318 <input type="hidden" name="res_max" value="$res_max">
319 &nbsp;dpi
320 EOT
321 esac
322 echo "</td>"
323 done)"
324 echo "$output" | sed '/^:/d'
326 org_x=$(xPOST geometry_x); [ "$org_x" ] || org_x=$(echo "$output" | sed '/^:x_max=/!d;s/.*=//')
327 org_y=$(xPOST geometry_y); [ "$org_y" ] || org_y=$(echo "$output" | sed '/^:y_max=/!d;s/.*=//')
329 cat <<EOT
330 </tr>
331 </table>
332 <input type="hidden" name="tmpreview" value="$tmpreview">
333 <input type="hidden" name="device" value="$device">
334 <input type="hidden" name="params" value="$(echo "$params" | uuencode -m -)">
335 <script language="JavaScript" type="text/javascript">
336 <!--
337 function setGeometry(x,y) {
338 document.parameters.geometry_x.value = x;
339 document.parameters.geometry_y.value = y;
340 cropSetFrameByInput();
341 }
343 function showGeometry() {
344 var resolution = document.parameters.resolution.value;
345 if (resolution) {
346 resolution /= 25.4;
347 var x = Math.floor(document.parameters.geometry_x.value * resolution);
348 var y = Math.floor(document.parameters.geometry_y.value * resolution);
349 alert((Math.round(x * y / 100000)/10) + ' Mpixels\n' + x + 'x' + y);
350 }
351 }
352 -->
353 </script>
355 <footer align="center">
356 EOT
357 awk -vox=$org_x -voy=$org_y 'END {
358 x=210*4; y=297*4; n=0; cnt=0;
359 while (cnt < 9) {
360 if (ox +1 >= x && oy +1 >= y) {
361 print "&nbsp;<a href=\"javascript:setGeometry(" x "," y ")\">DIN-A" n "</a>"
362 cnt++
363 }
364 if (ox +1 >= x && oy +1 >= y) {
365 print "&nbsp;<a href=\"javascript:setGeometry(" y "," x ")\">DIN-A" n "L</a>"
366 cnt++
367 }
368 tmp=x; x=y/2; y=tmp
369 n++
370 }
371 }' < /dev/null
373 cat <<EOT
374 </footer>
375 </form>
376 </section>
377 EOT
379 [ -s "$tmpreview" ] && cat <<EOT
380 <div margin="15px" style="overflow-x: auto">
381 <script type="text/javascript" src="lib/crop.js"></script>
382 <img src="$tmpreview" onload=cropInit(this,'x','y','width','height')>
383 </div>
384 EOT
385 xhtml_footer