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.

123 lines
3.4KB

  1. __version__ = '0.01'
  2. from flask import Flask, g, request, session, render_template, send_file, abort
  3. import jinja2
  4. import os.path
  5. import time
  6. import config
  7. import rophako.utils
  8. app = Flask(__name__,
  9. static_url_path="/.static",
  10. )
  11. app.DEBUG = config.DEBUG
  12. app.secret_key = config.SECRET_KEY
  13. # Load all the blueprints!
  14. from rophako.modules.admin import mod as AdminModule
  15. from rophako.modules.account import mod as AccountModule
  16. from rophako.modules.blog import mod as BlogModule
  17. app.register_blueprint(AdminModule)
  18. app.register_blueprint(AccountModule)
  19. app.register_blueprint(BlogModule)
  20. # Custom Jinja handler to support custom- and default-template folders for
  21. # rendering templates.
  22. app.jinja_loader = jinja2.ChoiceLoader([
  23. jinja2.FileSystemLoader("site/www"), # Site specific.
  24. jinja2.FileSystemLoader("rophako/www"), # Default
  25. ])
  26. app.jinja_env.globals["csrf_token"] = rophako.utils.generate_csrf_token
  27. app.jinja_env.globals["include_page"] = rophako.utils.include
  28. @app.before_request
  29. def before_request():
  30. """Called before all requests. Initialize global template variables."""
  31. # CSRF protection.
  32. if request.method == "POST":
  33. token = session.pop("_csrf", None)
  34. if not token or str(token) != str(request.form.get("token")):
  35. abort(403)
  36. # Default template vars.
  37. g.info = {
  38. "time": time.time(),
  39. "app": {
  40. "name": "Rophako",
  41. "version": __version__,
  42. "author": "Noah Petherbridge",
  43. },
  44. "uri": request.path.split("/")[1:],
  45. "session": {
  46. "login": False, # Not logged in, until proven otherwise.
  47. "username": "guest",
  48. "uid": 0,
  49. "name": "Guest",
  50. "role": "user",
  51. }
  52. }
  53. # Default session vars.
  54. if not "login" in session:
  55. session.update(g.info["session"])
  56. # Refresh their login status from the DB.
  57. if session["login"]:
  58. import rophako.model.user as User
  59. if not User.exists(uid=session["uid"]):
  60. # Weird! Log them out.
  61. from rophako.modules.account import logout
  62. logout()
  63. return
  64. db = User.get_user(uid=session["uid"])
  65. session["username"] = db["username"]
  66. session["name"] = db["name"]
  67. session["role"] = db["role"]
  68. # Copy session params into g.info. The only people who should touch the
  69. # session are the login/out pages.
  70. for key in session:
  71. g.info["session"][key] = session[key]
  72. @app.context_processor
  73. def after_request():
  74. """Called just before render_template. Inject g.info into the template vars."""
  75. return g.info
  76. @app.route("/<path:path>")
  77. def catchall(path):
  78. """The catch-all path handler. If it exists in the www folders, it's sent,
  79. otherwise we give the 404 error page."""
  80. # Search for this file.
  81. for root in ["site/www", "rophako/www"]:
  82. abspath = os.path.abspath("{}/{}".format(root, path))
  83. if os.path.isfile(abspath):
  84. return send_file(abspath)
  85. elif not "." in path and os.path.isfile(abspath + ".html"):
  86. return rophako.utils.template(path + ".html")
  87. return not_found("404")
  88. @app.route("/")
  89. def index():
  90. return catchall("index")
  91. @app.errorhandler(404)
  92. def not_found(error):
  93. print "NOT FOUND"
  94. return render_template('errors/404.html', **g.info), 404
  95. # Domain specific endpoints.
  96. if config.SITE_NAME == "kirsle.net":
  97. import rophako.modules.kirsle_legacy