A Python content management system designed for kirsle.net featuring a blog, comments and photo albums. https://rophako.kirsle.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

__init__.py 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. # -*- coding: utf-8 -*-
  2. from __future__ import unicode_literals, absolute_import
  3. """Endpoints for the wiki."""
  4. from flask import Blueprint, g, request, redirect, url_for, flash
  5. import rophako.model.user as User
  6. import rophako.model.wiki as Wiki
  7. import rophako.model.emoticons as Emoticons
  8. from rophako.utils import template, pretty_time, render_markdown, login_required
  9. from rophako.settings import Config
  10. mod = Blueprint("wiki", __name__, url_prefix="/wiki")
  11. @mod.route("/")
  12. def index():
  13. """Wiki index. Redirects to the default page from the config."""
  14. default = Wiki.name_to_url(Config.wiki.default_page)
  15. return redirect(url_for("wiki.view_page", name=default))
  16. @mod.route("/_pages")
  17. def list_pages():
  18. """Wiki page list."""
  19. g.info["pages"] = [
  20. {"name": name, "link": Wiki.name_to_url(name)} \
  21. for name in Wiki.list_pages()
  22. ]
  23. return template("wiki/list.html")
  24. @mod.route("/<path:name>")
  25. def view_page(name):
  26. """Show a specific wiki page."""
  27. link = name
  28. name = Wiki.url_to_name(name)
  29. g.info["link"] = link
  30. g.info["title"] = name
  31. # Look up the page.
  32. page = Wiki.get_page(name)
  33. if not page:
  34. # Page doesn't exist... yet!
  35. g.info["title"] = Wiki.url_to_name(name)
  36. return template("wiki/missing.html"), 404
  37. # Which revision to show?
  38. version = request.args.get("revision", None)
  39. if version:
  40. # Find this one.
  41. rev = None
  42. for item in page["revisions"]:
  43. if item["id"] == version:
  44. rev = item
  45. break
  46. if rev is None:
  47. flash("That revision was not found for this page.")
  48. rev = page["revisions"][0]
  49. else:
  50. # Show the latest one.
  51. rev = page["revisions"][0]
  52. # Getting the plain text source?
  53. if request.args.get("source", None):
  54. g.info["markdown"] = render_markdown("\n".join([
  55. "# Source: {}".format(name),
  56. "",
  57. "```markdown",
  58. rev["body"],
  59. "```"
  60. ]))
  61. return template("markdown.inc.html")
  62. # Render it!
  63. g.info["rendered_body"] = Wiki.render_page(rev["body"])
  64. g.info["rendered_body"] = Emoticons.render(g.info["rendered_body"])
  65. g.info["pretty_time"] = pretty_time(Config.wiki.time_format, rev["time"])
  66. # Author info
  67. g.info["author"] = User.get_user(uid=rev["author"])
  68. return template("wiki/page.html")
  69. @mod.route("/<path:name>/_revisions")
  70. def history(name):
  71. """Page history."""
  72. name = Wiki.url_to_name(name)
  73. # Look up the page.
  74. page = Wiki.get_page(name)
  75. if not page:
  76. flash("Wiki page not found.")
  77. return redirect(url_for(".index"))
  78. authors = dict()
  79. history = list()
  80. for rev in page["revisions"]:
  81. uid = rev["author"]
  82. if not uid in authors:
  83. authors[uid] = User.get_user(uid=uid)
  84. history.append(dict(
  85. id=rev["id"],
  86. author=authors[uid],
  87. note=rev["note"],
  88. pretty_time=pretty_time(Config.wiki.time_format, rev["time"]),
  89. ))
  90. g.info["link"] = Wiki.name_to_url(name)
  91. g.info["title"] = name
  92. g.info["history"] = history
  93. return template("wiki/history.html")
  94. @mod.route("/_edit", methods=["GET", "POST"])
  95. @login_required
  96. def edit():
  97. """Wiki page editor."""
  98. title = request.args.get("name", "")
  99. body = ""
  100. history = True # Update History box is always checked by default
  101. note = request.args.get("note", "")
  102. # Editing an existing page?
  103. page = Wiki.get_page(title)
  104. if page:
  105. head = page["revisions"][0]
  106. body = head["body"]
  107. if request.method == "POST":
  108. # Submitting the form.
  109. action = request.form.get("action", "preview")
  110. title = request.form.get("name", "")
  111. body = request.form.get("body", "")
  112. history = request.form.get("history", "false") == "true"
  113. note = request.form.get("note", "")
  114. if action == "preview":
  115. # Just previewing it.
  116. g.info["preview"] = True
  117. # Render markdown
  118. g.info["rendered_body"] = Wiki.render_page(body)
  119. # Render emoticons.
  120. g.info["rendered_body"] = Emoticons.render(g.info["rendered_body"])
  121. elif action == "publish":
  122. # Publishing! Validate inputs.
  123. invalid = False
  124. if len(title) == 0:
  125. invalid = True
  126. flash("You must have a page title.")
  127. if len(body) == 0:
  128. invalid = True
  129. flash("You must have a page body.")
  130. if not invalid:
  131. # Update the page.
  132. Wiki.edit_page(
  133. author=g.info["session"]["uid"],
  134. name=title,
  135. body=body,
  136. note=note,
  137. history=history,
  138. )
  139. return redirect(url_for("wiki.view_page",
  140. name=Wiki.name_to_url(title)
  141. ))
  142. g.info["title"] = title
  143. g.info["body"] = body
  144. g.info["note"] = note
  145. g.info["history"] = history
  146. return template("wiki/edit.html")
  147. @mod.route("/_delete_history/<path:name>/<revision>", methods=["GET", "POST"])
  148. @login_required
  149. def delete_revision(name, revision):
  150. """Delete a wiki page revision from history."""
  151. link = name
  152. name = Wiki.url_to_name(name)
  153. if request.method == "POST":
  154. Wiki.delete_history(name, revision)
  155. flash("Revision deleted.")
  156. return redirect(url_for("wiki.view_page", name=Wiki.name_to_url(name)))
  157. g.info["confirm_url"] = url_for("wiki.delete_revision", name=link, revision=revision)
  158. g.info["title"] = name
  159. g.info["type"] = "revision"
  160. return template("wiki/delete.html")
  161. @mod.route("/_delete_page/<path:name>", methods=["GET", "POST"])
  162. @login_required
  163. def delete_page(name):
  164. """Delete a wiki page entirely."""
  165. link = name
  166. name = Wiki.url_to_name(name)
  167. if request.method == "POST":
  168. Wiki.delete_page(name)
  169. flash("Page completely deleted.")
  170. return redirect(url_for("wiki.index"))
  171. g.info["confirm_url"] = url_for("wiki.delete_page", name=link)
  172. g.info["title"] = name
  173. g.info["type"] = "page"
  174. return template("wiki/delete.html")