wok-next view sane-backends/stuff/tazpanel/sane.cgi @ rev 18267
Up subversion (1.9.0), apache (2.4.16)
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Thu Aug 06 12:50:00 2015 +0200 (2015-08-06) |
parents | a705d8e80b1c |
children | 746d6d9ed619 |
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 ARGS=""
41 for i in x y l t ; do
42 j=$(inrange $(xPOST geometry_$i) $(xPOST ${i}_min) $(xPOST ${i}_max))
43 eval "geometry_$i=$j"
44 CMD="$CMD -$i $j"
45 ARGS="$ARGS $j"
46 done
47 for i in mode source contrast brightness ; do
48 [ "$(xPOST $i)" ] && CMD="$CMD --$i '$(xPOST $i)'"
49 done
50 resolution=${1:-0}
51 if [ $resolution -eq 0 ]; then
52 resolution=$(xPOST res_min)
53 width=$(GET width)
54 [ ${geometry_x:-0} -le 0 ] && geometry_x=$(xPOST x_max)
55 while [ $((${resolution:=150} * ${geometry_x%.*})) -lt ${width:-8192} ]; do
56 resolution=$(($resolution * 2))
57 done
58 fi
59 case "$(xPOST mode)" in
60 *lack*|*ineart*) mode="-monochrome" ;;
61 *ray*) mode="-colorspace gray" ;;
62 *) mode="" ;;
63 esac
64 [ -d tmp ] || ln -s /tmp tmp
65 case "$device" in
66 fake*) f=/usr/share/images/slitaz-banner.png
67 c="$(echo $ARGS $(identify $f | sed \
68 's/.* \([0-9]*\)x.*/\1/') $(GET width) $(POST x_max) | awk '
69 function a(x) { return int(($x * $5)/ $7); }
70 { printf "%dx%d+%d+%d -resize %dx%d",a(1),a(2),a(3),a(4),$6,int(($2*$6)/$1)}
71 ')"
72 suf="png"; [ "$1" ] && suf="pnm"
73 cat <<EOT
74 if convert -crop $c $mode $f /tmp/sane$$.$suf 2> /dev/null ; then
75 cat /tmp/sane$$.$suf
76 rm -f /tmp/sane$$.$suf
77 else
78 cat $f
79 fi
80 EOT
81 ;;
82 *) echo -n "scanimage -d '$(echo $device | sed 's/,.*//')' --resolution '$(inrange $resolution $(xPOST res_min) $(xPOST res_max))dpi'$CMD"
83 if [ -z "$1" -a "$(which convert)" ]; then
84 echo -n "> /tmp/sane$$.pnm ; convert -resize "
85 echo $ARGS $(GET width) | awk '{ printf "%dx%d",$5,int(($2*$5)/$1)}'
86 echo -n " /tmp/sane$$.pnm /tmp/sane$$.png ;"
87 echo -n "cat /tmp/sane$$.png ; rm -f /tmp/sane$$.pn?"
88 fi
89 esac
90 }
92 imgformat() {
93 tmp=$(mktemp -u -t tazsane.XXXXXX)
94 while read key name type exe pkg cmd ; do
95 case "$key" in
96 \#*) continue
97 esac
98 case "$1" in
99 list)
100 echo -n "<option value=\"$key\""
101 [ "$(which $exe 2> /dev/null)" ] ||
102 echo -n " disabled title=\"$exe not found: install $pkg\""
103 [ "$key" == "pnm" ] &&
104 echo -n " title=\"not supported by most browsers\""
105 echo ">$key" ;;
106 *)
107 case "$key" in
108 $(xPOST format)|'*')
109 case "$HTTP_USER_AGENT" in
111 # Tazweb has no download support
112 TazWe*) rm -f /tmp/$name
113 eval "$(getgeometry $(xPOST resolution)) $cmd >/tmp/$name" 2> $tmp.err
114 if [ -s /tmp/$name ]; then
115 info="Stored in /tmp/$name ($(stat -c %s /tmp/$name) bytes)."
116 else
117 error="$(sed 's|$|<br />|' $tmp.err)"
118 [ "$error" ] || error="I/O error"
119 fi
120 rm -f $tmp.* ;;
122 # Others should work
123 *) header "Content-Type: $type" \
124 "Content-Disposition: attachment; filename=$name" \
126 eval "$(getgeometry $(xPOST resolution)) $cmd"
127 rm -f $tmp.*
128 exit ;;
129 esac ;;
130 esac ;;
131 esac
132 done <<EOT
133 png tazsane.png image/png convert imagemagick > $tmp.pnm; convert $tmp.pnm png:-
134 jpeg tazsane.jpg image/jpeg convert imagemagick > $tmp.pnm; convert $tmp.pnm jpg:-
135 jpeg2000 tazsane.jp2 image/jpeg2000-image convert imagemagick > $tmp.pnm; convert $tmp.pnm jp2:-
136 tiff tazsane.tiff image/tiff convert imagemagick > $tmp.pnm; convert $tmp.pnm tiff:-
137 ps tazsane.ps application/postscript convert imagemagick > $tmp.pnm; convert -page A4+0+0 $tmp.pnm ps:-
138 pdf tazsane.pdf image/pdf convert imagemagick > $tmp.pnm; convert $tmp.pnm pdf:-
139 ocr1 tazsane-OCR1.txt text/plain gocr gocr | gocr -
140 ocr2 tazsane-OCR2.txt text/plain tesseract tesseract-ocr | tesseract stdin stdout
141 pnm tazsane.pnm image/pnm true slitaz
142 EOT
143 }
145 xPOST() {
146 [ "$preview" == "reset" ] || POST $@
147 }
149 tmpreview="$(POST tmpreview)"
150 find tmp/ -name 'tazsane*' -mmin +60 -prune -exec rm -f {} \;
152 device="$(POST device)"
153 preview="$(POST preview)"
154 info=""
155 error=""
157 case " $(POST) " in
158 *\ reset\ *)
159 unset device tmpreview
160 preview="reset" ;;
161 *\ preview\ *)
162 [ "$tmpreview" ] || tmpreview=$(mktemp -u -t tazsane.XXXXXX).png
163 tmp=$(mktemp -u -t tazsane.XXXXXX)
164 eval "$(getgeometry)" > $tmp.pnm 2> $tmp.err
165 if [ -s "$tmp.pnm" ]; then
166 convert $tmp.pnm $tmpreview > /dev/null 2>&1 ||
167 cp $tmp.pnm $tmpreview
168 else
169 error="$(sed 's|$|<br />|' $tmp.err)"
170 rm -f $tmpreview
171 fi
172 rm -f $tmp.pnm $tmp.err ;;
173 *\ scan\ *)
174 imgformat download ;;
175 esac
177 header
178 xhtml_header
179 [ -n "$error" ] && msg warn "$error"
180 [ -n "$info" ] && msg tip "$info"
181 if [ -z "$device" ]; then
182 all="$(scanimage -f '%d,%v %m|'|cat - sane-fake.log|sed 's/|/\n/g')"
183 case "$(echo "$all" | wc -l)" in
184 1) if [ -z "$all" ]; then
185 msg warn "$(_ "No scanner found")"
186 msg tip "$(_ "You can test this GUI with ")\
187 <a href=\"/user/pkgs.cgi?info=fake-sane\">fake-sane</a>"
188 xhtml_footer
189 exit 0
190 fi
191 device="${all%|}" ;;
192 *)
193 suggested=""
194 while read exe pkg msg; do
195 [ "$(which $exe 2> /dev/null)" ] && continue
196 suggested="$suggested
197 <li><a href=\"/user/pkgs.cgi?info=$pkg\">$pkg</a> $msg</li>"
198 done <<EOT
199 convert imagemagick $(_ "to preview images and support more image formats")
200 gocr gocr $(_ "a basic optical character recognition")
201 tesseract tesseract-ocr $(_ "a better optical character recognition")
202 EOT
203 [ "$suggested" ] &&
204 msg tip "$(_ "You may need to install:") <ol>$suggested</ol>"
205 cat <<EOT
206 <section>
207 <header>
208 <form name="scanner" method="post">
209 Scanner
210 <select name="device" size=1>
211 EOT
212 echo "$all" | awk -F, '{ if (NF > 0) print "<option value=\"" $0 "\">" 1+i++ " - " $2 }'
213 cat <<EOT
214 </select>
215 <button data-icon="start">$(_ "Continue")</button>
216 </form>
217 </header>
218 </section>
219 EOT
220 xhtml_footer
221 exit 0 ;;
222 esac
223 fi
225 cat <<EOT
226 <section>
227 <form name="parameters" method="post">
228 <script language="JavaScript" type="text/javascript">
229 <!--
230 function new_width() {
231 document.parameters.action = "?width="+(document.width-30)
232 }
234 window.onresize = new_width
235 new_width()
236 -->
237 </script>
239 <header>
240 $(echo $device | sed 's/.*,//')
241 <div class="float-right">
242 <button name="scan" data-icon="start">$(_ "Scan")</button>
243 <button name="reset" data-icon="refresh">$(_ "Reset")</button>
244 <button name="preview" data-icon="view">$(_ "Preview")</button>
245 </div>
246 </header>
248 <table class="wide">
249 <tr>
250 <td>
251 <fieldset><legend>$(_ 'Format')</legend>
252 <select name="format" size=1>
253 $(imgformat list)
254 </select>
255 </fieldset>
256 </td>
257 EOT
259 if [ "$(xPOST params)" ]; then
260 params="$(xPOST params | uudecode)"
261 else
262 params="$({
263 cat "$(echo $device | sed 's/,.*//').log" 2> /dev/null ||
264 scanimage --help -d "$(echo $device | sed 's/,.*//')"
265 } | awk '
266 function minmax()
267 {
268 if (match($2,"[0-9]")) {
269 i=$2; sub(/\.\..*/,"",i)
270 j=$2; sub(/.*\.\./,"",j)
271 sub(/\..*/,"",j); sub(/[dm%].*/,"",j)
272 k=$0; sub(/.* \[/,"",k); sub(/\].*/,"",k)
273 print $1 " " int(k) " " int(i) " " int(j)
274 }
275 }
277 function enum()
278 {
279 i=$0
280 if (index(i,"|")) {
281 sub(/^ *--*[a-z]* */,"",i)
282 sub(/dpi .*/,"",i); gsub(/ \[.*\].*/,"",i)
283 k=$0; sub(/.* \[/,"",k); sub(/\].*/,"",k)
284 gsub(/ /,"=",k)
285 print $1 " " k " enum " i
286 }
287 else minmax()
288 }
290 /Options specific to device/ { parse=1 }
291 {
292 if (parse != 1) next
293 if (/\[inactive\]/) next
294 if (match("-l-t-x-y", $1)) minmax()
295 if (match("--resolution--brightness--contrast--source--mode", $1)) enum()
296 }
297 ')"
298 fi
299 output="$(n=$(echo "$params" | wc -l); echo "$params" | \
300 while read name def min max ; do
301 name="${name##*-}"
302 def="${def//=/ }"
303 if [ "$min" == "enum" ]; then
304 res_min=1000000
305 res_max=0
306 echo "<td><fieldset><legend>$name</legend>"
307 echo -n "<select name=\"$name\" size=1"
308 [ "$name" == "resolution" ] && echo -n " onchange=showGeometry()"
309 echo ">"
310 IFS="|"; set -- $max ; unset IFS
311 while [ "$1" ]; do
312 echo -n "<option value=\"$1\""
313 [ "$(xPOST $name)" == "$1" ] && echo -n " selected"
314 [ -z "$(xPOST $name)" -a "$def" == "$1" ] && echo -n " selected"
315 echo ">$(_ "$1")"
316 if [ "$name" == "resolution" ]; then
317 [ $res_max -lt $1 ] && res_max=$1
318 [ $res_min -gt $1 ] && res_min=$1
319 fi
320 shift
321 done
322 echo "</select>"
323 else
324 [ "$(xPOST $name)" ] && def=$(xPOST $name)
325 [ $def -lt $min ] && def=$min
326 [ $def -gt $max ] && def=$max
327 f="$(_ "$name") <input name=\"$name\" value=\"$def\""
328 u=""
329 case "$name" in
330 x|y|l|t) cat <<EOT
331 :${name}_max=$max
332 <input type="hidden" name="${name}_min" value="$min">
333 <input type="hidden" name="${name}_max" value="$max">
334 EOT
335 while read name2 n2 id val; do
336 [ "$name" == "$name2" ] || continue
337 [ "$(xPOST geometry_$name)" ] &&
338 val="$(xPOST geometry_$name)"
339 f="<fieldset><legend>$(_ "$n2")</legend><input name=\"geometry_$name\" id=\"$id\" value=\"$val\""
340 u=" mm"
341 break
342 done <<EOT
343 l X-Offset x 0
344 t Y-Offset y 0
345 x Width width $max
346 y Height height $max
347 EOT
348 esac
349 [ "$name" == "resolution" ] && f="$f onchange=showGeometry()"
350 echo "<td>$f type=\"text\" title=\"$min .. $max\" size=4 maxlength=4>$u"
351 res_min=$min
352 res_max=$max
353 fi
354 case "$name" in
355 resolution) cat <<EOT
356 <input type="hidden" name="res_min" value="$res_min">
357 <input type="hidden" name="res_max" value="$res_max">
358 dpi
359 EOT
360 esac
361 echo "</filedset></td>"
362 n=$(($n - 2))
363 case "$n" in
364 1|2) echo "</tr><tr>"
365 esac
366 done)"
367 echo "$output" | sed '/^:/d'
369 org_x=$(xPOST geometry_x); [ "$org_x" ] || org_x=$(echo "$output" | sed '/^:x_max=/!d;s/.*=//')
370 org_y=$(xPOST geometry_y); [ "$org_y" ] || org_y=$(echo "$output" | sed '/^:y_max=/!d;s/.*=//')
372 cat <<EOT
373 </tr>
374 </table>
375 <input type="hidden" name="tmpreview" value="$tmpreview">
376 <input type="hidden" name="device" value="$device">
377 <input type="hidden" name="params" value="$(echo "$params" | uuencode -m -)">
378 <script language="JavaScript" type="text/javascript">
379 <!--
380 function setGeometry(x,y) {
381 document.parameters.geometry_x.value = x;
382 document.parameters.geometry_y.value = y;
383 cropSetFrameByInput();
384 }
386 function showGeometry() {
387 var resolution = document.parameters.resolution.value;
388 if (resolution) {
389 resolution /= 25.4;
390 var x = Math.floor(document.parameters.geometry_x.value * resolution);
391 var y = Math.floor(document.parameters.geometry_y.value * resolution);
392 alert((Math.round(x * y / 100000)/10) + ' Mpixels\n' + x + 'x' + y);
393 }
394 }
395 -->
396 </script>
398 <footer align="center">
399 EOT
400 awk -vox=$org_x -voy=$org_y 'END {
401 x=210*4; y=297*4; n=0; cnt=0;
402 while (cnt < 9) {
403 if (ox +1 >= x && oy +1 >= y) {
404 print " <a href=\"javascript:setGeometry(" x "," y ")\">DIN-A" n "</a>"
405 cnt++
406 }
407 if (ox +1 >= x && oy +1 >= y) {
408 print " <a href=\"javascript:setGeometry(" y "," x ")\">DIN-A" n "L</a>"
409 cnt++
410 }
411 tmp=x; x=y/2; y=tmp
412 n++
413 }
414 }' < /dev/null
416 cat <<EOT
417 </footer>
418 </form>
419 </section>
420 EOT
422 [ -s "$tmpreview" ] && cat <<EOT
423 <div margin="15px" style="overflow-x: auto">
424 <script type="text/javascript" src="lib/crop.js"></script>
425 <img src="$tmpreview" onload=cropInit(this,'x','y','width','height')>
426 </div>
427 EOT
428 xhtml_footer