tazbug rev 9

Add the web interface
author Christophe Lincoln <pankso@slitaz.org>
date Tue Apr 03 12:12:59 2012 +0200 (2012-04-03)
parents b3ab30f7f7ae
children 97f597b8e63c
files Makefile web/bug/0/bug.conf web/bugs.cgi web/favicon.ico web/images/avatar.png web/images/home.png web/images/logo.png web/lib/functions.js web/lib/header.html web/style.css
line diff
     1.1 --- a/Makefile	Tue Apr 03 12:10:12 2012 +0200
     1.2 +++ b/Makefile	Tue Apr 03 12:12:59 2012 +0200
     1.3 @@ -46,10 +46,10 @@
     1.4  install-server:
     1.5  	install -m 0700 -d $(DESTDIR)$(VAR)/people
     1.6  	install -m 0700 -d $(DESTDIR)$(VAR)/auth
     1.7 -	install -m 0777 -d $(DESTDIR)$(WEB)
     1.8  	install -m 0777 -d $(DESTDIR)$(PREFIX)/share/doc/tazbug
     1.9  	touch $(DESTDIR)$(VAR)/auth/people
    1.10  	chmod 0600 $(DESTDIR)$(VAR)/auth/people
    1.11  	cp -a web $(DESTDIR)$(WEB)/bugs
    1.12  	cp README $(DESTDIR)$(PREFIX)/share/doc/tazbug
    1.13  	chown -R www.www $(DESTDIR)$(VAR)/*
    1.14 +	chown -R www.www $(DESTDIR)$(WEB)/bug
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/web/bug/0/bug.conf	Tue Apr 03 12:12:59 2012 +0200
     2.3 @@ -0,0 +1,11 @@
     2.4 +# SliTaz Bug configuration
     2.5 +
     2.6 +BUG="Use SliTaz Bug Tracker"
     2.7 +STATUS="OPEN"
     2.8 +PRIORITY="standard"
     2.9 +CREATOR="root"
    2.10 +DATE="2012-03-29"
    2.11 +TAGS=""
    2.12 +PKGS="tazbug"
    2.13 +
    2.14 +DESC="The bug description with link and usefull information"
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/web/bugs.cgi	Tue Apr 03 12:12:59 2012 +0200
     3.3 @@ -0,0 +1,641 @@
     3.4 +#!/bin/sh
     3.5 +#
     3.6 +# TazBug Web interface
     3.7 +#
     3.8 +# Copyright (C) 2012 SliTaz GNU/Linux - BSD License
     3.9 +#
    3.10 +. /usr/lib/slitaz/httphelper
    3.11 +[ -f "/etc/slitaz/tazbug.conf" ] && . /etc/slitaz/tazbug.conf
    3.12 +[ -f "../tazbug.conf" ] && . ../tazbug.conf
    3.13 +
    3.14 +# Internal variable
    3.15 +bugdir="bug"
    3.16 +sessions="/tmp/tazbug/sessions"
    3.17 +
    3.18 +# Content negotiation for Gettext
    3.19 +IFS=","
    3.20 +for lang in $HTTP_ACCEPT_LANGUAGE
    3.21 +do
    3.22 +	lang=${lang%;*} lang=${lang# } lang=${lang%-*}
    3.23 +	[ -d "$lang" ] &&  break
    3.24 +	case "$lang" in
    3.25 +		en) lang="C" ;;
    3.26 +		fr) lang="fr_FR" ;;
    3.27 +	esac
    3.28 +done
    3.29 +unset IFS
    3.30 +export LANG=$lang LC_ALL=$lang
    3.31 +
    3.32 +# Internationalization: $(gettext "")
    3.33 +. /usr/bin/gettext.sh
    3.34 +TEXTDOMAIN='tazbug'
    3.35 +export TEXTDOMAIN
    3.36 +
    3.37 +#
    3.38 +# Functions
    3.39 +#
    3.40 +
    3.41 +# HTML 5 header.
    3.42 +html_header() {
    3.43 +	cat lib/header.html
    3.44 +}
    3.45 +
    3.46 +# HTML 5 footer.
    3.47 +html_footer() {
    3.48 +	cat << EOT
    3.49 +</div>
    3.50 +
    3.51 +<div id="footer">
    3.52 +	<a href="./">SliTaz Bugs</a> -
    3.53 +	<a href="./?README">README</a>
    3.54 +</div>
    3.55 +
    3.56 +</body>
    3.57 +</html>
    3.58 +EOT
    3.59 +}
    3.60 +
    3.61 +# Crypt pass when login
    3.62 +crypt_pass() {
    3.63 +	echo -n "$1" | md5sum | awk '{print $1}'
    3.64 +}
    3.65 +
    3.66 +# Check if user is auth
    3.67 +check_auth() {
    3.68 +	auth="$(COOKIE auth)"
    3.69 +	user="$(echo $auth | cut -d ":" -f 1)"
    3.70 +	md5cookie="$(echo $auth | cut -d ":" -f 2)"
    3.71 +	[ -f "$sessions/$user" ] && md5session="$(cat $sessions/$user)"
    3.72 +	if [ "$md5cookie" == "$md5session" ] && [ "$auth" ]; then
    3.73 +		return 0
    3.74 +	else
    3.75 +		return 1
    3.76 +	fi
    3.77 +}
    3.78 +
    3.79 +# Authentified or not
    3.80 +user_box() {
    3.81 +	if check_auth; then
    3.82 +		. $PEOPLE/$user/slitaz.conf
    3.83 +		cat << EOT
    3.84 +<div id="user">
    3.85 +$(get_gravatar $MAIL 20)
    3.86 +<a href="?user=$user">$user</a>
    3.87 +<a href="?logout">Logout</a>
    3.88 +</div>
    3.89 +EOT
    3.90 +	else
    3.91 +	cat << EOT
    3.92 +<div id="user">
    3.93 +	<img src="images/avatar.png" alt="[ User ]" />
    3.94 +	<a href="?login">Login</a>
    3.95 +</div>
    3.96 +EOT
    3.97 +	fi
    3.98 +	cat << EOT
    3.99 +
   3.100 +<!-- Content -->
   3.101 +<div id="content">
   3.102 +
   3.103 +EOT
   3.104 +}
   3.105 +
   3.106 +# Login page
   3.107 +login_page() {
   3.108 +	cat << EOT
   3.109 +<!-- Content -->
   3.110 +<div id="content">
   3.111 +
   3.112 +<h2>$(gettext "Login")</h2>
   3.113 +
   3.114 +<div id="account-info">
   3.115 +$(gettext "Not yet and account ? Please signup using SliTaz Bugs formular
   3.116 +from your SliTaz system. <p>Tip: to attach big files or images, you can use
   3.117 +SliTaz Paste service:") <a href="http://paste.slitaz.org/">paste.slitaz.org</a>
   3.118 +</p>
   3.119 +</div>
   3.120 +
   3.121 +<div id="login">
   3.122 +	<form method="post" action="$SCRIPT_NAME">
   3.123 +		<table>
   3.124 +			<tbody>
   3.125 +				<tr>
   3.126 +					<td>$(gettext "User name")</td>
   3.127 +					<td><input type="text" name="auth" /></td>
   3.128 +				</tr>
   3.129 +				<tr>
   3.130 +					<td>$(gettext "Password")</td>
   3.131 +					<td><input type="password" name="pass" /></td>
   3.132 +				</tr>
   3.133 +				<tr>
   3.134 +					<td><input type="submit" value="$(gettext "Login")" /></td>
   3.135 +					<td>$error </td>
   3.136 +				</tr>
   3.137 +			</tbody>
   3.138 +		</table>
   3.139 +	</form>
   3.140 +</div>
   3.141 +
   3.142 +<div style="clear: both;"></div>
   3.143 +EOT
   3.144 +}
   3.145 +
   3.146 +# Display user public profile.
   3.147 +public_people() {
   3.148 +	cat << EOT
   3.149 +<pre>
   3.150 +Real name : $NAME
   3.151 +</pre>
   3.152 +EOT
   3.153 +}
   3.154 +
   3.155 +# Display authentified user profile. TODO: change password
   3.156 +auth_people() {
   3.157 +	cat << EOT
   3.158 +<pre>
   3.159 +Real name  : $NAME
   3.160 +Email      : $MAIL
   3.161 +Secure key : $KEY
   3.162 +</pre>
   3.163 +EOT
   3.164 +}
   3.165 +
   3.166 +# Usage: list_bugs STATUS
   3.167 +list_bugs() {
   3.168 +	echo "<h3>$1 Bugs</h3>"
   3.169 +	for pr in critical standard
   3.170 +	do
   3.171 +		for bug in $(fgrep -H "$1" $bugdir/*/bug.conf | cut -d ":" -f 1)
   3.172 +		do
   3.173 +			. $bug
   3.174 +			id=$(dirname $bug | cut -d "/" -f 2)
   3.175 +			if [ "$PRIORITY" == "$pr" ]; then
   3.176 +				cat << EOT
   3.177 +<pre>
   3.178 +Bug title  : <strong>$BUG</strong>
   3.179 +ID - Date  : $id - $DATE
   3.180 +Creator    : <a href="?user=$CREATOR">$CREATOR</a> - \
   3.181 +<a href="?id=$id">Show Bug</a>
   3.182 +</pre>
   3.183 +EOT
   3.184 +			fi
   3.185 +		done
   3.186 +	done
   3.187 +}
   3.188 +
   3.189 +# Stripped down Wiki parser for bug desc and messages wich are simply
   3.190 +# displyed in <pre>
   3.191 +wiki_parser() {
   3.192 +	sed \
   3.193 +		-e s"#http://\([^']*\).png#<img src='\0' alt='[ Image ]' />#"g \
   3.194 +		-e s"#http://\([^']*\).*# <a href='\0'>\1</a>#"g
   3.195 +}
   3.196 +
   3.197 +# Bug page
   3.198 +bug_page() {
   3.199 +	if [ -f "$PEOPLE/$CREATOR/slitaz.conf" ]; then
   3.200 +		. $PEOPLE/$CREATOR/slitaz.conf
   3.201 +	else
   3.202 +		MAIL="defaul"
   3.203 +	fi
   3.204 +	cat << EOT
   3.205 +<h2>Bug $id</h2>
   3.206 +<form method="get" action="./">
   3.207 +
   3.208 +<p>
   3.209 +	$(get_gravatar $MAIL 32) <strong>$STATUS</strong> $BUG - $DATE - Priority $PRIORITY
   3.210 +	- $msgs messages
   3.211 +</p>
   3.212 +
   3.213 +<pre>
   3.214 +$(echo "$DESC" | wiki_parser)
   3.215 +</pre>
   3.216 +
   3.217 +<div id="tools">
   3.218 +EOT
   3.219 +	if check_auth; then
   3.220 +		if [ "$STATUS" == "OPEN" ]; then
   3.221 +			cat << EOT 
   3.222 +<a href="?id=$id&amp;close">$(gettext "Close bug")</a>
   3.223 +<a href="?edit=$id">$(gettext "Edit bug")</a>
   3.224 +EOT
   3.225 +		else
   3.226 +			cat << EOT
   3.227 +<a href="?id=$id&amp;open">$(gettext "Re open bug")</a>
   3.228 +EOT
   3.229 +		fi
   3.230 +	fi
   3.231 +	cat << EOT
   3.232 +</div>
   3.233 +
   3.234 +<h3>$(gettext "Messages")</h3>
   3.235 +EOT
   3.236 +	[ "$msgs" == "0" ] && gettext "No messages"
   3.237 +	for msg in $(ls -1tr $bugdir/$id/msg.*)
   3.238 +	do
   3.239 +		. $msg
   3.240 +		if [ "$MSG" ]; then
   3.241 +			msgid=$(echo $msg | cut -d "." -f 2)
   3.242 +			del=""
   3.243 +			# User can delete his post.
   3.244 +			[ "$user" == "$USER" ] && \
   3.245 +				del="<a href=\"?id=$id&amp;delmsg=$msgid\">delete</a>"
   3.246 +			cat << EOT
   3.247 +<p><strong>$USER</strong> $DATE $del</p>
   3.248 +<pre>
   3.249 +$(echo "$MSG" | wiki_parser)
   3.250 +</pre>
   3.251 +EOT
   3.252 +		fi
   3.253 +		unset NAME DATE MSG
   3.254 +	done
   3.255 +	if check_auth; then
   3.256 +		cat << EOT
   3.257 +<div>
   3.258 +	<h3>$(gettext "New message")</h3>
   3.259 +	
   3.260 +		<input type="hidden" name="id" value="$id" />
   3.261 +		<textarea name="msg" rows="8"></textarea>
   3.262 +		<p><input type="submit" value="$(gettext "Send message")" /></p>
   3.263 +	</form>
   3.264 +</div>
   3.265 +EOT
   3.266 +	fi
   3.267 +}
   3.268 +
   3.269 +# Write a new message
   3.270 +new_msg() {
   3.271 +	date=$(date "+%Y-%m-%d %H:%M")
   3.272 +	msgs=$(ls -1 $bugdir/$id/msg.* | wc -l)
   3.273 +	count=$(($msgs + 1))
   3.274 +	if check_auth; then
   3.275 +		USER="$user"
   3.276 +	fi
   3.277 +	sed "s/$(echo -en '\r') /\n/g" > $bugdir/$id/msg.$count << EOT
   3.278 +USER="$USER"
   3.279 +DATE="$date"
   3.280 +MSG="$(GET msg)"
   3.281 +EOT
   3.282 +}
   3.283 +
   3.284 +# Create a new Bug
   3.285 +new_bug() {
   3.286 +	count=$(ls -1 $bugdir | wc -l)
   3.287 +	date=$(date "+%Y-%m-%d %H:%M")
   3.288 +	# Sanity check, JS may be disabled.
   3.289 +	[ ! "$(GET bug)" ] && echo "Missing bug title" && exit 1
   3.290 +	[ ! "$(GET desc)" ] && echo "Missing bug description" && exit 1
   3.291 +	if check_auth; then
   3.292 +		USER="$user"
   3.293 +	fi
   3.294 +	mkdir -p $bugdir/$count
   3.295 +	sed "s/$(echo -en '\r') /\n/g" > $bugdir/$count/bug.conf << EOT
   3.296 +# SliTaz Bug configuration
   3.297 +
   3.298 +BUG="$(GET bug)"
   3.299 +STATUS="OPEN"
   3.300 +PRIORITY="$(GET priority)"
   3.301 +CREATOR="$USER"
   3.302 +DATE="$date"
   3.303 +PKGS="$(GET pkgs)"
   3.304 +
   3.305 +DESC="$(GET desc)"
   3.306 +EOT
   3.307 +}
   3.308 +
   3.309 +# New bug page for the web interface
   3.310 +new_bug_page() {
   3.311 +	cat << EOT
   3.312 +<h2>$(gettext "New Bug")</h2>
   3.313 +<div id="newbug">
   3.314 +
   3.315 +<form method="get" action="./" onsubmit="return checkNewBug();">
   3.316 +	<input type="hidden" name="addbug" />
   3.317 +	<table>
   3.318 +		<tbody>
   3.319 +			<tr>
   3.320 +				<td>$(gettext "Bug title")*</td>
   3.321 +				<td><input type="text" name="bug" /></td>
   3.322 +			</tr>
   3.323 +			<tr>
   3.324 +				<td>$(gettext "Description")*</td>
   3.325 +				<td><textarea name="desc"></textarea></td>
   3.326 +			</tr>
   3.327 +			<tr>
   3.328 +				<td>$(gettext "Packages")</td>
   3.329 +				<td><input type="text" name="pkgs" /></td>
   3.330 +			</tr>
   3.331 +			<tr>
   3.332 +				<td>$(gettext "Priority")</td>
   3.333 +				<td>
   3.334 +					<select name="priority">
   3.335 +						<option value="standard">$(gettext "Standard")</option>
   3.336 +						<option value="critical">$(gettext "Critical")</option>
   3.337 +					</select>
   3.338 +					<input type="submit" value="$(gettext "Create Bug")" />
   3.339 +				</td>
   3.340 +			</tr>
   3.341 +		</tbody>
   3.342 +	</table>
   3.343 +</form>
   3.344 +
   3.345 +<p>
   3.346 +$(gettext "* filed is obligatory. You can also specify affected packages.")
   3.347 +</p>
   3.348 +
   3.349 +</div>
   3.350 +EOT
   3.351 +}
   3.352 +
   3.353 +# Edit/Save a bug configuration file
   3.354 +edit_bug() {
   3.355 +	cat << EOT
   3.356 +<h2>$(gettext "Edit Bug $bug")</h2>
   3.357 +<div id="edit">
   3.358 +
   3.359 +<form method="get" action="./">
   3.360 +	<textarea name="bugconf">$(cat $bugdir/$bug/bug.conf)</textarea>
   3.361 +	<input type="hidden" name="bug" value="$bug" />
   3.362 +	<input type="submit" value="$(gettext "Save configuration")" />
   3.363 +</form>
   3.364 +
   3.365 +</div>
   3.366 +EOT
   3.367 +}
   3.368 +
   3.369 +save_bug() {
   3.370 +	bug="$(GET bug)"
   3.371 +	content="$(GET bugconf)"
   3.372 +	sed "s/$(echo -en '\r') /\n/g" > $bugdir/$bug/bug.conf << EOT
   3.373 +$content
   3.374 +EOT
   3.375 +}
   3.376 +
   3.377 +# Close a fixed bug
   3.378 +close_bug() {
   3.379 +	sed -i s'/OPEN/CLOSED/' $bugdir/$id/bug.conf
   3.380 +}
   3.381 +
   3.382 +# Re open an old bug
   3.383 +open_bug() {
   3.384 +	sed -i s'/CLOSED/OPEN/' $bugdir/$id/bug.conf
   3.385 +}
   3.386 +
   3.387 +# Get and display Gravatar image: get_gravatar email size
   3.388 +# Link to profile: <a href="http://www.gravatar.com/$md5">...</a>
   3.389 +get_gravatar() {
   3.390 +	email=$1
   3.391 +	size=$2
   3.392 +	[ "$size" ] || size=48
   3.393 +	url="http://www.gravatar.com/avatar"
   3.394 +	md5=$(echo -n $email | md5sum | cut -d " " -f 1)
   3.395 +	echo "<img src='$url/$md5?d=identicon&s=$size' alt='' />"
   3.396 +}
   3.397 +
   3.398 +# Create a new user
   3.399 +new_user_config() {
   3.400 +	mail="$(GET mail)"
   3.401 +	pass="$(GET pass)"
   3.402 +	key=$(echo -n "$user:$mail:$pass" | md5sum | awk '{print $1}')
   3.403 +	echo "$user:$pass" >> $AUTH_FILE
   3.404 +	mkdir -p $PEOPLE/$user/
   3.405 +	cat > $PEOPLE/$user/slitaz.conf << EOT
   3.406 +# SliTaz user configuration
   3.407 +#
   3.408 +
   3.409 +NAME="$(GET name)"
   3.410 +USER="$user"
   3.411 +MAIL="$mail"
   3.412 +KEY="$key"
   3.413 +
   3.414 +COMMUNITY="$(GET scn)"
   3.415 +LOCATION="$(GET location)"
   3.416 +RELEASES="$(GET releases)"
   3.417 +PACKAGES="$(GET packages)"
   3.418 +EOT
   3.419 +	chmod 0600 $PEOPLE/$user/slitaz.conf
   3.420 +}
   3.421 +
   3.422 +#
   3.423 +# POST actions
   3.424 +#
   3.425 +
   3.426 +case " $(POST) " in
   3.427 +	*\ auth\ *)
   3.428 +		# Authenticate user. Create a session file in $sessions to be used
   3.429 +		# by check_auth. We have the user login name and a peer session
   3.430 +		# md5 string in the COOKIE.
   3.431 +		user="$(POST auth)"
   3.432 +		pass="$(crypt_pass "$(POST pass)")"
   3.433 +		valid=$(fgrep "${user}:" $AUTH_FILE | cut -d ":" -f 2)
   3.434 +		if [ "$pass" == "$valid" ] && [ "$pass" != "" ]; then
   3.435 +			md5session=$(echo -n "$$:$user:$pass:$$" | md5sum | awk '{print $1}')
   3.436 +			mkdir -p $sessions
   3.437 +			echo "$md5session" > $sessions/$user
   3.438 +			header "Location: $WEB_URL" \
   3.439 +				"Set-Cookie: auth=$user:$md5session; HttpOnly"
   3.440 +		else
   3.441 +			header "Location: $WEB_URL?login&error"
   3.442 +		fi ;;
   3.443 +esac
   3.444 +
   3.445 +#
   3.446 +# GET actions
   3.447 +#
   3.448 +
   3.449 +case " $(GET) " in
   3.450 +	*\ README\ *)
   3.451 +		header
   3.452 +		html_header
   3.453 +		user_box
   3.454 +		echo '<h2>README</h2>'
   3.455 +		echo '<pre>'
   3.456 +		cat /usr/share/doc/tazbug/README
   3.457 +		echo '</pre>' 
   3.458 +		html_footer ;;
   3.459 +	*\ closed\ *)
   3.460 +		# Show all closed bugs.
   3.461 +		header
   3.462 +		html_header
   3.463 +		user_box
   3.464 +		list_bugs CLOSED
   3.465 +		html_footer ;;
   3.466 +	*\ login\ *)
   3.467 +		# The login page
   3.468 +		[ "$(GET error)" ] && \
   3.469 +			error="<span class="error">$(gettext "Bad login or pass")</span>"
   3.470 +		header 
   3.471 +		html_header
   3.472 +		login_page 
   3.473 +		html_footer ;;
   3.474 +	*\ logout\ *)
   3.475 +		# Set a Cookie in the past to logout.
   3.476 +		expires="Expires=Wed, 01-Jan-1980 00:00:00 GMT"
   3.477 +		if check_auth; then
   3.478 +			rm -f "$sessions/$user"
   3.479 +			header "Location: $WEB_URL" "Set-Cookie: auth=none; $expires; HttpOnly"
   3.480 +		fi ;;
   3.481 +	*\ user\ *)
   3.482 +		# User profile
   3.483 +		header
   3.484 +		html_header
   3.485 +		user_box
   3.486 +		. $PEOPLE/"$(GET user)"/slitaz.conf
   3.487 +		echo "<h2>$(get_gravatar $MAIL) $(GET user)</h2>"
   3.488 +		if check_auth && [ "$(GET user)" == "$user" ]; then
   3.489 +			auth_people
   3.490 +		else
   3.491 +			public_people
   3.492 +		fi
   3.493 +		html_footer ;;
   3.494 +	*\ newbug\ *)
   3.495 +		# Add a bug from web interface.
   3.496 +		header
   3.497 +		html_header
   3.498 +		user_box
   3.499 +		if check_auth; then
   3.500 +			new_bug_page
   3.501 +		else
   3.502 +			echo "<p>$(gettext "You must be logged to post a new bug")</p>"
   3.503 +		fi
   3.504 +		html_footer ;;
   3.505 +	*\ addbug\ *)
   3.506 +		# Add a bug from web interface.
   3.507 +		if check_auth; then
   3.508 +			new_bug
   3.509 +			header "Location: $WEB_URL?id=$count"
   3.510 +		fi ;;
   3.511 +	*\ edit\ *)
   3.512 +		bug="$(GET edit)"
   3.513 +		header
   3.514 +		html_header
   3.515 +		user_box
   3.516 +		edit_bug
   3.517 +		html_footer ;;
   3.518 +	*\ bugconf\ *)
   3.519 +		if check_auth; then
   3.520 +			save_bug
   3.521 +			header "Location: $WEB_URL?id=$bug"
   3.522 +		fi ;;
   3.523 +	*\ id\ *)
   3.524 +		# Empty deleted messages to keep msg count working.
   3.525 +		id="$(GET id)"
   3.526 +		[ "$(GET close)" ] && close_bug
   3.527 +		[ "$(GET open)" ] && open_bug
   3.528 +		[ "$(GET msg)" ] && new_msg
   3.529 +		[ "$(GET delmsg)" ] && rm -f $bugdir/$id/msg.$(GET delmsg) && \
   3.530 +			touch $bugdir/$id/msg.$(GET delmsg)
   3.531 +		msgs=$(fgrep MSG= $bugdir/$id/msg.* | wc -l)
   3.532 +		header 
   3.533 +		html_header
   3.534 +		user_box 
   3.535 +		. $bugdir/$id/bug.conf
   3.536 +		bug_page
   3.537 +		html_footer ;;
   3.538 +	*\ signup\ *)
   3.539 +		# Signup
   3.540 +		header "Content-type: text/plain;"
   3.541 +		user="$(GET signup)"
   3.542 +		echo "Requested user login : $user"
   3.543 +		if fgrep -q "$user:" $AUTH_FILE; then
   3.544 +			echo "ERROR: User already exist" && exit 1
   3.545 +		else
   3.546 +			echo "Creating account for : $(GET name)"
   3.547 +			new_user_config 
   3.548 +		fi ;;
   3.549 +	*\ key\ *)
   3.550 +		# Let user post new bug or message with crypted key (no gettext)
   3.551 +		#
   3.552 +		# Testing only and is security acceptable ?
   3.553 +		#
   3.554 +		key="$(GET key)"
   3.555 +		id="$(GET bug)"
   3.556 +		header "Content-type: text/plain;"
   3.557 +		echo "Checking secure key..." 
   3.558 +		if fgrep -qH $key $PEOPLE/*/slitaz.conf; then
   3.559 +			conf=$(fgrep -H $key $PEOPLE/*/slitaz.conf | cut -d ":" -f 1)
   3.560 +			. $conf
   3.561 +			echo "Authentified: $NAME ($USER)"
   3.562 +			case " $(GET) " in
   3.563 +				*\ msg\ *)
   3.564 +					[ ! "$id" ] && echo "Missing bug ID" && exit 0
   3.565 +					echo "Posting new message to bug: $id"
   3.566 +					echo "Message: $(GET msg)"
   3.567 +					new_msg ;;
   3.568 +				*\ bug\ *)
   3.569 +					echo "Adding new bug: $(GET bug)" 
   3.570 +					echo "Description: $(GET desc)" 
   3.571 +					new_bug ;;
   3.572 +			esac 
   3.573 +		else
   3.574 +			echo "Not a valid SliTaz user key"
   3.575 +			exit 0
   3.576 +		fi ;;
   3.577 +	*\ search\ *)
   3.578 +		header
   3.579 +		html_header
   3.580 +		user_box
   3.581 +		cat << EOT
   3.582 +<h2>$(gettext "Search")</h2>
   3.583 +<form method="get" action="./">
   3.584 +	<input type="text" name="search" />
   3.585 +	<input type="submit" value="$(gettext "Search")" />
   3.586 +</form>
   3.587 +<pre>
   3.588 +EOT
   3.589 +		IFS="/"
   3.590 +		grep -i -H $(GET search) $bugdir/*/* | while read bug id file
   3.591 +		do
   3.592 +			echo -n "<a href='?id=$id'>Bug</a> $id : " 
   3.593 +			echo $file | cut -d : -f 2 | \
   3.594 +				sed s"/$(GET search)/<span class='ok'>$(GET search)<\/span>/"g
   3.595 +		done
   3.596 +		unset IFS
   3.597 +		echo '</pre>' 
   3.598 +		html_footer ;;
   3.599 +	*)
   3.600 +		# Default page.
   3.601 +		bugs=$(ls -1 $bugdir | wc -l)
   3.602 +		close=$(fgrep "CLOSED" $bugdir/*/bug.conf | wc -l)
   3.603 +		fixme=$(fgrep "OPEN" $bugdir/*/bug.conf | wc -l)
   3.604 +		msgs=$(find $bugdir -name msg.* ! -size 0 | wc -l)
   3.605 +		pct=0
   3.606 +		[ $bugs -gt 0 ] && pct=$(( ($close * 100) / $bugs ))
   3.607 +		header
   3.608 +		html_header
   3.609 +		user_box
   3.610 +		cat << EOT
   3.611 +
   3.612 +<h2>$(gettext "Summary")</h2>
   3.613 +
   3.614 +<p>
   3.615 +	Bugs: $bugs in total - $close fixed - $fixme to fix - $msgs messages
   3.616 +</p>
   3.617 +
   3.618 +<div class="pctbar">
   3.619 +	<div class="pct" style="width: ${pct}%;">${pct}%</div>
   3.620 +</div>
   3.621 +
   3.622 +<p>
   3.623 +	Beta code! Please read the <a href="?README">README</a> for more 
   3.624 +	information. 
   3.625 +</p>
   3.626 +
   3.627 +<div id="tools">
   3.628 +	<a href="?closed">View closed bugs</a>
   3.629 +EOT
   3.630 +		if check_auth; then
   3.631 +			echo "<a href='?newbug'>$(gettext "Create a new bug")</a>"
   3.632 +		fi
   3.633 +		cat << EOT
   3.634 +<form method="get" action="./">
   3.635 +	<input type="text" name="search" />
   3.636 +	<input type="submit" value="$(gettext "Search")" />
   3.637 +</form>
   3.638 +</div>
   3.639 +EOT
   3.640 +		list_bugs OPEN
   3.641 +		html_footer ;;
   3.642 +esac
   3.643 +
   3.644 +exit 0
     4.1 Binary file web/favicon.ico has changed
     5.1 Binary file web/images/avatar.png has changed
     6.1 Binary file web/images/home.png has changed
     7.1 Binary file web/images/logo.png has changed
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/web/lib/functions.js	Tue Apr 03 12:12:59 2012 +0200
     8.3 @@ -0,0 +1,18 @@
     8.4 +// SliTaz Bugs Javascript functions.
     8.5 +//
     8.6 +
     8.7 +// Check form to avoid empty values and bad email.
     8.8 +function checkNewBug() {
     8.9 +	if(document.forms["addbug"]["title"].value == "")
    8.10 +    {
    8.11 +        alert("Please enter a title for the new bug");
    8.12 +        document.forms["addbug"]["title"].focus();
    8.13 +        return false;
    8.14 +    }
    8.15 +    if(document.forms["addbug"]["desc"].value == "")
    8.16 +    {
    8.17 +        alert("Please fill in the bug description");
    8.18 +        document.forms["addbug"]["desc"].focus();
    8.19 +        return false;
    8.20 +    }
    8.21 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/web/lib/header.html	Tue Apr 03 12:12:59 2012 +0200
     9.3 @@ -0,0 +1,27 @@
     9.4 +<!DOCTYPE html>
     9.5 +<html xmlns="http://www.w3.org/1999/xhtml">
     9.6 +<head>
     9.7 +	<title>SliTaz Bug Tracker</title>
     9.8 +	<meta charset="utf-8" />
     9.9 +	<link rel="shortcut icon" href="favicon.ico" />
    9.10 +	<link rel="stylesheet" type="text/css" href="style.css" />
    9.11 +	<script type="text/javascript" src="lib/functions.js"></script>
    9.12 +</head>
    9.13 +<body>
    9.14 +
    9.15 +<div id="header">
    9.16 +	<div id="logo"></div>
    9.17 +	<div id="network">
    9.18 +		<a href="http://www.slitaz.org/">
    9.19 +			<img src="images/home.png" alt="[ Home ]" /></a>
    9.20 +		<a href="http://scn.slitaz.org/">Community</a>
    9.21 +		<a href="http://doc.slitaz.org/">Doc</a>
    9.22 +		<a href="http://forum.slitaz.org/">Forum</a>
    9.23 +		<a href="http://slitaz.pro/">Pro</a>
    9.24 +		<a href="http://shop.slitaz.org/">Shop</a>
    9.25 +		<a href="http://hg.slitaz.org/">Hg</a>
    9.26 +		<a href="http://cook.slitaz.org/">Cook</a>
    9.27 +		<a href="http://roadmap.slitaz.org/">Roadmap</a>
    9.28 +	</div>
    9.29 +	<h1><a href="./">SliTaz Bugs</a></h1>
    9.30 +</div>
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/web/style.css	Tue Apr 03 12:12:59 2012 +0200
    10.3 @@ -0,0 +1,192 @@
    10.4 +/* CSS style for SliTaz Bugs */
    10.5 +
    10.6 +html { min-height: 102%; }
    10.7 +body { font: 13px sans-serif, vernada, arial; margin: 0; }
    10.8 +h1 { margin: 0; padding: 8px; color: #fff; font-size: 20px; }
    10.9 +h1 a { color: #fff; text-decoration: none; }
   10.10 +h2 { color: #444; } h3 { color: #666; font-size: 140%; }
   10.11 +a { text-decoration: underline; color: #215090; }
   10.12 +a:hover { text-decoration: none; }
   10.13 +img { border: 0pt none; vertical-align: middle; }
   10.14 +pre {
   10.15 +	overflow: auto;
   10.16 +	font-size: 96%;
   10.17 +}
   10.18 +textarea { width: 100%; }
   10.19 +
   10.20 +/* Header */
   10.21 +
   10.22 +#header {
   10.23 +	background: #351a0a;
   10.24 +	height: 40px;
   10.25 +	border-bottom: 8px solid #d66018;
   10.26 +}
   10.27 +
   10.28 +#header h1 {
   10.29 +	margin: 0;
   10.30 +	padding: 8px 0 0 42px;
   10.31 +	width: 250px;
   10.32 +}
   10.33 +
   10.34 +#header h1 a { 
   10.35 +	color: white; 
   10.36 +	text-decoration: none;
   10.37 +	font-size: 20px;
   10.38 +	font-style: italic;
   10.39 +}
   10.40 +
   10.41 +#header h1 a:hover, #network a:hover { 
   10.42 +	color: #d66018;
   10.43 +}
   10.44 +
   10.45 +/* Header links */
   10.46 +
   10.47 +#network { 
   10.48 +	float: right; 
   10.49 +	padding: 10px 5px 0; 
   10.50 +	font-size: 12px;
   10.51 +}
   10.52 +
   10.53 +#network a {
   10.54 +	padding: 0 6px;
   10.55 +	color: #fff; 
   10.56 +	font-weight: bold;
   10.57 +	text-decoration: none;
   10.58 +}
   10.59 +
   10.60 +/* Logo */
   10.61 +
   10.62 +#logo {
   10.63 +	background: url(images/logo.png) no-repeat left;
   10.64 +	position: absolute;
   10.65 +	float: left;
   10.66 +	left: 0px;
   10.67 +	top: 0px;
   10.68 +	width: 40px;
   10.69 +	height: 40px;
   10.70 +}
   10.71 +
   10.72 +/* Content */
   10.73 +
   10.74 +#content {
   10.75 +	margin: 40px auto;
   10.76 +	text-align: justify;
   10.77 +	width: 720px;
   10.78 +}
   10.79 +
   10.80 +#login {
   10.81 +	width: 280px;
   10.82 +	float: left;
   10.83 +	height: 120px;
   10.84 +}
   10.85 +
   10.86 +#login input[type="text"], #login input[type="password"],
   10.87 +#tools input[type="text"] { 
   10.88 +	width: 180px; padding: 3px; }
   10.89 +#tools input[type="submit"] { padding: 3px; }
   10.90 +#login input[type="submit"] { float: none; }
   10.91 +
   10.92 +#user {
   10.93 +	min-width: 180px;
   10.94 +	height: 20px;
   10.95 +	float: right;
   10.96 +	position: absolute;
   10.97 +	right: 20px;
   10.98 +	top: 68px;
   10.99 +}
  10.100 +#user a { padding: 0 4px; }
  10.101 +
  10.102 +#account-info { width: 380px; height: 120px; float: right; }
  10.103 +
  10.104 +#newbug textarea { width: 460px; }
  10.105 +
  10.106 +#edit textarea { width: 100%; height: 240px; }
  10.107 +
  10.108 +.box, pre, #user, #login, #account-info {
  10.109 +	background-color: #f8f8f8;
  10.110 +	border: 1px solid #ddd;
  10.111 +	padding: 10px;
  10.112 +}
  10.113 +
  10.114 +.error { color: red; }
  10.115 +.ok { color: green; }
  10.116 +
  10.117 +/* Progress bar */
  10.118 +
  10.119 +.pct { background: #9dff4a; padding: 2px 4px; }
  10.120 +
  10.121 +.pctbar {
  10.122 +	margin: 0;
  10.123 +	color: #666;
  10.124 +	background: #f1f1f1;
  10.125 +	border: 1px solid #ddd;
  10.126 +	overflow: hidden;
  10.127 +	clear: both;
  10.128 +}
  10.129 +
  10.130 +/* Form */
  10.131 +
  10.132 +form { display: inline; }
  10.133 +textarea { border: 2px solid #ccc; padding: 4px; width: 100%; }
  10.134 +select { min-width: 180px; }
  10.135 +input[type="submit"], input[type="text"], input[type="password"], 
  10.136 +select, #tools a {
  10.137 +	color: #444444;
  10.138 +	border: 1px solid #cccccc;
  10.139 +	padding: 4px;
  10.140 +	margin: 4px 0px;
  10.141 +	font-size: 14px;
  10.142 +	line-height: 1.2em;
  10.143 +	background-image: -webkit-linear-gradient(#FAFAFA, #F4F4F4 40%, #E5E5E5);
  10.144 +	background-image: -moz-linear-gradient(#FAFAFA, #F4F4F4 40%, #E5E5E5);
  10.145 +	-webkit-appearance: none;
  10.146 +	-webkit-padding-end: 12px;
  10.147 +	-webkit-padding-start: 6px;
  10.148 +}
  10.149 +
  10.150 +input[type="text"], input[type="password"] { 
  10.151 +	background: #fefefe; border: 2px solid #ccc; 
  10.152 +	width: 460px; }
  10.153 +/*input[type="file"] { border: 2px solid #ddd; }*/
  10.154 +/*input[type="checkbox"] { background: #fefefe; }*/
  10.155 +
  10.156 +/* Be compatible with old FF and Webkit version. */
  10.157 +input[type="submit"] {
  10.158 +	-webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
  10.159 +	-moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
  10.160 +	box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
  10.161 +}
  10.162 +
  10.163 +input[type="submit"]:hover, #tools a:hover { 
  10.164 +	cursor: pointer;
  10.165 +	color: black;
  10.166 +}
  10.167 +
  10.168 +select { 
  10.169 +	background-image: url(images/down.png), 
  10.170 +		-webkit-linear-gradient(#FAFAFA, #F4F4F4 40%, #E5E5E5);
  10.171 +	background-position: center right;
  10.172 +	background-repeat: no-repeat;
  10.173 +}
  10.174 +
  10.175 +#tools a { text-decoration: none; margin: 4px 6px 4px 0px; }
  10.176 +
  10.177 +/* Round corner */
  10.178 +
  10.179 +pre, .button, .pctbar, #login, #account-info, #user, img, input,
  10.180 +textarea, select, #tools a {
  10.181 +	-moz-border-radius: 4px;
  10.182 +	-webkit-border-radius: 4px;
  10.183 +	border-radius: 4px;
  10.184 +}
  10.185 +
  10.186 +/* Footer */
  10.187 +
  10.188 +#footer {
  10.189 +	text-align: center;
  10.190 +	padding: 20px;
  10.191 +	border-top: 1px solid #ddd;
  10.192 +	font-size: 90%;
  10.193 +}
  10.194 +
  10.195 +#footer a { padding: 0 2px; }