forums.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. # -*- coding: utf-8 -*-
  2. """
  3. flaskbb.api.forums
  4. ~~~~~~~~~~~~~~~~~~
  5. The Forum API.
  6. TODO: - POST/PUT/DELETE stuff
  7. - Permission checks.
  8. :copyright: (c) 2015 by the FlaskBB Team.
  9. :license: BSD, see LICENSE for more details.
  10. """
  11. from flask_restful import Resource, fields, marshal, abort, reqparse
  12. from flaskbb.forum.models import Category, Forum, Topic, Post
  13. category_fields = {
  14. 'id': fields.Integer,
  15. 'title': fields.String,
  16. 'description': fields.String,
  17. 'slug': fields.String,
  18. 'forums': fields.String(attribute="forums.title")
  19. }
  20. forum_fields = {
  21. 'id': fields.Integer,
  22. 'category_id': fields.Integer,
  23. 'title': fields.String,
  24. 'description': fields.String,
  25. 'position': fields.Integer,
  26. 'locked': fields.Boolean,
  27. 'show_moderators': fields.Boolean,
  28. 'external': fields.String,
  29. 'post_count': fields.Integer,
  30. 'topic_count': fields.Integer,
  31. 'last_post_id': fields.Integer,
  32. 'last_post_title': fields.String,
  33. 'last_post_created': fields.DateTime,
  34. 'last_post_username': fields.String
  35. }
  36. topic_fields = {
  37. 'id': fields.Integer,
  38. 'forum_id': fields.Integer,
  39. 'title': fields.String,
  40. 'user_id': fields.Integer,
  41. 'username': fields.String,
  42. 'date_created': fields.DateTime,
  43. 'last_updated': fields.DateTime,
  44. 'locked': fields.Boolean,
  45. 'important': fields.Boolean,
  46. 'views': fields.Integer,
  47. 'post_count': fields.Integer,
  48. 'content': fields.String(attribute='first_post.content'),
  49. 'first_post_id': fields.Integer,
  50. 'last_post_id': fields.Integer,
  51. }
  52. post_fields = {
  53. 'id': fields.Integer,
  54. 'topic_id': fields.Integer,
  55. 'user_id': fields.Integer,
  56. 'username': fields.String,
  57. 'content': fields.String,
  58. 'date_created': fields.DateTime,
  59. 'date_modified': fields.DateTime,
  60. 'modified_by': fields.String
  61. }
  62. class CategoryListAPI(Resource):
  63. def __init__(self):
  64. super(CategoryListAPI, self).__init__()
  65. def get(self):
  66. categories_list = Category.query.order_by(Category.position).all()
  67. categories = {'categories': [marshal(category, category_fields)
  68. for category in categories_list]}
  69. return categories
  70. class CategoryAPI(Resource):
  71. def __init__(self):
  72. super(CategoryAPI, self).__init__()
  73. def get(self, id):
  74. category = Category.query.filter_by(id=id).first()
  75. if not category:
  76. abort(404)
  77. return {'category': marshal(category, category_fields)}
  78. class ForumListAPI(Resource):
  79. def __init__(self):
  80. self.reqparse = reqparse.RequestParser()
  81. self.reqparse.add_argument('category_id', type=int, location='args')
  82. super(ForumListAPI, self).__init__()
  83. def get(self):
  84. # get the forums for a category or get all
  85. args = self.reqparse.parse_args()
  86. if args['category_id'] is not None:
  87. forums_list = Forum.query.\
  88. filter(Forum.category_id == args['category_id']).\
  89. order_by(Forum.position).all()
  90. else:
  91. forums_list = Forum.query.order_by(Forum.position).all()
  92. forums = {'forums': [marshal(forum, forum_fields)
  93. for forum in forums_list]}
  94. return forums
  95. class ForumAPI(Resource):
  96. def __init__(self):
  97. super(ForumAPI, self).__init__()
  98. def get(self, id):
  99. forum = Forum.query.filter_by(id=id).first()
  100. if not forum:
  101. abort(404)
  102. return {'forum': marshal(forum, forum_fields)}
  103. class TopicListAPI(Resource):
  104. def __init__(self):
  105. self.reqparse = reqparse.RequestParser()
  106. self.reqparse.add_argument('page', type=int, location='args')
  107. self.reqparse.add_argument('per_page', type=int, location='args')
  108. self.reqparse.add_argument('forum_id', type=int, location='args')
  109. super(TopicListAPI, self).__init__()
  110. def get(self):
  111. args = self.reqparse.parse_args()
  112. page = args['page'] or 1
  113. per_page = args['per_page'] or 20
  114. forum_id = args['forum_id']
  115. if forum_id is not None:
  116. topics_list = Topic.query.filter_by(forum_id=forum_id).\
  117. order_by(Topic.important.desc(), Topic.last_updated.desc()).\
  118. paginate(page, per_page, True)
  119. else:
  120. topics_list = Topic.query.\
  121. order_by(Topic.important.desc(), Topic.last_updated.desc()).\
  122. paginate(page, per_page, True)
  123. topics = {'topics': [marshal(topic, topic_fields)
  124. for topic in topics_list.items]}
  125. return topics
  126. class TopicAPI(Resource):
  127. def __init__(self):
  128. super(TopicAPI, self).__init__()
  129. def get(self, id):
  130. topic = Topic.query.filter_by(id=id).first()
  131. if not topic:
  132. abort(404)
  133. return {'topic': marshal(topic, topic_fields)}
  134. class PostListAPI(Resource):
  135. def __init__(self):
  136. self.reqparse = reqparse.RequestParser()
  137. self.reqparse.add_argument('page', type=int, location='args')
  138. self.reqparse.add_argument('per_page', type=int, location='args')
  139. self.reqparse.add_argument('topic_id', type=int, location='args')
  140. super(PostListAPI, self).__init__()
  141. def get(self):
  142. args = self.reqparse.parse_args()
  143. page = args['page'] or 1
  144. per_page = args['per_page'] or 20
  145. topic_id = args['topic_id']
  146. if topic_id is not None:
  147. posts_list = Post.query.\
  148. filter_by(topic_id=id).\
  149. order_by(Post.id.asc()).\
  150. paginate(page, per_page)
  151. else:
  152. posts_list = Post.query.\
  153. order_by(Post.id.asc()).\
  154. paginate(page, per_page)
  155. posts = {'posts': [marshal(post, post_fields)
  156. for post in posts_list.items]}
  157. return posts
  158. class PostAPI(Resource):
  159. def __init__(self):
  160. super(PostAPI, self).__init__()
  161. def get(self, id):
  162. post = Post.query.filter_by(id=id).first()
  163. if not post:
  164. abort(404)
  165. return {'post': marshal(post, post_fields)}