docx.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. from flask import Blueprint, render_template, abort, redirect, url_for, flash, make_response
  2. from flask_wtf import FlaskForm
  3. from flask_login import login_required, current_user
  4. from wtforms import TextAreaField, StringField, SelectMultipleField, SubmitField
  5. from wtforms.validators import DataRequired
  6. import app
  7. from sql.base import DBBit
  8. from object.blog import BlogArticle, load_blog_by_id
  9. from object.comment import Comment
  10. from object.archive import load_archive_by_id, Archive
  11. docx = Blueprint("docx", __name__)
  12. class WriteBlogForm(FlaskForm):
  13. title = StringField("标题", validators=[DataRequired()])
  14. subtitle = StringField("副标题", validators=[DataRequired()])
  15. archive = SelectMultipleField("归档", coerce=int)
  16. context = TextAreaField("博客内容", validators=[DataRequired()])
  17. submit = SubmitField("提交博客")
  18. def __init__(self, **kwargs):
  19. super().__init__(**kwargs)
  20. self.context.data = "# Blog Title\n## Blog subtitle\nHello, World"
  21. archive = Archive.get_archive_list()
  22. self.archive.choices = [(-1, "None")] + [(i[0], f"{i[1]} ({i[3]})") for i in archive]
  23. class WriteCommentForm(FlaskForm):
  24. context = TextAreaField(validators=[DataRequired()])
  25. submit = SubmitField("评论")
  26. @docx.route('/<int:page>')
  27. def docx_page(page: int = 1):
  28. if page < 1:
  29. app.HBlogFlask.print_user_opt_fail_log(f"Load docx list with error page({page})")
  30. abort(404)
  31. return
  32. blog_list = BlogArticle.get_blog_list(limit=20, offset=(page - 1) * 20)
  33. max_page = app.HBlogFlask.get_max_page(BlogArticle.get_blog_count(), 20)
  34. page_list = app.HBlogFlask.get_page("docx.docx_page", page, max_page)
  35. app.HBlogFlask.print_load_page_log(f"docx list (page: {page})")
  36. return render_template("docx/docx.html",
  37. blog_list=blog_list,
  38. is_top=DBBit.BIT_1,
  39. page_list=page_list,
  40. form=WriteBlogForm(),
  41. show_delete=current_user.check_role("DeleteBlog"))
  42. @docx.route('/<int:archive>/<int:page>')
  43. def archive_page(archive: int, page: int = 1):
  44. if page < 1:
  45. app.HBlogFlask.print_user_opt_fail_log(f"Load archive-docx list with error page({page}) archive: {archive}")
  46. abort(404)
  47. return
  48. blog_list = BlogArticle.get_blog_list(archive_id=archive, limit=20, offset=(page - 1) * 20)
  49. max_page = app.HBlogFlask.get_max_page(BlogArticle.get_blog_count(archive_id=archive), 20)
  50. page_list = app.HBlogFlask.get_page("docx.archive_page", page, max_page)
  51. app.HBlogFlask.print_load_page_log(f"archive-docx list (archive-id: {archive} page: {page})")
  52. return render_template("docx/docx.html",
  53. blog_list=blog_list,
  54. is_top=DBBit.BIT_1,
  55. page_list=page_list,
  56. form=None)
  57. @docx.route('/article/<int:blog_id>')
  58. def article_page(blog_id: int):
  59. article = load_blog_by_id(blog_id)
  60. if article is None:
  61. app.HBlogFlask.print_user_opt_fail_log(f"Load article with error id({blog_id})")
  62. abort(404)
  63. return
  64. app.HBlogFlask.print_load_page_log(f"article (id: {blog_id})")
  65. return render_template("docx/article.html",
  66. article=article,
  67. archive_list=article.archive,
  68. form=WriteCommentForm(),
  69. show_delete=current_user.check_role("DeleteComment"),
  70. show_email=current_user.check_role("ReadUserInfo"))
  71. @docx.route('/down/<int:blog_id>')
  72. def article_down_page(blog_id: int):
  73. article = load_blog_by_id(blog_id)
  74. if article is None:
  75. app.HBlogFlask.print_user_opt_fail_log(f"Download article with error id({blog_id})")
  76. abort(404)
  77. return
  78. response = make_response(article.context)
  79. response.headers["Content-Disposition"] = f"attachment;filename={article.title.encode().decode('latin-1')}.md"
  80. app.HBlogFlask.print_load_page_log(f"download article (id: {blog_id})")
  81. return response
  82. @docx.route('/comment/<int:blog>', methods=["POST"])
  83. @login_required
  84. @app.form_required(WriteCommentForm, "write comment")
  85. @app.role_required("WriteComment", "write comment")
  86. def comment_page(blog: int, form: WriteCommentForm):
  87. context = form.context.data
  88. if Comment(None, blog, current_user, context).create():
  89. app.HBlogFlask.print_user_opt_success_log("comment")
  90. flash("评论成功")
  91. else:
  92. app.HBlogFlask.print_user_opt_error_log("comment")
  93. flash("评论失败")
  94. return redirect(url_for("docx.article_page", blog_id=blog))
  95. @docx.route('/create-docx', methods=["POST"])
  96. @login_required
  97. @app.form_required(WriteBlogForm, "write blog")
  98. @app.role_required("WriteBlog", "write blog")
  99. def create_docx_page(form: WriteBlogForm):
  100. title = form.title.data
  101. if len(title) > 10:
  102. flash("标题太长了")
  103. abort(400)
  104. subtitle = form.subtitle.data
  105. if len(subtitle) > 10:
  106. flash("副标题太长了")
  107. abort(400)
  108. archive = []
  109. if -1 not in form.archive.data:
  110. for i in form.archive.data:
  111. i = load_archive_by_id(i)
  112. if i is not None:
  113. archive.append(i)
  114. if BlogArticle(None, current_user, title, subtitle, form.context.data, archive=archive).create():
  115. app.HBlogFlask.print_sys_opt_success_log("write blog")
  116. flash(f"博客 {title} 发表成功")
  117. else:
  118. app.HBlogFlask.print_sys_opt_fail_log("write blog")
  119. flash(f"博客 {title} 发表失败")
  120. return redirect(url_for("docx.docx_page", page=1))
  121. @docx.route("delete/<int:blog_id>")
  122. @login_required
  123. @app.role_required("DeleteBlog", "delete blog")
  124. def delete_blog_page(blog_id: int):
  125. if BlogArticle(blog_id, None, None, None, None).delete():
  126. app.HBlogFlask.print_sys_opt_success_log("delete blog")
  127. flash("博文删除成功")
  128. else:
  129. app.HBlogFlask.print_sys_opt_fail_log("delete blog")
  130. flash("博文删除失败")
  131. return redirect(url_for("docx.docx_page", page=1))
  132. @docx.route("delete_comment/<int:comment_id>")
  133. @login_required
  134. @app.role_required("DeleteComment", "delete comment")
  135. def delete_comment_page(comment_id: int):
  136. if Comment(comment_id, None, None, None).delete():
  137. app.HBlogFlask.print_sys_opt_success_log("delete comment")
  138. flash("博文评论成功")
  139. else:
  140. app.HBlogFlask.print_sys_opt_fail_log("delete comment")
  141. flash("博文评论失败")
  142. return redirect(url_for("docx.docx_page", page=1))
  143. @docx.context_processor
  144. def inject_base():
  145. return {"top_nav": ["", "", "active", "", "", ""]}