index.cgi 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #!/bin/sh
  2. #
  3. # Business Layer - the "Controller" of our MVC.
  4. # v1.0
  5. # index.cgi
  6. #
  7. # PLEASE, DO NOT EDIT THESE VARIABLES. If you need to make a change, do so in
  8. # the following config files:
  9. # - wiki.conf
  10. # - templates.conf
  11. #
  12. # USEFUL RESOURCES IN THIS DEVELOPMENT:
  13. # http://paulturner.me/2009/07/reading-http-post-data-using-bash/
  14. # http://www.ffnn.nl/pages/articles/linux/cgi-scripting-tips-for-bash-or-sh.php
  15. #
  16. # TODO: Implement a translating engine to get plain text from the DB and
  17. # compile it into pretty markup, markdown-style.
  18. #
  19. #---- Preprocessor variables ----#
  20. title="Nothing"
  21. content="Nothing yet"
  22. command=$(echo "$QUERY_STRING" | cut -d "&" -f 1 | cut -d "=" -f 1)
  23. argument=$(echo "$QUERY_STRING" | cut -d "&" -f 1 | cut -d "=" -f 2)
  24. editable=""
  25. # a show for the home page
  26. home_cont="
  27. <p>
  28. Welcome to <strong>MyWiki</strong>, the simple wiki. Search for, create
  29. and edit your pages at will!
  30. </p>
  31. <p>
  32. If you need help, <a href=\"http://sonokisworld.appspot.com/contact\">
  33. get in touch with me</a>. I am yet to implement proper documentation here.
  34. But, most importantly, HAVE FUN!
  35. </p>"
  36. help_cont="
  37. <p>
  38. <strong>MyWiki</strong> is a ready-to-deploy, out-of-the-box wiki engine
  39. for Unix servers that requires little to no configuration.
  40. </p>
  41. <p>
  42. To create a new wiki page, click <strong>Create a new page</strong> in the
  43. menu. The page editor allows only for plain text (no hyperlinks or other
  44. formatting) to be used, but paragraphs are separated by inserting two
  45. consecutive line breaks. Hopefully, future releases of MyWiki will include
  46. a simple plain text to html interpreter similar to
  47. <a href=\"http://daringfireball.net/projects/markdown/\">MarkDown</a> so
  48. that the possibilities are expanded, images included.
  49. </p>
  50. <p>
  51. Note that you can edit any page that you have created (not including these
  52. predefined ones) by clicking <strong>Edit this page</strong> on the top
  53. right corner of an existing page.
  54. </p>
  55. "
  56. # boilerplate to create new pages:
  57. # UPDATE: now a function!
  58. # 1 ) The title of the page (empty if new)
  59. # 2 ) The content of the page (empty if new)
  60. # 3 ) The tag <input type="hidden" name="update" value="true" /> (empty if new)
  61. # 4 ) The pid of the page (empty if new)
  62. create_cont() {
  63. echo "
  64. <form action=\"index.cgi\" method=\"post\">
  65. <label for=\"newtitle\">Page title:</label><br />
  66. <input type=\"text\" name=\"newtitle\" value=\""$1"\" /><br />
  67. <label for=\"newcontent\">Page content:</label><br />
  68. <textarea name=\"newcontent\" rows=\"80\" cols=\"40\">"$2"</textarea><br />
  69. <input type=\"submit\" value=\"Create page\" />
  70. $3<input type=\"hidden\" name=\"pid\" value=\"$4\" />
  71. </form>"
  72. }
  73. # Routine to report errors:
  74. show_error() {
  75. # pass an explanation of the error as the first argument.
  76. echo "Status: 500"
  77. echo "Content-Type: text/html"
  78. echo ""
  79. echo "<h1>500 - INTERNALSERVER ERROR</h1>"
  80. echo "<p>The innards of the system suffered an error.
  81. Don't worry, though, it wasn't your fault.</p>"
  82. echo "<p>The most probable cause of the error is this: $1</p>"
  83. echo "<p>Please try again. If this problem persists, get in touch
  84. with the administrator.</p>"
  85. exit
  86. }
  87. # URL string decoder:
  88. unescape() {
  89. # take an input string as the only argument to store it in the base.
  90. # HINT: the newlines appear like this:
  91. # %0D%0A %0D%0A
  92. # These, for the sake of our CMS-ish wiki system, will need to be converted
  93. # into <p> tags, that is, at FETCH time, not storage time!
  94. # TODO: allow for some Unicode characters?
  95. echo "$1" | sed s/^/\<p\>/ |
  96. sed s#$\#\</p\>#g |
  97. sed s/%22/"\&quot\;"/g |
  98. sed s/%21/\!/g |
  99. sed s/%2C/,/g |
  100. sed s/%27/"\&#39\;"/g |
  101. sed s/%28/\(/g |
  102. sed s/%3F/\?/g |
  103. sed s/%29/\)/g |
  104. tr "+" " " |
  105. sed s/%3C/"\&lt\;"/g |
  106. sed s/%3E/"\&gt\;"/g |
  107. sed s@%2F@/@g |
  108. sed s@%0D%0A%0D%0A@\</p\>\<p\>@g
  109. }
  110. # A proper searching mechanism
  111. search() {
  112. # arguments: [search string]
  113. final="<ul>\n"
  114. ids=$(sqlite3 index.db "SELECT id FROM main WHERE content LIKE '%$1%'")
  115. if [ -z "$ids" ]; then
  116. final=$final"Sorry, no results found."
  117. else
  118. for result in $ids
  119. do
  120. result_t=$(sqlite3 index.db "SELECT title FROM main WHERE id=$result")
  121. final=$final"<li><a href=\"index.cgi?p=$result\">""$result_t""</a></li>\n"
  122. done
  123. fi
  124. final="$final</ul>"
  125. echo -e "$final"
  126. }
  127. # Debug for post string format; pass the postdata as the first argument.
  128. post_debug() {
  129. echo "Content-Type: text/html; charset=utf-8"
  130. echo ""
  131. echo "<h1>Diagnostics for POST string</h1>
  132. <p>You entered the following query string as POST:</p>
  133. <p>
  134. <pre>$1</pre>
  135. </p>
  136. <p>
  137. Diagnostics end here.
  138. </p>"
  139. exit
  140. }
  141. #---- Logical flow ----#
  142. if [ "$REQUEST_METHOD" == "GET" ]; then
  143. # Either serve a page or search for one.
  144. case "$command" in
  145. "p" )
  146. title=$(sqlite3 index.db "SELECT title FROM main WHERE id=$argument")
  147. content=$(sqlite3 index.db "SELECT content FROM main WHERE id=$argument")
  148. editable="<a style=\"float: right\" href=\"index.cgi?edit=$argument\">Edit this page</a>"
  149. ;;
  150. "search" )
  151. argument=$(echo "$argument" | tr "+" " ")
  152. title="Search results for \"$argument\""
  153. content=$(search "$argument")
  154. ;;
  155. "create" )
  156. title="Create a new page:"
  157. content=$(create_cont)
  158. ;;
  159. "all" )
  160. title="All pages in this wiki"
  161. content=$(search)
  162. ;;
  163. "about" )
  164. title="About MyWiki"
  165. content="$help_cont"
  166. ;;
  167. "edit" )
  168. title="Now editing \"$(sqlite3 index.db "SELECT title FROM main WHERE id=$argument")\""
  169. content=$(create_cont "$(sqlite3 index.db "SELECT title FROM main WHERE id=$argument")" "$(sqlite3 index.db "SELECT content FROM main WHERE id=$argument")" "<input type=\"hidden\" name=\"update\" value=\"true\" />" $argument)
  170. ;;
  171. * ) # Serve the home page.
  172. title="MyWiki Home"
  173. content="$home_cont"
  174. ;;
  175. esac
  176. else if [ "$REQUEST_METHOD" == "POST" ]; then
  177. # NOTE: the query string for post goes like this:
  178. # newtitle=this+is+an+example+title&newcontent=Here+goes+some+content
  179. if [ "$CONTENT_LENGTH" -gt 0 ]; then
  180. read -n $CONTENT_LENGTH postdata <& 0
  181. fi
  182. title=$(echo $postdata | cut -d "&" -f 1 | cut -d "=" -f 2 | tr "+" " ")
  183. content=$(echo $postdata | cut -d "&" -f 2 | cut -d "=" -f 2)
  184. editing=$(echo $postdata | cut -d "&" -f 3 | cut -d "=" -f 2)
  185. argument=$(echo $postdata | cut -d "&" -f 4 | cut -d "=" -f 2)
  186. content=$(unescape "$content")
  187. #post_debug "$argument"
  188. # Hey, the folder that contains 'index.db' must also be owned by the www
  189. # user, otherwise a clash of permissions ensues!
  190. if [ "$editing" == "true" ]; then
  191. sqlite3 index.db "UPDATE main SET title = \"$title\", content = \"$content\" WHERE id=$argument" || show_error "$argument"
  192. else
  193. sqlite3 index.db "INSERT INTO main (title, content) VALUES ('$title', \"$content\")" ||
  194. show_error "permission error"
  195. fi
  196. # Load the brand-new page!
  197. argument=$(sqlite3 index.db "SELECT id FROM main WHERE title = '$title'")
  198. title=$(sqlite3 index.db "SELECT title FROM main WHERE id=$argument")
  199. content=$(sqlite3 index.db "SELECT content FROM main WHERE id=$argument")
  200. editable="<a style=\"float: right\" href=\"index.cgi?edit=$argument\">Edit this page</a>"
  201. fi
  202. fi
  203. #---- Set the HTTP Headers ----#
  204. echo "Status: 200 OK"
  205. echo "Content-Language: en"
  206. echo "Content-Type: text/html; charset=UTF-8"
  207. echo ""
  208. #---- Serve the content ----#
  209. cat <<EOF
  210. <!DOCTYPE html>
  211. <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  212. <head>
  213. <title>$title - MyWiki</title>
  214. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  215. <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
  216. <link rel="stylesheet" type="text/css" href="style.css" />
  217. </head>
  218. <body>
  219. <header>
  220. <h1>MyWiki - the simple wiki</h1>
  221. <nav>
  222. <div class="menutrigger">Menu</div>
  223. <ul>
  224. <li><a href="index.cgi">Home</a></li>
  225. <li><a href="index.cgi?all">All pages</a></li>
  226. <li><a href="index.cgi?about=about">About</a></li>
  227. <li><a href="index.cgi?about=help">Help</a></li>
  228. <li><a href="index.cgi?create=new">Create a new page</a></li>
  229. <li><a href="javascript:void(0)" class="search" >Search</a></li>
  230. <li class="search">
  231. <form action="index.cgi" method="GET">
  232. <input type="text" name="search" placeholder="search MyWiki" />
  233. <input type="submit" value="search" />
  234. </form>
  235. </li>
  236. </ul>
  237. </nav>
  238. </header>
  239. <section id="content">
  240. $editable
  241. <h2>$title</h2>
  242. $content
  243. </section>
  244. <footer>
  245. <p>
  246. Made with <a href="https://notabug.org/kzimmermann/MyWiki">MyWiki, the Simple Wiki</a> - Est. 2014
  247. </p>
  248. </footer>
  249. <script type="text/javascript" src="main.js"></script>
  250. </body>
  251. </html>
  252. EOF