posts.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. from django.conf import settings
  2. from misago.acl import add_acl
  3. from misago.core.shortcuts import paginate, pagination_dict
  4. from misago.readtracker.threadstracker import make_posts_read_aware
  5. from misago.users.online.utils import make_users_status_aware
  6. from ..paginator import PostsPaginator
  7. from ..permissions.threads import exclude_invisible_posts
  8. from ..serializers import PostSerializer
  9. from ..utils import add_likes_to_posts
  10. __all__ = ['ThreadPosts']
  11. class ViewModel(object):
  12. def __init__(self, request, thread, page):
  13. try:
  14. thread_model = thread.unwrap()
  15. except AttributeError:
  16. thread_model = thread
  17. posts_queryset = self.get_posts_queryset(request, thread_model)
  18. list_page = paginate(
  19. posts_queryset, page, settings.MISAGO_POSTS_PER_PAGE, settings.MISAGO_POSTS_TAIL,
  20. paginator=PostsPaginator)
  21. paginator = pagination_dict(list_page, include_page_range=False)
  22. posts = list(list_page.object_list)
  23. posters = []
  24. for post in posts:
  25. post.category = thread.category
  26. post.thread = thread_model
  27. if post.poster:
  28. posters.append(post.poster)
  29. make_users_status_aware(request.user, posters)
  30. if thread.category.acl['can_see_posts_likes']:
  31. add_likes_to_posts(request.user, posts)
  32. # add events to posts
  33. first_post = None
  34. if list_page.has_previous():
  35. first_post = posts[0]
  36. last_post = None
  37. if list_page.has_next():
  38. last_post = posts[-1]
  39. posts += self.get_events_queryset(
  40. request, thread_model, settings.MISAGO_EVENTS_PER_PAGE, first_post, last_post)
  41. # sorth both by pk
  42. posts.sort(key=lambda p: p.pk)
  43. # make posts and events ACL and reads aware
  44. add_acl(request.user, posts)
  45. make_posts_read_aware(request.user, thread_model, posts)
  46. self._user = request.user
  47. self.posts = posts
  48. self.paginator = paginator
  49. def get_posts_queryset(self, request, thread):
  50. queryset = thread.post_set.select_related(
  51. 'poster',
  52. 'poster__rank',
  53. 'poster__ban_cache',
  54. 'poster__online_tracker'
  55. ).filter(is_event=False).order_by('id')
  56. return exclude_invisible_posts(request.user, thread.category, queryset)
  57. def get_events_queryset(self, request, thread, limit, first_post=None, last_post=None):
  58. queryset = thread.post_set.select_related('poster').filter(is_event=True)
  59. if first_post:
  60. queryset = queryset.filter(pk__gt=first_post.pk)
  61. if last_post:
  62. queryset = queryset.filter(pk__lt=last_post.pk)
  63. queryset = exclude_invisible_posts(request.user, thread.category, queryset)
  64. return list(queryset.order_by('id')[:limit])
  65. def get_frontend_context(self):
  66. context = {
  67. 'results': PostSerializer(self.posts, many=True, context={'user': self._user}).data
  68. }
  69. context.update(self.paginator)
  70. return context
  71. def get_template_context(self):
  72. return {
  73. 'posts': self.posts,
  74. 'paginator': self.paginator
  75. }
  76. class ThreadPosts(ViewModel):
  77. pass