tinycm view index.cgi @ rev 48

Bunch of small fixes and improvments
author Christophe Lincoln <pankso@slitaz.org>
date Sun Jan 19 15:53:39 2014 +0100 (2014-01-19)
parents 30e39dd19525
children 6dfd1c3a2fdf
line source
1 #!/bin/sh
2 #
3 # TinyCM - Small, fast and elegent CGI/SHell Content Manager
4 #
5 # Copyright (C) 2012-2014 SliTaz GNU/Linux - BSD License
6 #
7 . /usr/lib/slitaz/httphelper
9 # Let's have a peer site config file with a .cgi extension so content
10 # is secure even if left in a web server directory.
11 . config.cgi
13 tiny="$PWD"
14 content="content"
15 wiki="$content/wiki"
16 index="index"
17 cache="cache"
18 plugins="plugins"
19 tmp="/tmp/tinycm"
20 sessions="$tmp/sessions"
21 script="$SCRIPT_NAME"
22 activity="$cache/log/activity.log"
24 # Content negotiation for Gettext
25 IFS=","
26 for lang in $HTTP_ACCEPT_LANGUAGE
27 do
28 lang=${lang%;*} lang=${lang# } lang=${lang%-*}
29 if echo "$po" | fgrep -q "$lang"; then
30 break
31 fi
32 case "$lang" in
33 en) lang="C" ;;
34 fr) lang="fr_FR" ;;
35 pt) lang="pt_BR" ;;
36 ru) lang="ru_RU" ;;
37 esac
38 done
39 unset IFS
40 export LANG=$lang LC_ALL=$lang
42 #
43 # Functions
44 #
46 # Used by edit to display language name and the language box. This is
47 # for CM content not gettext support.
48 get_lang() {
49 lang=$(echo $d | cut -d "/" -f 1)
50 doc=${d#$lang/}
51 echo '<div id="lang">'
52 for l in $LANGUAGES
53 do
54 case $lang in
55 en) i18n="English" ;;
56 fr) i18n="Français" ;;
57 pt) i18n="Português" ;;
58 ru) i18n="Русский" ;;
59 *) i18n="*" ;;
60 esac
61 echo "<a href='?d=$l/$doc'>$l</a>"
62 done
63 echo '</div>'
64 }
66 # HTML 5 header.
67 html_header() {
68 if [ -f "$tiny/lib/header.html" ]; then
69 cat $tiny/lib/header.html | sed -e s!'%TITLE%'!"$TITLE - $d"!g
70 else
71 cat << EOT
72 <!DOCTYPE html>
73 <html xmlns="http://www.w3.org/1999/xhtml">
74 <head>
75 <title>$TITLE</title>
76 <meta charset="utf-8" />
77 <style type="text/css">body { margin: 40px 120px; }</style>
78 </head>
79 <body>
80 <!-- Content -->
81 <div id="content">
82 EOT
83 fi
84 }
86 # HTML 5 footer.
87 html_footer() {
88 if [ -f "$tiny/lib/footer.html" ]; then
89 cat $tiny/lib/footer.html
90 else
91 cat << EOT
93 <!-- End content -->
94 </div>
96 <div id="footer">&hearts;</div>
98 </body>
99 </html>
100 EOT
101 fi
102 }
104 # Default index if missing
105 default_index() {
106 mkdir -p "$wiki"
107 cat > $wiki/$index.txt << EOT
108 ==== Welcome ====
110 <p>
111 This is the default index page of your TinyCM, you can login then start to
112 edit and adding some content. You can read the help about text formating
113 and functions: [Help page|en/help]
114 </p>
116 EOT
117 }
119 # Log main activity.
120 log_activity() {
121 [ -d "$cache/log" ] || mkdir -p ${cache}/log
122 #gravatar="$(get_gravatar $MAIL 24)"
123 grep ^[A-Z] | \
124 sed s"#^[A-Z]\([^']*\)#$user|$(date '+%Y-%m-%d')|\0#" \
125 >> $cache/log/activity.log
126 }
128 # Log documents activity.
129 log() {
130 grep ^[A-Z] | \
131 sed s"#^[A-Z]\([^']*\)#$(date '+%Y-%m-%d %H:%M') : \0#" \
132 >> $cache/$d/activity.log
133 }
135 # Check if user is auth
136 check_auth() {
137 auth="$(COOKIE auth)"
138 user="$(echo $auth | cut -d ":" -f 1)"
139 md5cookie="$(echo $auth | cut -d ":" -f 2)"
140 [ -f "$sessions/$user" ] && md5session="$(cat $sessions/$user)"
141 if [ "$md5cookie" == "$md5session" ] && [ "$auth" ]; then
142 . $PEOPLE/$user/account.conf
143 return 0
144 else
145 return 1
146 fi
147 }
149 # Check if user is admin
150 admin_user() {
151 fgrep -q 'ADMIN_USER="yes"' ${PEOPLE}/${user}/account.conf
152 }
154 # Authentified or not
155 user_box() {
156 if check_auth; then
157 cat << EOT
159 <div id="user">
160 <a href="$script?user=$user">$(get_gravatar $MAIL 20)</a>
161 <a href="$script?logout">Logout</a>
162 </div>
164 EOT
165 else
166 cat << EOT
168 <div id="user">
169 <a href="$script?login"><img src="images/avatar.png" alt="[ User ]" /></a>
170 <a href="$script?login">Login</a>
171 </div>
173 EOT
174 fi
175 cat << EOT
176 <!--
177 <div id="search">
178 <form method="get" action="$script">
179 <input type="text" name="search" placeholder="$(gettext "Search")" />
180 </form>
181 </div>
182 -->
183 EOT
184 }
186 # Link for online signup if enabled.
187 online_signup() {
188 if [ "$ONLINE_SIGNUP" == "yes" ]; then
189 echo -n "<p><a href='$script?signup'>"
190 gettext "Create a new account"
191 echo '</a></p>'
192 fi
193 }
195 # Login page
196 login_page() {
197 cat << EOT
198 <h2>$(gettext "Login")</h2>
200 <div id="account-info">
201 $(gettext "No account yet or trouble with you account? Please send
202 a request to $ADMIN_MAIL with your real name, user name, mail and password.")
203 $(online_signup)
204 </div>
206 <div id="login">
207 <form method="post" action="$script">
208 <input type="text" name="auth" placeholder="$(gettext "User name")" />
209 <input type="password" name="pass" placeholder="$(gettext "Password")" />
210 <div>
211 <input type="submit" value="Login" /> $error
212 </div>
213 </form>
214 </div>
216 <div style="clear: both;"></div>
217 EOT
218 }
220 # Signup page
221 signup_page() {
222 cat << EOT
224 <div id="signup">
225 <form method="post" name="signup" action="$script" onsubmit="return checkSignup();">
226 <input type="hidden" name="signup" value="new" />
227 <input type="text" name="name" placeholder="$(gettext "Real name")" />
228 <input type="text" name="user" placeholder="$(gettext "User name")" />
229 <input type="text" name="mail" placeholder="$(gettext "Email")" />
230 <input type="password" name="pass" placeholder="$(gettext "Password")" />
231 <div>
232 <input type="submit" value="$(gettext "Create new account")" />
233 </div>
234 </form>
235 </div>
237 EOT
238 }
240 # Create a new user in AUTH_FILE and PEOPLE
241 new_user_config() {
242 if [ ! -f "$AUTH_FILE" ];then
243 touch $(DESTDIR)$(LOGIN)/auth/people
244 chmod 0600 $(DESTDIR)$(LOGIN)/auth/people
245 fi
246 key=$(echo -n "$user:$mail:$pass" | md5sum | awk '{print $1}')
247 echo "$user:$pass" >> $AUTH_FILE
248 mkdir -p $PEOPLE/$user/
249 cat > $PEOPLE/$user/account.conf << EOT
250 # SliTaz user configuration
251 #
253 NAME="$name"
254 USER="$user"
255 MAIL="$mail"
256 KEY="$key"
258 EOT
259 chmod 0600 $PEOPLE/$user/account.conf
260 # First created user is admin
261 if [ $(ls ${PEOPLE} | wc -l) == "1" ]; then
262 echo 'ADMIN_USER="yes"' >> $PEOPLE/$user/account.conf
263 fi
264 }
266 # Display user public profile.
267 public_people() {
268 echo "</pre>"
269 # Display personnal user profile
270 if [ -f "$PEOPLE/$USER/profile.txt" ]; then
271 cat $PEOPLE/$USER/profile.txt | wiki_parser
272 fi
273 }
275 # Display authentified user profile. TODO: change password
276 auth_people() {
277 cat << EOT
278 Email : $MAIL
279 Secure key : $KEY
280 </pre>
281 EOT
282 # Each user can have personal profile page
283 if [ -f "$PEOPLE/$USER/profile.txt" ]; then
284 cat $PEOPLE/$USER/profile.txt | wiki_parser
285 cat << EOT
286 <div id="tools">
287 <a href="$script?edit=profile">$(gettext "Edit profile")</a>
288 </div>
289 EOT
290 else
291 cat << EOT
292 <div id="tools">
293 <a href="$script?edit=profile">$(gettext "Create a profile page")</a>
294 </div>
295 EOT
296 fi
297 }
299 # The CM style parser. Just a title, simple text formating and internal
300 # links, as well as images and use HTML for other stuff. Keep it fast!
301 # To make TinyCM as easy as possible we have a small HTML editor/helper
302 # written in Javascript
303 wiki_parser() {
304 doc="[0-9a-zA-Z\.\#/~\_%=\?\&,\+\:@;!\(\)\*\$'\-]*"
305 sed \
306 -e s"#====\([^']*\)====#<h2>\1</h2>#"g \
307 -e s"#===\([^']*\)===#<h3>\1</h3>#"g \
308 -e s"#==\([^']*\)==#<h4>\1</h4>#"g \
309 -e s"#\*\*\([^']*\)\*\*#<b>\1</b>#"g \
310 -e s"#''\([^']*\)''#<em>\1</em>#"g \
311 -e s"#__\([^']*\)__#<u>\1</u>#"g \
312 -e s"#\[\([^]]*\)|\($doc\)\]#<a href='$script?d=\2'>\1</a>#"g \
313 -e s"#\[\([^]]*\)!\($doc\)\]#<a href='\2'>\1</a>#"g \
314 -e s"#\[\(http://*[^]]*.png\)\]#<img src='\1' />#"g \
315 -e s"#\[\([^]]*.png\)\]#<img src='content/cloud/\1' />#"g
316 }
318 link_user() {
319 echo "<a href='$(basename $script)?user=$user'>$user</a>"
320 }
322 # Save a document. Do we need more than 1 backup and diff ?
323 save_document() {
324 mkdir -p $cache/$d $(dirname $wiki/$d)
325 # May be a new page.
326 if [ ! -f "$wiki/$d.txt" ]; then
327 new=0
328 touch $wiki/$d.txt
329 fi
330 cp $wiki/$d.txt $cache/$d/last.bak
331 sed "s/$(echo -en '\r') /\n/g" > $wiki/$d.txt << EOT
332 $(GET content)
333 EOT
334 diff $cache/$d/last.bak $wiki/$d.txt > $cache/$d/last.diff
335 # Log
336 if [ "$new" ]; then
337 echo "Page created by: $(link_user)" | log
338 echo "New document: <a href='$script?d=$d'>$d</a>" | log_activity
339 if [ "$HG" == "yes" ]; then
340 cd $content && hg -q add
341 hg commit -q -u "$NAME <$MAIL>" -m "Created new document: $d"
342 cd $tiny
343 fi
344 else
345 # Here we may clean log: cat && tail -n 40
346 echo "Page edited by: $(link_user)" | log
347 if [ "$HG" == "yes" ]; then
348 cd $content && hg commit -q -u "$NAME <$MAIL>" \
349 -m "Edited document: $d"
350 cd $tiny
351 fi
352 fi
353 }
355 # Save a user profile.
356 save_profile() {
357 path="$PEOPLE/$user"
358 cp -f ${path}/${d}.txt ${path}/${d}.bak
359 sed "s/$(echo -en '\r') /\n/g" > ${path}/${d}.txt << EOT
360 $(GET content)
361 EOT
362 }
364 # CM tools (edit, diff, etc).
365 wiki_tools() {
366 cat << EOT
367 <div id="tools">
368 <a href="$script?edit=$d">$(gettext "Edit document")</a>
369 <a href="$script?diff=$d">$(gettext "Last diff")</a>
370 <a href="$script?log=$d">$(gettext "File log")</a>
371 <a href="$script?dashboard">$(gettext "Dashboard")</a>
372 $([ "$HG" == "yes" ] && echo "<a href='$script?hg'>Hg Log</a>")
373 </div>
374 EOT
375 }
377 # Get and display Gravatar image: get_gravatar email size
378 # Link to profile: <a href="http://www.gravatar.com/$md5">...</a>
379 get_gravatar() {
380 email=$1
381 size=$2
382 [ "$size" ] || size=48
383 url="http://www.gravatar.com/avatar"
384 md5=$(md5crypt $email)
385 echo "<img src='$url/$md5?d=identicon&s=$size' alt='&lowast;' />"
386 }
388 # List hg logs
389 hg_log() {
390 cd $content
391 cat << EOT
392 <table>
393 <thead>
394 <td>$(gettext "User")</td>
395 <td>$(gettext "Description")</td>
396 <td>$(gettext "Revision")</td>
397 </thead>
398 EOT
399 hg log --template "<tr><td>{author}</td><td>{desc}</td><td>{rev}</td></tr>\n"
400 echo '</table>'
401 }
403 #
404 # POST actions
405 #
407 case " $(POST) " in
408 *\ auth\ *)
409 # Authenticate user. Create a session file in $sessions to be used
410 # by check_auth. We have the user login name and a peer session
411 # md5 string in the COOKIE.
412 user="$(POST auth)"
413 pass="$(md5crypt "$(POST pass)")"
414 valid=$(fgrep "${user}:" $AUTH_FILE | cut -d ":" -f 2)
415 if [ "$pass" == "$valid" ] && [ "$pass" != "" ]; then
416 md5session=$(echo -n "$$:$user:$pass:$$" | md5sum | awk '{print $1}')
417 [ -d $sessions ] || mkdir -p $sessions
418 date '+%Y-%m-%d' > ${PEOPLE}/${user}/last
419 echo "$md5session" > $sessions/$user
420 header "Location: $script" \
421 "Set-Cookie: auth=$user:$md5session; HttpOnly"
422 else
423 header "Location: $script?login&error"
424 fi ;;
425 *\ signup\ *)
426 # POST action for signup
427 name="$(POST name)"
428 user="$(POST user)"
429 mail="$(POST mail)"
430 pass="$(md5crypt "$(POST pass)")"
431 if ! grep "^${user}:" $AUTH_FILE; then
432 new_user_config
433 header "Location: $script?login"
434 else
435 header
436 html_header
437 user_box
438 echo "<h2>$(gettext 'User already exists:') $user</h2>"
439 html_footer
440 fi ;;
441 esac
443 #
444 # Plugins
445 #
446 for p in $(ls -1 $plugins)
447 do
448 [ -f "$plugins/$p/$p.conf" ] && . $plugins/$p/$p.conf
449 [ -x "$plugins/$p/$p.cgi" ] && . $plugins/$p/$p.cgi
450 done
452 #
453 # GET actions
454 #
456 case " $(GET) " in
457 *\ edit\ *)
458 d="$(GET edit)"
459 header
460 html_header
461 user_box
462 get_lang
463 if check_auth; then
464 if [ "$doc" == "profile" ]; then
465 wiki="$PEOPLE/$user"
466 fi
467 cat << EOT
468 <h2>$(gettext "Edit $doc [ $i18n ]")</h2>
470 <div id="edit">
472 <form method="get" action="$script" name="editor">
473 <input type="hidden" name="save" value="$d" />
474 <textarea name="content">$(cat "$wiki/$d.txt")</textarea>
475 <input type="submit" value="$(gettext "Save document")" />
476 $(gettext "Code Helper:")
477 $(cat lib/jseditor.html)
478 </form>
480 </div>
481 EOT
482 else
483 gettext "You must be logged in to edit pages"
484 fi
485 html_footer ;;
487 *\ save\ *)
488 d="$(GET save)"
489 if check_auth; then
490 # User profile
491 if [ "$d" == "profile" ]; then
492 save_profile
493 header "Location: $script?user=$user"
494 else
495 save_document
496 fi
497 fi
498 header "Location: $script?d=$d" ;;
500 *\ log\ *)
501 d="$(GET log)"
502 header
503 html_header
504 user_box
505 # Main activity
506 if [ "$d" == "log" ]; then
507 echo "<h2>$(gettext "Activity")</h2>"
508 if check_auth; then
509 echo "<div id='tools'>"
510 echo "<a href='$script?dashboard'>Dashboard</a>"
511 echo "</div>"
512 fi
513 echo '<pre>'
514 if [ -f "$cache/log/activity.log" ]; then
515 IFS="|"
516 tac $cache/log/activity.log | while read USER DATE LOG
517 do
518 . ${PEOPLE}/${USER}/account.conf
519 cat << EOT
520 <a href='$script?user=$USER'>$(get_gravatar $MAIL 24)</a>\
521 <span class='date'>$DATE -</span> $LOG
522 EOT
523 done
524 unset IFS
525 else
526 gettext "No activity log yet"; echo
527 fi
528 echo '</pre>'
529 html_footer && exit 0
530 fi
531 get_lang
532 echo "<h2>$(gettext "Activity for:") <a href='$script?d=$d'>$d</a></h2>"
533 echo '<pre>'
534 if [ -f "$cache/$d/activity.log" ]; then
535 tac $cache/$d/activity.log
536 else
537 gettext "No log for: $d"; echo
538 fi
539 echo '</pre>'
540 if check_auth; then
541 wiki_tools
542 fi
543 html_footer ;;
545 *\ ls\ *)
546 d="Document list"
547 header
548 html_header
549 user_box
550 echo "<h2>$(gettext "Pages list")</h2>"
551 if check_auth; then
552 echo "<div id='tools'>"
553 echo "<a href='$script?dashboard'>Dashboard</a>"
554 echo "</div>"
555 fi
556 echo '<pre>'
557 cd ${wiki}
558 for d in $(find . -type f | sed s'/.\///')
559 do
560 cat << EOT
561 <a href="$script?d=${d%.txt}">${d%.txt}</a> : \
562 <a href="$script?rm=$d">$(gettext "Remove")</a>
563 EOT
564 done
565 echo '</pre>'
566 html_footer ;;
568 *\ rm\ *)
569 [ ! check_auth ] && header "Location: Location: $script"
570 d="$(GET rm)"
571 rm ${wiki}/"${d}"
572 rm -rf ${cache}/"${d%.txt}"
573 header "Location: $script?ls" ;;
575 *\ diff\ *)
576 d="$(GET diff)"
577 date="last"
578 header
579 html_header
580 user_box
581 get_lang
582 echo "<h2>$(gettext "Diff for:") <a href='$script?d=$d'>$d</a></h2>"
583 echo '<pre>'
584 if [ -f "$cache/$d/$date.diff" ]; then
585 cat $cache/$d/$date.diff | sed \
586 -e 's|&|\&amp;|g' -e 's|<|\&lt;|g' -e 's|>|\&gt;|g' \
587 -e s"#^-\([^']*\).#<span style='color: red;'>\0</span>#"g \
588 -e s"#^+\([^']*\).#<span style='color: green;'>\0</span>#"g \
589 -e s"#@@\([^']*\)@@#<span style='color: blue;'>@@\1@@</span>#"g
590 else
591 gettext "No diff for: $d"; echo
592 fi
593 echo '</pre>'
594 if check_auth; then
595 wiki_tools
596 fi
597 html_footer ;;
599 *\ login\ *)
600 # The login page
601 d="Login"
602 [ "$(GET error)" ] && \
603 error="<p class="error">$(gettext "Bad login or pass")</p>"
604 header
605 html_header
606 user_box
607 login_page
608 html_footer ;;
610 *\ signup\ *)
611 # The login page
612 d="$(gettext "Sign Up")"
613 header
614 html_header
615 user_box
616 echo "<h2>$d</h2>"
617 if [ "$ONLINE_SIGNUP" == "yes" ]; then
618 signup_page
619 else
620 gettext "Online registration is disabled"
621 fi
622 html_footer ;;
624 *\ logout\ *)
625 # Set a Cookie in the past to logout.
626 expires="Expires=Wed, 01-Jan-1980 00:00:00 GMT"
627 if check_auth; then
628 rm -f "$sessions/$user"
629 header "Location: $script" "Set-Cookie: auth=none; $expires; HttpOnly"
630 fi ;;
632 *\ user\ *)
633 # User profile
634 d="$(GET user)"
635 last="$(cat $PEOPLE/"$(GET user)"/last)"
636 header
637 html_header
638 user_box
639 . $PEOPLE/"$(GET user)"/account.conf
640 cat << EOT
641 <h2>$(get_gravatar $MAIL) $NAME</h2>
643 <pre>
644 $(gettext "User name :") $USER
645 $(gettext "Last login :") $last
646 EOT
647 if check_auth && [ "$(GET user)" == "$user" ]; then
648 auth_people
649 else
650 # check_auth will set VARS to current logged user: re-source
651 . $PEOPLE/"$(GET user)"/account.conf
652 public_people
653 fi
654 html_footer ;;
656 *\ dashboard\ *)
657 # For now simply list plugins and users info. We could have a
658 # dashbord only for ADMINS found in the config file. The dashboard
659 # should also be a plugin.
660 d="Dashboard"
661 header
662 html_header
663 user_box
664 users=$(ls -1 $PEOPLE | wc -l)
665 docs=$(find $wiki -type f | wc -l)
666 wikisize="$(du -sh $wiki | awk '{print $1}')"
667 cachesize="$(du -sh $cache | awk '{print $1}')"
668 [ "$HG" != "yes" ] && hg=$(gettext "disabled")
669 [ "$HG" == "yes" ] && hg=$(gettext "enabled")
670 # Source all plugins.conf to get DASHBOARD_TOOLS and ADMIN_TOOLS
671 ADMIN_TOOLS=""
672 DASHBOARD_TOOLS=""
673 for p in $(ls $plugins)
674 do
675 . $plugins/$p/$p.conf
676 done
677 if check_auth && ! admin_user; then
678 ADMIN_TOOLS=""
679 fi
680 echo "<h2>$d</h2>"
681 if check_auth; then
682 cat << EOT
683 <div id="tools">
684 <a href='$script?log'>Activity log</a>
685 <a href='$script?ls'>Pages list</a>
686 $DASHBOARD_TOOLS
687 $ADMIN_TOOLS
688 </div>
690 <pre>
691 Users : $users
692 Wiki : $docs ($wikisize)
693 Cache : $cachesize
694 Mercurial : $hg
695 </pre>
696 <h3>Admin users</h3>
697 EOT
698 # Get the list of administrators
699 for u in $(ls $PEOPLE)
700 do
701 user=${u}
702 if admin_user; then
703 echo "<a href='?user=$u'>$u</a>"
704 fi
705 done
706 cat << EOT
707 <h3>$(gettext "Plugins")</h3>
708 <pre>
709 EOT
710 for p in $(ls -1 $plugins)
711 do
712 . $plugins/$p/$p.conf
713 echo "<a href='?$p'>$PLUGIN</a> - $SHORT_DESC"
714 done
715 echo '</pre>'
716 else
717 gettext "You must be logged in to view the dashboard."
718 fi
719 html_footer ;;
721 *\ hg\ *)
722 header
723 [ "$HG" != "yes" ] && gettext "Hg is disabled" && exit 0
724 [ ! -x /usr/bin/hg ] && gettext "Hg is not installed" && exit 0
725 d="Hg Log"
726 html_header
727 user_box
728 echo "<h2>$d</h2>"
729 case " $(GET hg) " in
730 *\ init\ *)
731 if check_auth; then
732 [ -d "$content/.hg" ] && exit 0
733 echo '<pre>'
734 gettext "Executing: hg init"; echo
735 cd $content/ && hg init
736 echo '[hooks]' > .hg/hgrc
737 echo 'incoming = hg update' >> .hg/hgrc
738 gettext "Adding current content and committing"; echo
739 [ ! -f "$wiki/index.txt" ] && touch $wiki/$index.txt
740 hg add && hg commit -u "$NAME <$MAIL>" \
741 -m "Initial commit with current content"
742 echo '</pre>' && cd ..
743 fi ;;
744 esac
745 hg_log
746 html_footer ;;
748 *)
749 # Display requested page
750 d="$(GET d)"
751 [ "$d" ] || d=$index
752 header
753 html_header
754 user_box
755 get_lang
756 # Generate a default index on first run
757 if [ ! -f "$wiki/$index.txt" ]; then
758 if ! default_index; then
759 echo "<pre class='error'>Directory : content/ is not writable</pre>"
760 html_footer && exit 0
761 fi
762 fi
763 # Check cache dir
764 if [ ! -w "$cache" ]; then
765 echo "<pre class='error'>Directory : cache/ is not writable"
766 echo "Command : install -m 0777 -d $tiny/cache</pre>"
767 html_footer && exit 0
768 fi
769 # Wiki document
770 if [ ! -f "$wiki/$d.txt" ]; then
771 echo "<h2>$d</h2>"
772 gettext "The document does not exist. You can create it or read the"
773 echo " <a href='?d=en/help'>help</a>"
774 else
775 if fgrep -q [NOWIKI] $wiki/$d.txt; then
776 cat $wiki/$d.txt | sed '/\[NOWIKI\]/'d
777 else
778 cat $wiki/$d.txt | wiki_parser
779 fi
780 fi
781 if check_auth; then
782 wiki_tools
783 if [ "$HG" == "yes" ] && [ ! -d "$content/.hg" ]; then
784 echo '<p class="error box">'
785 gettext "Mercurial is enabled but no repository found"
786 echo ": <a href='?hg=init'>Hg init</a>"
787 echo '</p>'
788 fi
789 fi
790 html_footer ;;
791 esac
793 exit 0