Browse Source

laying out private threads

Rafał Pitoń 8 years ago
parent
commit
1c9270c832

+ 1 - 1
misago/conf/defaults.py

@@ -325,7 +325,7 @@ CRISPY_TEMPLATE_PACK = 'bootstrap3'
 # Rest Framework Configuration
 REST_FRAMEWORK = {
     'DEFAULT_PERMISSION_CLASSES': (
-        'misago.users.rest_permissions.IsAuthenticatedOrReadOnly',
+        'misago.core.rest_permissions.IsAuthenticatedOrReadOnly',
     ),
     'DEFAULT_RENDERER_CLASSES': (
         'rest_framework.renderers.JSONRenderer',

+ 12 - 0
misago/core/rest_permissions.py

@@ -0,0 +1,12 @@
+from django.core.exceptions import PermissionDenied
+from django.utils.translation import ugettext as _
+
+from rest_framework.permissions import SAFE_METHODS, BasePermission
+
+
+class IsAuthenticatedOrReadOnly(BasePermission):
+    def has_permission(self, request, view):
+        if request.user.is_anonymous() and request.method not in SAFE_METHODS:
+            raise PermissionDenied(_("This action is not available to guests."))
+        else:
+            return True

+ 10 - 0
misago/threads/api/rest_permissions.py

@@ -0,0 +1,10 @@
+from rest_framework.permissions import BasePermission
+
+from ..permissions.privatethreads import allow_use_private_threads
+
+
+class PrivateThreadsPermission(BasePermission):
+    def has_permission(self, request, view):
+        allow_use_private_threads(request.user)
+
+        return True

+ 14 - 4
misago/threads/api/threadendpoints/list.py

@@ -2,8 +2,9 @@ from rest_framework.response import Response
 
 from misago.core.shortcuts import get_int_or_404
 
-from ...viewmodels.category import ThreadsCategory, ThreadsRootCategory
-from ...viewmodels.threads import ForumThreads
+from ...viewmodels.category import (
+    ThreadsCategory, ThreadsRootCategory, PrivateThreadsCategory)
+from ...viewmodels.threads import ForumThreads, PrivateThreads
 
 
 class ListEndpointBase(object):
@@ -31,7 +32,7 @@ class ListEndpointBase(object):
         return threads.get_frontend_context()
 
 
-class ForumThreads(ListEndpointBase):
+class ForumThreadsList(ListEndpointBase):
     threads = ForumThreads
 
     def get_category(self, request, pk=None):
@@ -40,4 +41,13 @@ class ForumThreads(ListEndpointBase):
         else:
             return ThreadsRootCategory(request)
 
-threads_list_endpoint = ForumThreads()
+
+class PrivateThreadsList(ListEndpointBase):
+    threads = PrivateThreads
+
+    def get_category(self, request, pk=None):
+        return PrivateThreadsCategory(request)
+
+
+threads_list_endpoint = ForumThreadsList()
+private_threads_list_endpoint = PrivateThreadsList()

+ 6 - 0
misago/threads/api/threadposts.py

@@ -25,6 +25,7 @@ from .postendpoints.patch_event import event_patch_endpoint
 from .postendpoints.patch_post import post_patch_endpoint
 from .postendpoints.read import post_read_endpoint
 from .postendpoints.split import posts_split_endpoint
+from .rest_permissions import PrivateThreadsPermission
 
 
 class ViewSet(viewsets.ViewSet):
@@ -280,3 +281,8 @@ class ThreadPostsViewSet(ViewSet):
     thread = ForumThread
     posts = ThreadPosts
     post_ = ThreadPost
+
+
+class PrivateThreadPostsViewSet(ViewSet):
+    permission_classes = (PrivateThreadsPermission,)
+

+ 16 - 4
misago/threads/api/threads.py

@@ -13,8 +13,9 @@ from ..models import Post, Thread
 from ..moderation import threads as moderation
 from ..viewmodels import ForumThread
 from .postingendpoint import PostingEndpoint
+from .rest_permissions import PrivateThreadsPermission
 from .threadendpoints.editor import thread_start_editor
-from .threadendpoints.list import threads_list_endpoint
+from .threadendpoints.list import threads_list_endpoint, private_threads_list_endpoint
 from .threadendpoints.merge import thread_merge_endpoint, threads_merge_endpoint
 from .threadendpoints.patch import thread_patch_endpoint
 
@@ -40,9 +41,6 @@ class ViewSet(viewsets.ViewSet):
             select_for_update=True
         )
 
-    def list(self, request):
-        return threads_list_endpoint(request)
-
     def retrieve(self, request, pk):
         thread = self.get_thread(request, pk)
         return Response(thread.get_frontend_context())
@@ -66,6 +64,9 @@ class ViewSet(viewsets.ViewSet):
 class ThreadViewSet(ViewSet):
     thread = ForumThread
 
+    def list(self, request):
+        return threads_list_endpoint(request)
+
     @transaction.atomic
     def create(self, request):
         # Initialize empty instances for new thread
@@ -106,3 +107,14 @@ class ThreadViewSet(ViewSet):
     @list_route(methods=['get'])
     def editor(self, request):
         return thread_start_editor(request)
+
+
+class PrivateThreadViewSet(ViewSet):
+    permission_classes = (PrivateThreadsPermission,)
+
+    def list(self, request):
+        return private_threads_list_endpoint(request)
+
+    @list_route(methods=['get'])
+    def editor(self, request):
+        return thread_start_editor(request)

+ 6 - 1
misago/threads/context_processors.py

@@ -4,7 +4,12 @@ from django.core.urlresolvers import reverse
 def preload_threads_urls(request):
     request.frontend_context.update({
         'ATTACHMENTS_API': reverse('misago:api:attachment-list'),
-        'THREAD_EDITOR_API': reverse('misago:api:thread-editor')
+
+        'THREAD_EDITOR_API': reverse('misago:api:thread-editor'),
+        'THREADS_API': reverse('misago:api:thread-list'),
+
+        'PRIVATE_THREAD_EDITOR_API': reverse('misago:api:private-thread-editor'),
+        'PRIVATE_THREADS_API': reverse('misago:api:private-thread-list'),
     })
 
     return {}

+ 4 - 3
misago/threads/permissions/privatethreads.py

@@ -49,7 +49,8 @@ class PermissionsForm(forms.Form):
     )
     can_moderate_private_threads = forms.YesNoSwitch(
         label=_("Can moderate private threads"),
-        help_text=_("Allows user to read, reply, edit and delete content in reported private threads.")
+        help_text=_("Allows user to read, reply, edit and delete content "
+                    "in reported private threads.")
     )
 
 
