views.py 7.5 KB

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