tazbug view web/bugs.cgi @ rev 23

web: enable content negociation fo Russian
author Christophe Lincoln <pankso@slitaz.org>
date Wed Apr 04 23:00:54 2012 +0200 (2012-04-04)
parents 74eb7fea1546
children 828d018ffb0f
line source
1 #!/bin/sh
2 #
3 # TazBug Web interface
4 #
5 # Copyright (C) 2012 SliTaz GNU/Linux - BSD License
6 #
7 . /usr/lib/slitaz/httphelper
8 [ -f "/etc/slitaz/tazbug.conf" ] && . /etc/slitaz/tazbug.conf
9 [ -f "../tazbug.conf" ] && . ../tazbug.conf
11 # Internal variable
12 bugdir="bug"
13 sessions="/tmp/tazbug/sessions"
15 # Content negotiation for Gettext
16 IFS=","
17 for lang in $HTTP_ACCEPT_LANGUAGE
18 do
19 lang=${lang%;*} lang=${lang# } lang=${lang%-*}
20 [ -d "$lang" ] && break
21 case "$lang" in
22 en) lang="C" ;;
23 fr) lang="fr_FR" ;;
24 ru) lang="ru_RU" ;;
25 esac
26 done
27 unset IFS
28 export LANG=$lang LC_ALL=$lang
30 # Internationalization: $(gettext "")
31 . /usr/bin/gettext.sh
32 TEXTDOMAIN='tazbug'
33 export TEXTDOMAIN
35 #
36 # Functions
37 #
39 # HTML 5 header.
40 html_header() {
41 cat lib/header.html
42 }
44 # HTML 5 footer.
45 html_footer() {
46 cat << EOT
47 </div>
49 <div id="footer">
50 <a href="./">SliTaz Bugs</a> -
51 <a href="./?README">README</a>
52 </div>
54 </body>
55 </html>
56 EOT
57 }
59 # Crypt pass when login
60 crypt_pass() {
61 echo -n "$1" | md5sum | awk '{print $1}'
62 }
64 # Check if user is auth
65 check_auth() {
66 auth="$(COOKIE auth)"
67 user="$(echo $auth | cut -d ":" -f 1)"
68 md5cookie="$(echo $auth | cut -d ":" -f 2)"
69 [ -f "$sessions/$user" ] && md5session="$(cat $sessions/$user)"
70 if [ "$md5cookie" == "$md5session" ] && [ "$auth" ]; then
71 return 0
72 else
73 return 1
74 fi
75 }
77 # Authentified or not
78 user_box() {
79 if check_auth; then
80 . $PEOPLE/$user/slitaz.conf
81 cat << EOT
82 <div id="user">
83 $(get_gravatar $MAIL 20)
84 <a href="?user=$user">$user</a>
85 <a href="?logout">Logout</a>
86 </div>
87 EOT
88 else
89 cat << EOT
90 <div id="user">
91 <img src="images/avatar.png" alt="[ User ]" />
92 <a href="?login">Login</a>
93 </div>
94 EOT
95 fi
96 cat << EOT
98 <!-- Content -->
99 <div id="content">
101 EOT
102 }
104 # Login page
105 login_page() {
106 cat << EOT
107 <!-- Content -->
108 <div id="content">
110 <h2>$(gettext "Login")</h2>
112 <div id="account-info">
113 $(gettext "No account yet? Please signup using the SliTaz Bugs reporter
114 on your SliTaz system. <p>Tip: to attach big files or images, you can use
115 SliTaz Paste services:") <a href="http://paste.slitaz.org/">paste.slitaz.org</a>
116 </p>
117 </div>
119 <div id="login">
120 <form method="post" action="$SCRIPT_NAME">
121 <input type="text" name="auth" placeholder="$(gettext "User name")" />
122 <input type="password" name="pass" placeholder="$(gettext "Password")" />
123 <div>
124 <input type="submit" value="Login" />
125 $error
126 </div>
127 </form>
128 </div>
130 <div style="clear: both;"></div>
131 EOT
132 }
134 # Display user public profile.
135 public_people() {
136 cat << EOT
137 <pre>
138 Real name : $NAME
139 </pre>
140 EOT
141 }
143 # Display authentified user profile. TODO: change password
144 auth_people() {
145 cat << EOT
146 <pre>
147 Real name : $NAME
148 Email : $MAIL
149 Secure key : $KEY
150 </pre>
151 EOT
152 }
154 # Usage: list_bugs STATUS
155 list_bugs() {
156 echo "<h3>$1 Bugs</h3>"
157 for pr in critical standard
158 do
159 for bug in $(fgrep -H "$1" $bugdir/*/bug.conf | cut -d ":" -f 1)
160 do
161 . $bug
162 id=$(dirname $bug | cut -d "/" -f 2)
163 if [ "$PRIORITY" == "$pr" ]; then
164 cat << EOT
165 <pre>
166 Bug title : <strong>$BUG</strong> <a href="?id=$id">Show</a>
167 ID - Date : $id - $DATE
168 Creator : <a href="?user=$CREATOR">$CREATOR</a>
169 </pre>
170 EOT
171 fi
172 done
173 done
174 }
176 # Stripped down Wiki parser for bug desc and messages which are simply
177 # displayed in <pre>
178 wiki_parser() {
179 sed \
180 -e s"#http://\([^']*\).png#<img src='\0' alt='[ Image ]' />#"g \
181 -e s"#http://\([^']*\).*# <a href='\0'>\1</a>#"g
182 }
184 # Bug page
185 bug_page() {
186 if [ -f "$PEOPLE/$CREATOR/slitaz.conf" ]; then
187 . $PEOPLE/$CREATOR/slitaz.conf
188 else
189 MAIL="default"
190 fi
191 cat << EOT
192 <h2>Bug $id</h2>
193 <form method="get" action="./">
195 <p>
196 $(get_gravatar $MAIL 32) <strong>$STATUS</strong> $BUG - $DATE - Priority $PRIORITY
197 - $msgs messages
198 </p>
200 <pre>
201 $(echo "$DESC" | wiki_parser)
202 </pre>
204 <div id="tools">
205 EOT
206 if check_auth; then
207 if [ "$STATUS" == "OPEN" ]; then
208 cat << EOT
209 <a href="?id=$id&amp;close">$(gettext "Close bug")</a>
210 <a href="?edit=$id">$(gettext "Edit bug")</a>
211 EOT
212 else
213 cat << EOT
214 <a href="?id=$id&amp;open">$(gettext "Re open bug")</a>
215 EOT
216 fi
217 fi
218 cat << EOT
219 </div>
221 <h3>$(gettext "Messages")</h3>
222 EOT
223 [ "$msgs" == "0" ] && gettext "No messages"
224 for msg in $(ls -1tr $bugdir/$id/msg.*)
225 do
226 . $msg
227 if [ "$MSG" ]; then
228 msgid=$(echo $msg | cut -d "." -f 2)
229 del=""
230 # User can delete his post.
231 [ "$user" == "$USER" ] && \
232 del="<a href=\"?id=$id&amp;delmsg=$msgid\">delete</a>"
233 cat << EOT
234 <p><strong>$USER</strong> $DATE $del</p>
235 <pre>
236 $(echo "$MSG" | wiki_parser)
237 </pre>
238 EOT
239 fi
240 unset NAME DATE MSG
241 done
242 if check_auth; then
243 cat << EOT
244 <div>
245 <h3>$(gettext "New message")</h3>
247 <input type="hidden" name="id" value="$id" />
248 <textarea name="msg" rows="8"></textarea>
249 <p><input type="submit" value="$(gettext "Send message")" /></p>
250 </form>
251 </div>
252 EOT
253 fi
254 }
256 # Write a new message
257 new_msg() {
258 date=$(date "+%Y-%m-%d %H:%M")
259 msgs=$(ls -1 $bugdir/$id/msg.* | wc -l)
260 count=$(($msgs + 1))
261 if check_auth; then
262 USER="$user"
263 fi
264 sed "s/$(echo -en '\r') /\n/g" > $bugdir/$id/msg.$count << EOT
265 USER="$USER"
266 DATE="$date"
267 MSG="$(GET msg)"
268 EOT
269 }
271 # Create a new Bug
272 new_bug() {
273 count=$(ls -1 $bugdir | wc -l)
274 date=$(date "+%Y-%m-%d %H:%M")
275 # Sanity check, JS may be disabled.
276 [ ! "$(GET bug)" ] && echo "Missing bug title" && exit 1
277 [ ! "$(GET desc)" ] && echo "Missing bug description" && exit 1
278 if check_auth; then
279 USER="$user"
280 fi
281 mkdir -p $bugdir/$count
282 sed "s/$(echo -en '\r') /\n/g" > $bugdir/$count/bug.conf << EOT
283 # SliTaz Bug configuration
285 BUG="$(GET bug)"
286 STATUS="OPEN"
287 PRIORITY="$(GET priority)"
288 CREATOR="$USER"
289 DATE="$date"
290 PKGS="$(GET pkgs)"
292 DESC="$(GET desc)"
293 EOT
294 }
296 # New bug page for the web interface
297 new_bug_page() {
298 cat << EOT
299 <h2>$(gettext "New Bug")</h2>
300 <div id="newbug">
302 <form method="get" action="./" onsubmit="return checkNewBug();">
303 <input type="hidden" name="addbug" />
304 <table>
305 <tbody>
306 <tr>
307 <td>$(gettext "Bug title")*</td>
308 <td><input type="text" name="bug" /></td>
309 </tr>
310 <tr>
311 <td>$(gettext "Description")*</td>
312 <td><textarea name="desc"></textarea></td>
313 </tr>
314 <tr>
315 <td>$(gettext "Packages")</td>
316 <td><input type="text" name="pkgs" /></td>
317 </tr>
318 <tr>
319 <td>$(gettext "Priority")</td>
320 <td>
321 <select name="priority">
322 <option value="standard">$(gettext "Standard")</option>
323 <option value="critical">$(gettext "Critical")</option>
324 </select>
325 <input type="submit" value="$(gettext "Create Bug")" />
326 </td>
327 </tr>
328 </tbody>
329 </table>
330 </form>
332 <p>
333 $(gettext "* field is obligatory. You can also specify affected packages.")
334 </p>
336 </div>
337 EOT
338 }
340 # Edit/Save a bug configuration file
341 edit_bug() {
342 cat << EOT
343 <h2>$(gettext "Edit Bug $bug")</h2>
344 <div id="edit">
346 <form method="get" action="./">
347 <textarea name="bugconf">$(cat $bugdir/$bug/bug.conf)</textarea>
348 <input type="hidden" name="bug" value="$bug" />
349 <input type="submit" value="$(gettext "Save configuration")" />
350 </form>
352 </div>
353 EOT
354 }
356 save_bug() {
357 bug="$(GET bug)"
358 content="$(GET bugconf)"
359 sed "s/$(echo -en '\r') /\n/g" > $bugdir/$bug/bug.conf << EOT
360 $content
361 EOT
362 }
364 # Close a fixed bug
365 close_bug() {
366 sed -i s'/OPEN/CLOSED/' $bugdir/$id/bug.conf
367 }
369 # Re open an old bug
370 open_bug() {
371 sed -i s'/CLOSED/OPEN/' $bugdir/$id/bug.conf
372 }
374 # Get and display Gravatar image: get_gravatar email size
375 # Link to profile: <a href="http://www.gravatar.com/$md5">...</a>
376 get_gravatar() {
377 email=$1
378 size=$2
379 [ "$size" ] || size=48
380 url="http://www.gravatar.com/avatar"
381 md5=$(echo -n $email | md5sum | cut -d " " -f 1)
382 echo "<img src='$url/$md5?d=identicon&s=$size' alt='' />"
383 }
385 # Create a new user in AUTH_FILE and PEOPLE
386 new_user_config() {
387 mail="$(GET mail)"
388 pass="$(GET pass)"
389 key=$(echo -n "$user:$mail:$pass" | md5sum | awk '{print $1}')
390 echo "$user:$pass" >> $AUTH_FILE
391 mkdir -p $PEOPLE/$user/
392 cat > $PEOPLE/$user/slitaz.conf << EOT
393 # SliTaz user configuration
394 #
396 NAME="$(GET name)"
397 USER="$user"
398 MAIL="$mail"
399 KEY="$key"
401 COMMUNITY="$(GET scn)"
402 LOCATION="$(GET location)"
403 RELEASES="$(GET releases)"
404 PACKAGES="$(GET packages)"
405 EOT
406 chmod 0600 $PEOPLE/$user/slitaz.conf
407 }
409 #
410 # POST actions
411 #
413 case " $(POST) " in
414 *\ auth\ *)
415 # Authenticate user. Create a session file in $sessions to be used
416 # by check_auth. We have the user login name and a peer session
417 # md5 string in the COOKIE.
418 user="$(POST auth)"
419 pass="$(crypt_pass "$(POST pass)")"
420 valid=$(fgrep "${user}:" $AUTH_FILE | cut -d ":" -f 2)
421 if [ "$pass" == "$valid" ] && [ "$pass" != "" ]; then
422 md5session=$(echo -n "$$:$user:$pass:$$" | md5sum | awk '{print $1}')
423 mkdir -p $sessions
424 echo "$md5session" > $sessions/$user
425 header "Location: $WEB_URL" \
426 "Set-Cookie: auth=$user:$md5session; HttpOnly"
427 else
428 header "Location: $WEB_URL?login&error"
429 fi ;;
430 esac
432 #
433 # GET actions
434 #
436 case " $(GET) " in
437 *\ README\ *)
438 header
439 html_header
440 user_box
441 echo '<h2>README</h2>'
442 echo '<pre>'
443 cat /usr/share/doc/tazbug/README
444 echo '</pre>'
445 html_footer ;;
446 *\ closed\ *)
447 # Show all closed bugs.
448 header
449 html_header
450 user_box
451 list_bugs CLOSED
452 html_footer ;;
453 *\ login\ *)
454 # The login page
455 [ "$(GET error)" ] && \
456 error="<span class="error">$(gettext "Bad login or pass")</span>"
457 header
458 html_header
459 user_box
460 login_page
461 html_footer ;;
462 *\ logout\ *)
463 # Set a Cookie in the past to logout.
464 expires="Expires=Wed, 01-Jan-1980 00:00:00 GMT"
465 if check_auth; then
466 rm -f "$sessions/$user"
467 header "Location: $WEB_URL" "Set-Cookie: auth=none; $expires; HttpOnly"
468 fi ;;
469 *\ user\ *)
470 # User profile
471 header
472 html_header
473 user_box
474 . $PEOPLE/"$(GET user)"/slitaz.conf
475 echo "<h2>$(get_gravatar $MAIL) $(GET user)</h2>"
476 if check_auth && [ "$(GET user)" == "$user" ]; then
477 auth_people
478 else
479 public_people
480 fi
481 html_footer ;;
482 *\ newbug\ *)
483 # Add a bug from web interface.
484 header
485 html_header
486 user_box
487 if check_auth; then
488 new_bug_page
489 else
490 echo "<p>$(gettext "You must be logged in to post a new bug")</p>"
491 fi
492 html_footer ;;
493 *\ addbug\ *)
494 # Add a bug from web interface.
495 if check_auth; then
496 new_bug
497 header "Location: $WEB_URL?id=$count"
498 fi ;;
499 *\ edit\ *)
500 bug="$(GET edit)"
501 header
502 html_header
503 user_box
504 edit_bug
505 html_footer ;;
506 *\ bugconf\ *)
507 if check_auth; then
508 save_bug
509 header "Location: $WEB_URL?id=$bug"
510 fi ;;
511 *\ id\ *)
512 # Empty deleted messages to keep msg count working.
513 id="$(GET id)"
514 [ "$(GET close)" ] && close_bug
515 [ "$(GET open)" ] && open_bug
516 [ "$(GET msg)" ] && new_msg
517 [ "$(GET delmsg)" ] && rm -f $bugdir/$id/msg.$(GET delmsg) && \
518 touch $bugdir/$id/msg.$(GET delmsg)
519 msgs=$(fgrep MSG= $bugdir/$id/msg.* | wc -l)
520 header
521 html_header
522 user_box
523 . $bugdir/$id/bug.conf
524 bug_page
525 html_footer ;;
526 *\ signup\ *)
527 # Signup
528 header "Content-type: text/plain;"
529 user="$(GET signup)"
530 echo "Requested user login : $user"
531 if fgrep -q "$user:" $AUTH_FILE; then
532 echo "ERROR: User already exists" && exit 1
533 else
534 echo "Creating account for : $(GET name)"
535 new_user_config
536 fi ;;
537 *\ key\ *)
538 # Let user post new bug or message with crypted key (no gettext)
539 #
540 # Testing only and is security acceptable ?
541 #
542 key="$(GET key)"
543 id="$(GET bug)"
544 header "Content-type: text/plain;"
545 echo "Checking secure key..."
546 if fgrep -qH $key $PEOPLE/*/slitaz.conf; then
547 conf=$(fgrep -H $key $PEOPLE/*/slitaz.conf | cut -d ":" -f 1)
548 . $conf
549 echo "Authentified: $NAME ($USER)"
550 case " $(GET) " in
551 *\ msg\ *)
552 [ ! "$id" ] && echo "Missing bug ID" && exit 0
553 echo "Posting new message to bug: $id"
554 echo "Message: $(GET msg)"
555 new_msg ;;
556 *\ bug\ *)
557 echo "Adding new bug: $(GET bug)"
558 echo "Description: $(GET desc)"
559 new_bug ;;
560 esac
561 else
562 echo "Not a valid SliTaz user key"
563 exit 0
564 fi ;;
565 *\ search\ *)
566 header
567 html_header
568 user_box
569 cat << EOT
570 <h2>$(gettext "Search")</h2>
571 <form method="get" action="./">
572 <input type="text" name="search" />
573 <input type="submit" value="$(gettext "Search")" />
574 </form>
575 <div>
576 EOT
578 #found=0 JS to notify or write results nb under the search box.
579 for bug in $bugdir/*
580 do
581 result=$(fgrep -i "$(GET search)" $bug/*)
582 if [ "$result" ]; then
583 #found=$(($found + 1))
584 id=${bug#bug/}
585 echo "<p><strong>Bug $id</strong> <a href='?id=$id'>$(gettext "Show")</a></p>"
586 echo '<pre>'
587 fgrep -i "$(GET search)" $bugdir/$id/* | \
588 sed s"/$(GET search)/<span class='ok'>$(GET search)<\/span>/"g
589 echo '</pre>'
590 else
591 gettext "<p>No result found for:"; echo " $(GET search)</p>"
592 fi
593 done
594 echo '</div>'
595 html_footer ;;
596 *)
597 # Default page.
598 bugs=$(ls -1 $bugdir | wc -l)
599 close=$(fgrep "CLOSED" $bugdir/*/bug.conf | wc -l)
600 fixme=$(fgrep "OPEN" $bugdir/*/bug.conf | wc -l)
601 msgs=$(find $bugdir -name msg.* ! -size 0 | wc -l)
602 pct=0
603 [ $bugs -gt 0 ] && pct=$(( ($close * 100) / $bugs ))
604 header
605 html_header
606 user_box
607 cat << EOT
609 <h2>$(gettext "Summary")</h2>
611 <p>
612 Bugs: $bugs in total - $close fixed - $fixme to fix - $msgs messages
613 </p>
615 <div class="pctbar">
616 <div class="pct" style="width: ${pct}%;">${pct}%</div>
617 </div>
619 <p>
620 Beta code! Please read the <a href="?README">README</a> for more
621 information.
622 </p>
624 <div id="tools">
625 <a href="?closed">View closed bugs</a>
626 EOT
627 if check_auth; then
628 echo "<a href='?newbug'>$(gettext "Create a new bug")</a>"
629 fi
630 cat << EOT
631 <form method="get" action="./">
632 <input type="text" name="search" placeholder="$(gettext "Search")" />
633 <!-- <input type="submit" value="$(gettext "Search")" /> -->
634 </form>
635 </div>
636 EOT
637 list_bugs OPEN
638 html_footer ;;
639 esac
641 exit 0