views.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # **************************************************************************
  4. # Copyright © 2016 jianglin
  5. # File Name: views.py
  6. # Author: jianglin
  7. # Email: xiyang0807@gmail.com
  8. # Created: 2016-12-15 22:07:39 (CST)
  9. # Last Update:星期三 2017-3-29 21:18:33 (CST)
  10. # By:
  11. # Description:
  12. # **************************************************************************
  13. from flask import Markup, redirect, render_template, request, url_for
  14. from flask_babelex import gettext as _
  15. from flask_login import current_user, login_required
  16. from flask_maple.auth.forms import form_validate
  17. from flask_maple.response import HTTPResponse
  18. from forums.api.forms import (CollectForm, ReplyForm, TopicForm,
  19. collect_error_callback, error_callback,
  20. form_board)
  21. from forums.api.forums.models import Board
  22. from forums.api.tag.models import Tags
  23. from forums.common.serializer import Serializer
  24. from forums.common.utils import gen_filter_dict, gen_order_by
  25. from forums.common.views import BaseMethodView as MethodView
  26. from forums.common.views import IsAuthMethodView, IsConfirmedMethodView
  27. from forums.filters import safe_markdown
  28. from .models import Reply, Topic
  29. from .permissions import (like_permission, reply_list_permission,
  30. reply_permission, topic_list_permission,
  31. topic_permission)
  32. class TopicAskView(IsConfirmedMethodView):
  33. def get(self):
  34. boardId = request.args.get('boardId', type=int)
  35. form = form_board()
  36. if boardId is not None:
  37. form.category.data = boardId
  38. data = {'title': _('Ask - '), 'form': form}
  39. return render_template('topic/ask.html', **data)
  40. class TopicEditView(IsConfirmedMethodView):
  41. def get(self, topicId):
  42. topic = Topic.query.filter_by(id=topicId).first_or_404()
  43. form = form_board()
  44. form.title.data = topic.title
  45. form.category.data = topic.board_id
  46. form.tags.data = ','.join([tag.name for tag in topic.tags])
  47. form.content.data = topic.content
  48. data = {'title': _('Edit -'), 'form': form, 'topic': topic}
  49. return render_template('topic/edit.html', **data)
  50. class TopicPreviewView(IsConfirmedMethodView):
  51. @login_required
  52. def post(self):
  53. post_data = request.data
  54. content_type = post_data.pop('content_type', None)
  55. content = post_data.pop('content', None)
  56. if content_type == Topic.CONTENT_TYPE_MARKDOWN:
  57. return safe_markdown(content)
  58. return content
  59. class TopicListView(MethodView):
  60. decorators = (topic_list_permission, )
  61. def get(self):
  62. query_dict = request.data
  63. page, number = self.page_info
  64. keys = ['title']
  65. order_by = gen_order_by(query_dict, keys)
  66. filter_dict = gen_filter_dict(query_dict, keys)
  67. if request.path.endswith('good'):
  68. filter_dict.update(is_good=True)
  69. elif request.path.endswith('top'):
  70. filter_dict.update(is_top=True)
  71. topics = Topic.query.filter_by(
  72. **filter_dict).order_by(*order_by).paginate(page, number, True)
  73. return render_template('topic/topic_list.html', topics=topics)
  74. @form_validate(form_board, error=error_callback, f='')
  75. def post(self):
  76. user = request.user
  77. form = form_board()
  78. post_data = form.data
  79. title = post_data.pop('title', None)
  80. content = post_data.pop('content', None)
  81. tags = post_data.pop('tags', None)
  82. content_type = post_data.pop('content_type', None)
  83. board = post_data.pop('category', None)
  84. topic = Topic(
  85. title=title,
  86. content=content,
  87. content_type=content_type,
  88. board_id=int(board))
  89. tags = tags.split(',')
  90. topic_tags = []
  91. for tag in tags:
  92. topic_tag = Tags.query.filter_by(name=tag).first()
  93. if topic_tag is None:
  94. topic_tag = Tags(name=tag, description=tag)
  95. topic_tag.save()
  96. topic_tags.append(topic_tag)
  97. topic.tags = topic_tags
  98. topic.author = user
  99. topic.save()
  100. return redirect(url_for('topic.topic', topicId=topic.id))
  101. class TopicView(MethodView):
  102. per_page = 10
  103. decorators = (topic_permission, )
  104. def get(self, topicId):
  105. form = ReplyForm()
  106. query_dict = request.data
  107. topic = Topic.query.filter_by(id=topicId).first_or_404()
  108. page, number = self.page_info
  109. keys = ['title']
  110. order_by = gen_order_by(query_dict, keys)
  111. filter_dict = gen_filter_dict(query_dict, keys)
  112. replies = topic.replies.filter_by(
  113. **filter_dict).order_by(*order_by).paginate(page, number, True)
  114. data = {
  115. 'title': topic.title,
  116. 'form': form,
  117. 'topic': topic,
  118. 'replies': replies
  119. }
  120. return render_template('topic/topic.html', **data)
  121. # def put(self, topicId):
  122. # post_data = request.data
  123. # topic = Topic.query.filter_by(id=topicId).first_or_404()
  124. # title = post_data.pop('title', None)
  125. # content = post_data.pop('content', None)
  126. # content_type = post_data.pop('content_type', None)
  127. # board = post_data.pop('board', None)
  128. # if title is not None:
  129. # topic.title = title
  130. # if content is not None:
  131. # topic.content = content
  132. # if content_type is not None:
  133. # topic.content_type = content_type
  134. # if board is not None:
  135. # topic.board = int(board)
  136. # topic.save()
  137. # return redirect(url_for('topic.topic', topicId=topic.id))
  138. class ReplyListView(MethodView):
  139. decorators = (reply_list_permission, )
  140. @form_validate(ReplyForm, error=error_callback, f='')
  141. def post(self, topicId):
  142. topic = Topic.query.filter_by(id=topicId).first_or_404()
  143. post_data = request.data
  144. user = request.user
  145. content = post_data.pop('content', None)
  146. reply = Reply(content=content, topic_id=topic.id)
  147. reply.author = user
  148. reply.save()
  149. return redirect(url_for('topic.topic', topicId=topic.id))
  150. class ReplyView(MethodView):
  151. decorators = (reply_permission, )
  152. def put(self, replyId):
  153. post_data = request.data
  154. reply = Reply.query.filter_by(id=replyId).first()
  155. content = post_data.pop('content', None)
  156. if content is not None:
  157. reply.content = content
  158. reply.save()
  159. serializer = Serializer(reply, many=False)
  160. return HTTPResponse(HTTPResponse.NORMAL_STATUS,
  161. **serializer.data).to_response()
  162. def delete(self, replyId):
  163. reply = Reply.query.filter_by(id=replyId).first()
  164. reply.delete()
  165. serializer = Serializer(reply, many=False)
  166. return HTTPResponse(HTTPResponse.NORMAL_STATUS,
  167. **serializer.data).to_response()
  168. class LikeView(MethodView):
  169. decorators = (like_permission, )
  170. def post(self, replyId):
  171. user = request.user
  172. reply = Reply.query.filter_by(id=replyId).first_or_404()
  173. reply.likers.append(user)
  174. reply.save()
  175. serializer = Serializer(reply, many=False)
  176. return HTTPResponse(
  177. HTTPResponse.NORMAL_STATUS, data=serializer.data).to_response()
  178. def delete(self, replyId):
  179. user = request.user
  180. reply = Reply.query.filter_by(id=replyId).first_or_404()
  181. reply.likers.remove(user)
  182. reply.save()
  183. serializer = Serializer(reply, many=False)
  184. return HTTPResponse(
  185. HTTPResponse.NORMAL_STATUS, data=serializer.data).to_response()