tinycm view index.cgi @ rev 52

Improved added some functions
author Christophe Lincoln <pankso@slitaz.org>
date Fri Jan 24 23:08:48 2014 +0100 (2014-01-24)
parents c4a472d0a45e
children 190b9ba3af06
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) for auth users
365 wiki_tools() {
366 if check_auth; then
367 cat << EOT
368 <div id="tools">
369 <a href="$script?edit=$d">$(gettext "Edit document")</a>
370 <a href="$script?diff=$d">$(gettext "Last diff")</a>
371 <a href="$script?log=$d">$(gettext "File log")</a>
372 <a href='$script?dashboard'>$(gettext 'Dashboard')</a>
373 EOT
374 [ "$HG" == "yes" ] && echo "<a href='$script?hg'>Hg Log</a>"
375 echo "</div>"
376 fi
377 }
379 # Built-in Dashboard tools and ADMIN_TOOLS from plugins
380 dashboard_tools() {
381 if check_auth; then
382 cat << EOT
383 <div id='tools'>
384 <a href='$script?log'>Activity log</a>
385 <a href='$script?ls'>Pages list</a>
386 <a href='$script?dashboard'>Dashboard</a>
387 </div>
388 EOT
389 fi
390 }
392 # Get and display Gravatar image: get_gravatar email size
393 # Link to profile: <a href="http://www.gravatar.com/$md5">...</a>
394 get_gravatar() {
395 email=$1
396 size=$2
397 [ "$size" ] || size=48
398 url="http://www.gravatar.com/avatar"
399 md5=$(md5crypt $email)
400 echo "<img src='$url/$md5?d=identicon&s=$size' alt='&lowast;' />"
401 }
403 # List hg logs
404 hg_log() {
405 cd $content
406 cat << EOT
407 <table>
408 <thead>
409 <td>$(gettext "User")</td>
410 <td>$(gettext "Description")</td>
411 <td>$(gettext "Revision")</td>
412 </thead>
413 EOT
414 hg log --template "<tr><td>{author}</td><td>{desc}</td><td>{rev}</td></tr>\n"
415 echo '</table>'
416 }
418 #
419 # POST actions
420 #
422 case " $(POST) " in
423 *\ auth\ *)
424 # Authenticate user. Create a session file in $sessions to be used
425 # by check_auth. We have the user login name and a peer session
426 # md5 string in the COOKIE.
427 user="$(POST auth)"
428 pass="$(md5crypt "$(POST pass)")"
429 valid=$(fgrep "${user}:" $AUTH_FILE | cut -d ":" -f 2)
430 if [ "$pass" == "$valid" ] && [ "$pass" != "" ]; then
431 md5session=$(echo -n "$$:$user:$pass:$$" | md5sum | awk '{print $1}')
432 [ -d $sessions ] || mkdir -p $sessions
433 date '+%Y-%m-%d' > ${PEOPLE}/${user}/last
434 echo "$md5session" > $sessions/$user
435 header "Location: $script" \
436 "Set-Cookie: auth=$user:$md5session; HttpOnly"
437 else
438 header "Location: $script?login&error"
439 fi ;;
440 *\ signup\ *)
441 # POST action for signup
442 name="$(POST name)"
443 user="$(POST user)"
444 mail="$(POST mail)"
445 pass="$(md5crypt "$(POST pass)")"
446 if ! grep "^${user}:" $AUTH_FILE; then
447 new_user_config
448 header "Location: $script?login"
449 else
450 header
451 html_header
452 user_box
453 echo "<h2>$(gettext 'User already exists:') $user</h2>"
454 html_footer
455 fi ;;
456 esac
458 #
459 # Plugins
460 #
461 for p in $(ls -1 $plugins)
462 do
463 [ -f "$plugins/$p/$p.conf" ] && . $plugins/$p/$p.conf
464 [ -x "$plugins/$p/$p.cgi" ] && . $plugins/$p/$p.cgi
465 done
467 #
468 # GET actions
469 #
471 case " $(GET) " in
472 *\ edit\ *)
473 d="$(GET edit)"
474 header
475 html_header
476 user_box
477 get_lang
478 if check_auth; then
479 if [ "$doc" == "profile" ]; then
480 wiki="$PEOPLE/$user"
481 fi
482 cat << EOT
483 <h2>$(gettext "Edit $doc [ $i18n ]")</h2>
485 <div id="edit">
487 <form method="get" action="$script" name="editor">
488 <input type="hidden" name="save" value="$d" />
489 <textarea name="content">$(cat "$wiki/$d.txt")</textarea>
490 <input type="submit" value="$(gettext "Save document")" />
491 $(gettext "Code Helper:")
492 $(cat lib/jseditor.html)
493 </form>
495 </div>
496 EOT
497 else
498 gettext "You must be logged in to edit pages"
499 fi
500 html_footer ;;
502 *\ save\ *)
503 d="$(GET save)"
504 if check_auth; then
505 # User profile
506 if [ "$d" == "profile" ]; then
507 save_profile
508 header "Location: $script?user=$user"
509 else
510 save_document
511 fi
512 fi
513 header "Location: $script?d=$d" ;;
515 *\ log\ *)
516 d="$(GET log)"
517 header
518 html_header
519 user_box
520 # Main activity
521 if [ "$d" == "log" ]; then
522 dashboard_tools
523 echo "<h2>$(gettext "Activity log")</h2>"
524 echo '<pre>'
525 if [ -f "$cache/log/activity.log" ]; then
526 IFS="|"
527 tac $cache/log/activity.log | while read USER DATE LOG
528 do
529 . ${PEOPLE}/${USER}/account.conf
530 cat << EOT
531 <a href='$script?user=$USER'>$(get_gravatar $MAIL 24)</a>\
532 <span class='date'>$DATE -</span> $LOG
533 EOT
534 done
535 unset IFS
536 else
537 gettext "No activity log yet"; echo
538 fi
539 echo '</pre>'
540 html_footer && exit 0
541 fi
542 # Document activity
543 get_lang
544 wiki_tools
545 echo "<h2>$(gettext "Activity for:") <a href='$script?d=$d'>$d</a></h2>"
546 echo '<pre>'
547 if [ -f "$cache/$d/activity.log" ]; then
548 tac $cache/$d/activity.log
549 else
550 gettext "No log for: $d"; echo
551 fi
552 echo '</pre>'
553 html_footer ;;
555 *\ ls\ *)
556 d="Document list"
557 header
558 html_header
559 user_box
560 dashboard_tools
561 echo "<h2>$(gettext "Pages list")</h2>"
562 echo '<pre>'
563 cd ${wiki}
564 for d in $(find . -type f | sed s'/.\///')
565 do
566 cat << EOT
567 <a href="$script?d=${d%.txt}">${d%.txt}</a> : \
568 <a href="$script?rm=$d">$(gettext "Remove")</a> || \
569 <a href="$script?edit=$d">$(gettext "Edit")</a>
570 EOT
571 done
572 echo '</pre>'
573 html_footer ;;
575 *\ rm\ *)
576 [ ! check_auth ] && header "Location: Location: $script"
577 d="$(GET rm)"
578 rm ${wiki}/"${d}"
579 rm -rf ${cache}/"${d%.txt}"
580 header "Location: $script?ls" ;;
582 *\ diff\ *)
583 d="$(GET diff)"
584 date="last"
585 header
586 html_header
587 user_box
588 get_lang
589 wiki_tools
590 echo "<h2>$(gettext "Diff for:") <a href='$script?d=$d'>$d</a></h2>"
591 echo '<pre>'
592 if [ -f "$cache/$d/$date.diff" ]; then
593 cat $cache/$d/$date.diff | sed \
594 -e 's|&|\&amp;|g' -e 's|<|\&lt;|g' -e 's|>|\&gt;|g' \
595 -e s"#^-\([^']*\).#<span style='color: red;'>\0</span>#"g \
596 -e s"#^+\([^']*\).#<span style='color: green;'>\0</span>#"g \
597 -e s"#@@\([^']*\)@@#<span style='color: blue;'>@@\1@@</span>#"g
598 else
599 gettext "No diff for: $d"; echo
600 fi
601 echo '</pre>'
602 html_footer ;;
604 *\ login\ *)
605 # The login page
606 d="Login"
607 [ "$(GET error)" ] && \
608 error="<p class="error">$(gettext "Bad login or pass")</p>"
609 header
610 html_header
611 user_box
612 login_page
613 html_footer ;;
615 *\ signup\ *)
616 # The login page
617 d="$(gettext "Sign Up")"
618 header
619 html_header
620 user_box
621 echo "<h2>$d</h2>"
622 if [ "$ONLINE_SIGNUP" == "yes" ]; then
623 signup_page
624 else
625 gettext "Online registration is disabled"
626 fi
627 html_footer ;;
629 *\ logout\ *)
630 # Set a Cookie in the past to logout.
631 expires="Expires=Wed, 01-Jan-1980 00:00:00 GMT"
632 if check_auth; then
633 rm -f "$sessions/$user"
634 header "Location: $script" "Set-Cookie: auth=none; $expires; HttpOnly"
635 fi ;;
637 *\ user\ *)
638 # User profile
639 d="$(GET user)"
640 last="$(cat $PEOPLE/"$(GET user)"/last)"
641 header
642 html_header
643 user_box
644 . $PEOPLE/"$(GET user)"/account.conf
645 cat << EOT
646 <h2>$(get_gravatar $MAIL) $NAME</h2>
648 <pre>
649 $(gettext "User name :") $USER
650 $(gettext "Last login :") $last
651 EOT
652 if check_auth && [ "$(GET user)" == "$user" ]; then
653 auth_people
654 else
655 # check_auth will set VARS to current logged user: re-source
656 . $PEOPLE/"$(GET user)"/account.conf
657 public_people
658 fi
659 html_footer ;;
661 *\ dashboard\ *)
662 # For now simply list plugins and users info. We could have a
663 # dashbord only for ADMINS found in the config file. The dashboard
664 # should also be a plugin.
665 d="Dashboard"
666 header
667 html_header
668 user_box
669 users=$(ls -1 $PEOPLE | wc -l)
670 docs=$(find $wiki -type f | wc -l)
671 wikisize="$(du -sh $wiki | awk '{print $1}')"
672 cachesize="$(du -sh $cache | awk '{print $1}')"
673 [ "$HG" != "yes" ] && hg=$(gettext "disabled")
674 [ "$HG" == "yes" ] && hg=$(gettext "enabled")
675 # Source all plugins.conf to get DASHBOARD_TOOLS and ADMIN_TOOLS
676 ADMIN_TOOLS=""
677 DASHBOARD_TOOLS=""
678 for p in $(ls $plugins)
679 do
680 . $plugins/$p/$p.conf
681 done
682 if check_auth && ! admin_user; then
683 ADMIN_TOOLS=""
684 fi
685 if check_auth; then
686 cat << EOT
687 <div id="tools">
688 <a href='$script?log'>Activity log</a>
689 <a href='$script?ls'>Pages list</a>
690 $DASHBOARD_TOOLS
691 $ADMIN_TOOLS
692 </div>
694 <h2>$d</h2>
696 <pre>
697 Users : $users
698 Wiki : $docs ($wikisize)
699 Cache : $cachesize
700 Mercurial : $hg
701 </pre>
702 <h3>Admin users</h3>
703 EOT
704 # Get the list of administrators
705 for u in $(ls $PEOPLE)
706 do
707 user=${u}
708 if admin_user; then
709 echo "<a href='?user=$u'>$u</a>"
710 fi
711 done
712 cat << EOT
713 <h3>$(gettext "Plugins")</h3>
714 <pre>
715 EOT
716 for p in $(ls -1 $plugins)
717 do
718 . $plugins/$p/$p.conf
719 echo "<a href='?$p'>$PLUGIN</a> - $SHORT_DESC"
720 done
721 echo '</pre>'
722 else
723 gettext "You must be logged in to view the dashboard."
724 fi
725 html_footer ;;
727 *\ hg\ *)
728 header
729 [ "$HG" != "yes" ] && gettext "Hg is disabled" && exit 0
730 [ ! -x /usr/bin/hg ] && gettext "Hg is not installed" && exit 0
731 d="Hg Log"
732 html_header
733 user_box
734 echo "<h2>$d</h2>"
735 case " $(GET hg) " in
736 *\ init\ *)
737 if check_auth; then
738 [ -d "$content/.hg" ] && exit 0
739 echo '<pre>'
740 gettext "Executing: hg init"; echo
741 cd $content/ && hg init
742 echo '[hooks]' > .hg/hgrc
743 echo 'incoming = hg update' >> .hg/hgrc
744 gettext "Adding current content and committing"; echo
745 [ ! -f "$wiki/index.txt" ] && touch $wiki/$index.txt
746 hg add && hg commit -u "$NAME <$MAIL>" \
747 -m "Initial commit with current content"
748 echo '</pre>' && cd ..
749 fi ;;
750 esac
751 hg_log
752 html_footer ;;
754 *)
755 # Display requested page
756 d="$(GET d)"
757 [ "$d" ] || d=$index
758 header
759 html_header
760 user_box
761 get_lang
763 # Generate a default index on first run
764 if [ ! -f "$wiki/$index.txt" ]; then
765 if ! default_index; then
766 echo "<pre class='error'>Directory : content/ is not writable</pre>"
767 html_footer && exit 0
768 fi
769 fi
771 # Check cache dir
772 if [ ! -w "$cache" ]; then
773 echo "<pre class='error'>Directory : cache/ is not writable"
774 echo "Command : install -m 0777 -d $tiny/cache</pre>"
775 html_footer && exit 0
776 fi
778 # Wiki tools and Hg warning if enable but not initiated
779 if [ "$HG" == "yes" ] && [ ! -d "$content/.hg" ]; then
780 echo '<p class="error box">'
781 gettext "Mercurial is enabled but no repository found"
782 echo ": <a href='?hg=init'>Hg init</a>"
783 echo '</p>'
784 fi
786 # Wiki tools
787 wiki_tools
789 # Wiki document
790 if [ ! -f "$wiki/$d.txt" ]; then
791 echo "<h2>$d</h2>"
792 gettext "The document does not exist. You can create it or read the"
793 echo " <a href='?d=en/help'>help</a>"
794 else
795 if fgrep -q [NOWIKI] $wiki/$d.txt; then
796 cat $wiki/$d.txt | sed '/\[NOWIKI\]/'d
797 else
798 cat $wiki/$d.txt | wiki_parser
799 fi
800 fi
801 html_footer ;;
802 esac
804 exit 0