privatethreads.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. from django.http import Http404
  2. from django.shortcuts import get_object_or_404
  3. from django.utils.translation import ugettext as _
  4. from misago.acl import add_acl
  5. from misago.forums.models import Forum
  6. from misago.threads.models import Thread, ThreadParticipant
  7. from misago.threads.permissions import (allow_use_private_threads,
  8. allow_see_private_thread,
  9. allow_see_private_post,
  10. exclude_invisible_private_threads)
  11. from misago.threads.views import generic
  12. def private_threads_view(klass):
  13. """
  14. decorator for making views check allow_use_private_threads
  15. """
  16. def dispatch(self, request, *args, **kwargs):
  17. allow_use_private_threads(request.user)
  18. return super(self.__class__, self).dispatch(
  19. request, *args, **kwargs)
  20. klass.dispatch = dispatch
  21. return klass
  22. class PrivateThreadsMixin(object):
  23. """
  24. Mixin is used to make views use different permission tests
  25. """
  26. def get_forum(self, request, lock=False, **kwargs):
  27. forum = Forum.objects.private_threads()
  28. add_acl(request.user, forum)
  29. return forum
  30. def check_forum_permissions(self, request, forum):
  31. add_acl(request.user, forum)
  32. allow_use_private_threads(request.user)
  33. def fetch_thread(self, request, lock=False, select_related=None,
  34. queryset=None, **kwargs):
  35. queryset = queryset or Thread.objects
  36. if lock:
  37. queryset = queryset.select_for_update()
  38. select_related = select_related or []
  39. if not 'forum' in select_related:
  40. select_related.append('forum')
  41. queryset = queryset.select_related(*select_related)
  42. where = {'id': kwargs.get('thread_id')}
  43. thread = get_object_or_404(queryset, **where)
  44. if thread.forum.special_role != 'private_threads':
  45. raise Http404()
  46. return thread
  47. def fetch_thread_participants(self, user, thread):
  48. thread.participants_list = []
  49. thread.participant = None
  50. participants_qs = ThreadParticipant.objects.filter(thread=thread)
  51. participants_qs = participants_qs.select_related('user')
  52. for participant in participants_qs:
  53. participant.thread = thread
  54. thread.participants_list.append(participant)
  55. if participant.user == user:
  56. thread.participant = participant
  57. return thread.participants_list
  58. def check_thread_permissions(self, request, thread):
  59. add_acl(request.user, thread.forum)
  60. add_acl(request.user, thread)
  61. self.fetch_thread_participants(request.user, thread)
  62. allow_see_private_thread(request.user, thread)
  63. allow_use_private_threads(request.user)
  64. def check_post_permissions(self, request, post):
  65. add_acl(request.user, post.forum)
  66. add_acl(request.user, post.thread)
  67. add_acl(request.user, post)
  68. self.fetch_thread_participants(request.user, post.thread)
  69. allow_see_private_post(request.user, post)
  70. allow_see_private_thread(request.user, post.thread)
  71. allow_use_private_threads(request.user)
  72. def exclude_invisible_posts(self, queryset, user, forum, thread):
  73. return queryset
  74. class PrivateThreads(generic.Threads):
  75. def get_queryset(self):
  76. threads_qs = Forum.objects.private_threads().thread_set
  77. return exclude_invisible_private_threads(threads_qs, self.user)
  78. def clean_threads_activity(self, user, threads):
  79. pass
  80. class PrivateThreadsFiltering(generic.ThreadsFiltering):
  81. def get_available_filters(self):
  82. filters = super(PrivateThreadsFiltering, self).get_available_filters()
  83. if self.user.acl['can_moderate_private_threads']:
  84. filters.append({
  85. 'type': 'reported',
  86. 'name': _("With reported posts"),
  87. 'is_label': False,
  88. })
  89. return filters
  90. @private_threads_view
  91. class PrivateThreadsView(generic.ThreadsView):
  92. link_name = 'misago:private_threads'
  93. template = 'misago/privatethreads/list.html'
  94. Threads = PrivateThreads
  95. Filtering = PrivateThreadsFiltering
  96. @private_threads_view
  97. class ThreadView(PrivateThreadsMixin, generic.ThreadView):
  98. pass
  99. @private_threads_view
  100. class GotoLastView(PrivateThreadsMixin, generic.GotoLastView):
  101. pass
  102. @private_threads_view
  103. class GotoNewView(PrivateThreadsMixin, generic.GotoNewView):
  104. pass
  105. @private_threads_view
  106. class GotoPostView(PrivateThreadsMixin, generic.GotoPostView):
  107. pass
  108. @private_threads_view
  109. class ReportedPostsListView(PrivateThreadsMixin, generic.ReportedPostsListView):
  110. pass
  111. @private_threads_view
  112. class QuotePostView(PrivateThreadsMixin, generic.QuotePostView):
  113. pass
  114. @private_threads_view
  115. class UnhidePostView(PrivateThreadsMixin, generic.UnhidePostView):
  116. pass
  117. @private_threads_view
  118. class HidePostView(PrivateThreadsMixin, generic.HidePostView):
  119. pass
  120. @private_threads_view
  121. class DeletePostView(PrivateThreadsMixin, generic.DeletePostView):
  122. pass
  123. @private_threads_view
  124. class EventsView(PrivateThreadsMixin, generic.EventsView):
  125. pass
  126. @private_threads_view
  127. class PostingView(PrivateThreadsMixin, generic.PostingView):
  128. pass