views.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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-5-10 16:35:37 (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.form 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.api.utils import gen_topic_filter, gen_topic_orderby
  24. from forums.common.serializer import Serializer
  25. from forums.common.utils import gen_filter_dict, gen_order_by
  26. from forums.common.views import BaseMethodView as MethodView
  27. from forums.common.views import IsAuthMethodView, IsConfirmedMethodView
  28. from forums.filters import safe_markdown
  29. from .models import Reply, Topic
  30. from .permissions import (like_permission, reply_list_permission,
  31. reply_permission, topic_list_permission,
  32. topic_permission, edit_permission)
  33. from forums.api.message.models import MessageClient
  34. class TopicAskView(IsConfirmedMethodView):
  35. def get(self):
  36. boardId = request.args.get('boardId', type=int)
  37. form = form_board()
  38. if boardId is not None:
  39. form.category.data = boardId
  40. data = {'title': _('Ask - '), 'form': form}
  41. return render_template('topic/ask.html', **data)
  42. class TopicEditView(IsConfirmedMethodView):
  43. decorators = (edit_permission, )
  44. def get(self, topicId):
  45. topic = Topic.query.filter_by(id=topicId).first_or_404()
  46. form = form_board()
  47. form.title.data = topic.title
  48. form.category.data = topic.board_id
  49. form.tags.data = ','.join([tag.name for tag in topic.tags])
  50. form.content.data = topic.content
  51. data = {'title': _('Edit -'), 'form': form, 'topic': topic}
  52. return render_template('topic/edit.html', **data)
  53. class TopicPreviewView(IsConfirmedMethodView):
  54. @login_required
  55. def post(self):
  56. post_data = request.data
  57. content_type = post_data.pop('content_type', None)
  58. content = post_data.pop('content', None)
  59. if content_type == Topic.CONTENT_TYPE_MARKDOWN:
  60. return safe_markdown(content)
  61. return content
  62. class TopicListView(MethodView):
  63. decorators = (topic_list_permission, )
  64. def get(self):
  65. query_dict = request.data
  66. page, number = self.page_info
  67. keys = ['title']
  68. # order_by = gen_order_by(query_dict, keys)
  69. # filter_dict = gen_filter_dict(query_dict, keys)
  70. order_by = gen_topic_orderby(query_dict, keys)
  71. filter_dict = gen_topic_filter(query_dict, keys)
  72. title = _('All Topics')
  73. if request.path.endswith('good'):
  74. filter_dict.update(is_good=True)
  75. title = _('Good Topics')
  76. elif request.path.endswith('top'):
  77. filter_dict.update(is_top=True)
  78. title = _('Top Topics')
  79. topics = Topic.query.filter_by(
  80. **filter_dict).order_by(*order_by).paginate(page, number, True)
  81. data = {'title': title, 'topics': topics}
  82. return render_template('topic/topic_list.html', **data)
  83. @form_validate(form_board, error=error_callback, f='')
  84. def post(self):
  85. user = request.user
  86. form = form_board()
  87. post_data = form.data
  88. title = post_data.pop('title', None)
  89. content = post_data.pop('content', None)
  90. tags = post_data.pop('tags', None)
  91. content_type = post_data.pop('content_type', None)
  92. board = post_data.pop('category', None)
  93. topic = Topic(
  94. title=title,
  95. content=content,
  96. content_type=content_type,
  97. board_id=int(board))
  98. tags = tags.split(',')
  99. topic_tags = []
  100. for tag in tags:
  101. tag = tag.strip()
  102. topic_tag = Tags.query.filter_by(name=tag).first()
  103. if topic_tag is None:
  104. topic_tag = Tags(name=tag, description=tag)
  105. topic_tag.save()
  106. topic_tags.append(topic_tag)
  107. topic.tags = topic_tags
  108. topic.author = user
  109. topic.save()
  110. # count
  111. topic.board.topic_count = 1
  112. topic.board.post_count = 1
  113. topic.author.topic_count = 1
  114. topic.reply_count = 1
  115. return redirect(url_for('topic.topic', topicId=topic.id))
  116. class TopicView(MethodView):
  117. decorators = (topic_permission, )
  118. def get(self, topicId):
  119. form = ReplyForm()
  120. query_dict = request.data
  121. topic = Topic.query.filter_by(id=topicId).first_or_404()
  122. page, number = self.page_info
  123. keys = ['title']
  124. order_by = gen_order_by(query_dict, keys)
  125. filter_dict = gen_filter_dict(query_dict, keys)
  126. replies = topic.replies.filter_by(
  127. **filter_dict).order_by(*order_by).paginate(page, number, True)
  128. data = {
  129. 'title': topic.title,
  130. 'form': form,
  131. 'topic': topic,
  132. 'replies': replies
  133. }
  134. topic.read_count = 1
  135. return render_template('topic/topic.html', **data)
  136. @form_validate(form_board)
  137. def put(self, topicId):
  138. form = form_board()
  139. post_data = form.data
  140. topic = Topic.query.filter_by(id=topicId).first_or_404()
  141. title = post_data.pop('title', None)
  142. content = post_data.pop('content', None)
  143. content_type = post_data.pop('content_type', None)
  144. category = post_data.pop('category', None)
  145. if title is not None:
  146. topic.title = title
  147. if content is not None:
  148. topic.content = content
  149. if content_type is not None:
  150. topic.content_type = content_type
  151. if category is not None:
  152. topic.board_id = int(category)
  153. topic.save()
  154. return HTTPResponse(HTTPResponse.NORMAL_STATUS).to_response()
  155. class ReplyListView(MethodView):
  156. decorators = (reply_list_permission, )
  157. @form_validate(ReplyForm, error=error_callback, f='')
  158. def post(self, topicId):
  159. topic = Topic.query.filter_by(id=topicId).first_or_404()
  160. post_data = request.data
  161. user = request.user
  162. content = post_data.pop('content', None)
  163. reply = Reply(content=content, topic_id=topic.id)
  164. reply.author = user
  165. reply.save()
  166. # notice
  167. MessageClient.topic(reply)
  168. # count
  169. topic.board.post_count = 1
  170. reply.author.reply_count = 1
  171. return redirect(url_for('topic.topic', topicId=topic.id))
  172. class ReplyView(MethodView):
  173. decorators = (reply_permission, )
  174. def put(self, replyId):
  175. post_data = request.data
  176. reply = Reply.query.filter_by(id=replyId).first_or_404()
  177. content = post_data.pop('content', None)
  178. if content is not None:
  179. reply.content = content
  180. reply.save()
  181. return HTTPResponse(HTTPResponse.NORMAL_STATUS).to_response()
  182. def delete(self, replyId):
  183. reply = Reply.query.filter_by(id=replyId).first_or_404()
  184. reply.delete()
  185. return HTTPResponse(HTTPResponse.NORMAL_STATUS).to_response()
  186. class LikeView(MethodView):
  187. decorators = (like_permission, )
  188. def post(self, replyId):
  189. user = request.user
  190. reply = Reply.query.filter_by(id=replyId).first_or_404()
  191. reply.likers.append(user)
  192. reply.save()
  193. MessageClient.like(reply)
  194. serializer = Serializer(reply, many=False)
  195. return HTTPResponse(
  196. HTTPResponse.NORMAL_STATUS, data=serializer.data).to_response()
  197. def delete(self, replyId):
  198. user = request.user
  199. reply = Reply.query.filter_by(id=replyId).first_or_404()
  200. reply.likers.remove(user)
  201. reply.save()
  202. serializer = Serializer(reply, many=False)
  203. return HTTPResponse(
  204. HTTPResponse.NORMAL_STATUS, data=serializer.data).to_response()