@@ -140,9 +141,9 @@ ACL tests
 """
 def allow_use_private_threads(user):
     if user.is_anonymous():
-        raise PermissionDenied(_("Unsigned members can't use private threads system."))
+        raise PermissionDenied(_("You have to sign in to use private threads."))
     if not user.acl['can_use_private_threads']:
-        raise PermissionDenied(_("You can't use private threads system."))
+        raise PermissionDenied(_("You can't use private threads."))
 can_use_private_threads = return_boolean(allow_use_private_threads)
 
 

+ 8 - 2
misago/threads/urls/api.py

@@ -1,14 +1,20 @@
 from misago.core.apirouter import MisagoApiRouter
 
 from ..api.attachments import AttachmentViewSet
-from ..api.threadposts import ThreadPostsViewSet
-from ..api.threads import ThreadViewSet
+from ..api.threadposts import ThreadPostsViewSet, PrivateThreadPostsViewSet
+from ..api.threads import ThreadViewSet, PrivateThreadViewSet
 from ..api.threadpoll import ThreadPollViewSet
 
 
 router = MisagoApiRouter()
+
 router.register(r'attachments', AttachmentViewSet, base_name='attachment')
+
 router.register(r'threads', ThreadViewSet, base_name='thread')
 router.register(r'threads/(?P<thread_pk>[^/.]+)/posts', ThreadPostsViewSet, base_name='thread-post')
 router.register(r'threads/(?P<thread_pk>[^/.]+)/poll', ThreadPollViewSet, base_name='thread-poll')
+
+router.register(r'private-threads', PrivateThreadViewSet, base_name='private-thread')
+router.register(r'private-threads/(?P<thread_pk>[^/.]+)/posts', PrivateThreadViewSet, base_name='private-thread-post')
+
 urlpatterns = router.urls

+ 2 - 1
misago/threads/viewmodels/category.py

@@ -79,4 +79,5 @@ class ThreadsCategory(ThreadsRootCategory):
 
 
 class PrivateThreadsCategory(ViewModel):
-    pass
+    def get_categories(self, request):
+        return [Category.objects.private_threads()]

+ 4 - 0
misago/threads/viewmodels/threads.py

@@ -145,7 +145,11 @@ class ForumThreads(ViewModel):
 
 
 class PrivateThreads(ViewModel):
+    def get_pinned_threads(self, queryset, category, threads_categories):
+        return [] # this is noop for Private Threads where its impossible to weight threads
+
     def get_remaining_threads_queryset(self, queryset, category, threads_categories):
+        # todo: return all with reports (if moderator) or ones user is participating in otherwhise
         return queryset.filter(category__in=threads_categories)
 
 

+ 0 - 1
misago/threads/views/list.py

@@ -67,7 +67,6 @@ class ForumThreads(ListBase):
 
     def get_default_frontend_context(self):
         return {
-            'THREADS_API': reverse('misago:api:thread-list'),
             'MERGE_THREADS_API': reverse('misago:api:thread-merge'),
         }
 

+ 1 - 1
misago/users/api/auth.py

@@ -12,10 +12,10 @@ from misago.core.mail import mail_user
 
 from ..bans import get_user_ban
 from ..forms.auth import AuthenticationForm, ResendActivationForm, ResetPasswordForm
-from ..rest_permissions import UnbannedAnonOnly, UnbannedOnly
 from ..serializers import AnonymousUserSerializer, AuthenticatedUserSerializer
 from ..tokens import is_password_change_token_valid, make_activation_token, make_password_change_token
 from ..validators import validate_password
+from .rest_permissions import UnbannedAnonOnly, UnbannedOnly
 
 
 def gateway(request):

+ 3 - 13
misago/users/rest_permissions.py → misago/users/api/rest_permissions.py

@@ -1,30 +1,20 @@
 from django.core.exceptions import PermissionDenied
 from django.utils.translation import ugettext as _
 
-from rest_framework.permissions import SAFE_METHODS, AllowAny, BasePermission
+from rest_framework.permissions import BasePermission
 
 from misago.core.exceptions import Banned
 
-from .bans import get_request_ip_ban
-from .models import BAN_IP, Ban
+from ..bans import get_request_ip_ban
+from ..models import BAN_IP, Ban
 
 
 __all__ = [
-    'AllowAny',
-    'IsAuthenticatedOrReadOnly',
     'UnbannedOnly',
     'UnbannedAnonOnly'
 ]
 
 
-class IsAuthenticatedOrReadOnly(BasePermission):
-    def has_permission(self, request, view):
-        if request.user.is_anonymous() and request.method not in SAFE_METHODS:
-            raise PermissionDenied(_("This action is not available to guests."))
-        else:
-            return True
-
-
 class UnbannedOnly(BasePermission):
     def is_request_banned(self, request):
         ban = get_request_ip_ban(request)

+ 1 - 1
misago/users/api/usernamechanges.py

@@ -10,8 +10,8 @@ from misago.core.apipaginator import ApiPaginator
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
 
 from ..models import UsernameChange
-from ..rest_permissions import BasePermission
 from ..serializers.usernamechange import UsernameChangeSerializer
+from .rest_permissions import BasePermission
 
 
 class UsernameChangesViewSetPermission(BasePermission):

+ 2 - 1
misago/users/api/users.py

@@ -13,6 +13,7 @@ from rest_framework.response import Response
 from misago.acl import add_acl
 from misago.categories.models import Category
 from misago.core.cache import cache
+from misago.core.rest_permissions import IsAuthenticatedOrReadOnly
 from misago.core.shortcuts import get_int_or_404, get_object_or_404
 from misago.threads.moderation.posts import hide_post
 from misago.threads.moderation.threads import hide_thread
@@ -23,7 +24,6 @@ from ..online.utils import get_user_status
 from ..permissions.delete import allow_delete_user
 from ..permissions.moderation import allow_moderate_avatar, allow_rename_user
 from ..permissions.profiles import allow_browse_users_list, allow_follow_user, allow_see_ban_details
-from ..rest_permissions import BasePermission, IsAuthenticatedOrReadOnly, UnbannedAnonOnly
 from ..serializers import BanDetailsSerializer, UserProfileSerializer, UserSerializer
 from ..viewmodels import UserPosts, UserThreads
 from .userendpoints.avatar import avatar_endpoint, moderate_avatar_endpoint
@@ -33,6 +33,7 @@ from .userendpoints.create import create_endpoint
 from .userendpoints.list import list_endpoint
 from .userendpoints.signature import signature_endpoint
 from .userendpoints.username import moderate_username_endpoint, username_endpoint
+from .rest_permissions import BasePermission, UnbannedAnonOnly
 
 
 class UserViewSetPermission(BasePermission):