Browse Source

non-js private threads list

Rafał Pitoń 8 years ago
parent
commit
4dd09dcad6

+ 5 - 5
misago/templates/misago/threadslist/category.html

@@ -5,14 +5,14 @@
 {% block title %}
 {% block title %}
 {% if list_name %}
 {% if list_name %}
   {% if paginator.page > 1 %}
   {% if paginator.page > 1 %}
-    {{ list_name }} ({% blocktrans with page=paginator.page %}page: {{ page }}{% endblocktrans %}) | {{ category.name }} | {{ block.super }}
+    {{ list_name }} ({% blocktrans with page=paginator.page %}page: {{ page }}{% endblocktrans %}) | {{ category }} | {{ block.super }}
   {% else %}
   {% else %}
-    {{ list_name }} | {{ category.name }} | {{ block.super }}
+    {{ list_name }} | {{ category }} | {{ block.super }}
   {% endif %}
   {% endif %}
 {% elif paginator.page > 1 %}
 {% elif paginator.page > 1 %}
-  {{ category.name }} ({% blocktrans with page=paginator.page %}page: {{ page }}{% endblocktrans %}) | {{ block.super }}
+  {{ category }} ({% blocktrans with page=paginator.page %}page: {{ page }}{% endblocktrans %}) | {{ block.super }}
 {% else %}
 {% else %}
-  {{ category.name }} | {{ block.super }}
+  {{ category }} | {{ block.super }}
 {% endif %}
 {% endif %}
 {% endblock title %}
 {% endblock title %}
 
 
@@ -41,7 +41,7 @@
     </a>
     </a>
 
 
     <h1 class="pull-left">
     <h1 class="pull-left">
-      {{ category.name }}
+      {{ category }}
     </h1>
     </h1>
   </div>
   </div>
   {% if user.is_authenticated %}
   {% if user.is_authenticated %}

+ 69 - 0
misago/templates/misago/threadslist/private_threads.html

@@ -0,0 +1,69 @@
+{% extends "misago/threadslist/base.html" %}
+{% load i18n misago_shorthands misago_stringutils %}
+
+
+{% block title %}
+{% if list_name %}
+  {% if paginator.page > 1 %}
+    {{ list_name }} ({% blocktrans with page=paginator.page %}page: {{ page }}{% endblocktrans %}) | {{ category }} | {{ block.super }}
+  {% else %}
+    {{ list_name }} | {{ category }} | {{ block.super }}
+  {% endif %}
+{% elif paginator.page > 1 %}
+  {{ category }} ({% blocktrans with page=paginator.page %}page: {{ page }}{% endblocktrans %}) | {{ block.super }}
+{% else %}
+  {{ category }} | {{ block.super }}
+{% endif %}
+{% endblock title %}
+
+
+{% block extra-css %}
+page-private-threads
+{% endblock extra-css %}
+
+
+{% block page-header %}
+<div class="page-header tabbed">
+  <div class="container">
+    <a href="{{ category.parent.get_absolute_url }}{% if list_type != 'all' %}{{ list_type }}/{% endif %}" class="btn btn-default btn-aligned btn-icon btn-go-back pull-left">
+      <span class="material-icon">
+        keyboard_arrow_left
+      </span>
+    </a>
+
+    <h1 class="pull-left">
+      {{ category }}
+    </h1>
+  </div>
+  {% if user.is_authenticated %}
+    {% include "misago/threadslist/tabs.html" with hide_unapproved=True %}
+  {% endif %}
+</div>
+{% endblock page-header %}
+
+
+{% block list-container %}
+  <div class="category-description">
+    <div class="page-lead">
+      <p>{% trans "Private threads are threads which only those that started them and those they have invited may see and participate in." %}</p>
+    </div>
+  </div>
+
+  {{ block.super }}
+{% endblock list-container%}
+
+
+{% block thread %}
+  {% include "misago/threadslist/thread.html" with hide_path=True %}
+{% endblock thread %}
+
+
+{% block list-empty-message %}
+  {% if list_type == 'all' %}
+    <p class="lead">
+      {% trans "You aren't participating in any private threads." %}
+    </p>
+  {% else %}
+    {% trans "No threads matching specified criteria were found." %}
+  {% endif %}
+{% endblock list-empty-message %}

+ 1 - 1
misago/templates/misago/threadslist/tabs.html

@@ -32,7 +32,7 @@
           <span class="hidden-md hidden-lg">{% trans "Subscribed threads" %}</span>
           <span class="hidden-md hidden-lg">{% trans "Subscribed threads" %}</span>
         </a>
         </a>
       </li>
       </li>
-      {% if user.acl.can_see_unapproved_content_lists %}
+      {% if user.acl.can_see_unapproved_content_lists and not hide_unapproved %}
         <li{% if list_type == 'unapproved' %} class="active"{% endif %}>
         <li{% if list_type == 'unapproved' %} class="active"{% endif %}>
           <a href="{{ category.get_absolute_url }}unapproved/">
           <a href="{{ category.get_absolute_url }}unapproved/">
             <span class="hidden-xs hidden-sm">{% trans "Unapproved" %}</span>
             <span class="hidden-xs hidden-sm">{% trans "Unapproved" %}</span>

+ 2 - 2
misago/templates/misago/threadslist/thread.html

@@ -132,7 +132,7 @@
         </span>
         </span>
       </li>
       </li>
       {% endif %}
       {% endif %}
-      {% if thread.top_category %}
+      {% if thread.top_category and not hide_path %}
       <li class="thread-path">
       <li class="thread-path">
         <a href="{{ thread.top_category.get_absolute_url }}{% if list_type != 'all' %}{{ list_type }}/{% endif %}" class="thread-category{% if thread.top_category.css_class %} thread-category-{{ thread.top_category.css_class }}{% endif %}">
         <a href="{{ thread.top_category.get_absolute_url }}{% if list_type != 'all' %}{{ list_type }}/{% endif %}" class="thread-category{% if thread.top_category.css_class %} thread-category-{{ thread.top_category.css_class }}{% endif %}">
           {{ thread.top_category.name }}
           {{ thread.top_category.name }}
@@ -173,7 +173,7 @@
       </li>
       </li>
     </ul>
     </ul>
     <ul class="thread-details-compact list-inline">
     <ul class="thread-details-compact list-inline">
-      {% if thread.top_category %}
+      {% if thread.top_category and not hide_path %}
         {% if thread.top_category != thread.category %}
         {% if thread.top_category != thread.category %}
         <li class="thread-path">
         <li class="thread-path">
           <a href="{{ thread.category.get_absolute_url }}{% if list_type != 'all' %}{{ list_type }}/{% endif %}" class="thread-category{% if thread.category.css_class %} thread-category-{{ thread.category.css_class }}{% endif %}">
           <a href="{{ thread.category.get_absolute_url }}{% if list_type != 'all' %}{{ list_type }}/{% endif %}" class="thread-category{% if thread.category.css_class %} thread-category-{{ thread.category.css_class }}{% endif %}">

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

@@ -1,10 +0,0 @@
-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

+ 0 - 3
misago/threads/api/threads.py

@@ -13,7 +13,6 @@ from ..models import Post, Thread
 from ..moderation import threads as moderation
 from ..moderation import threads as moderation
 from ..viewmodels import ForumThread
 from ..viewmodels import ForumThread
 from .postingendpoint import PostingEndpoint
 from .postingendpoint import PostingEndpoint
-from .rest_permissions import PrivateThreadsPermission
 from .threadendpoints.editor import thread_start_editor
 from .threadendpoints.editor import thread_start_editor
 from .threadendpoints.list import threads_list_endpoint, private_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.merge import thread_merge_endpoint, threads_merge_endpoint
@@ -110,8 +109,6 @@ class ThreadViewSet(ViewSet):
 
 
 
 
 class PrivateThreadViewSet(ViewSet):
 class PrivateThreadViewSet(ViewSet):
-    permission_classes = (PrivateThreadsPermission,)
-
     def list(self, request):
     def list(self, request):
         return private_threads_list_endpoint(request)
         return private_threads_list_endpoint(request)
 
 

+ 0 - 2
misago/threads/permissions/privatethreads.py

@@ -129,8 +129,6 @@ def build_acl(acl, roles, key_name):
             'can_protect_posts': 1,
             'can_protect_posts': 1,
             'can_merge_posts': 1,
             'can_merge_posts': 1,
             'can_see_reports': 1,
             'can_see_reports': 1,
-            'can_see_reports': 1,
-            'can_approve_content': 1,
             'can_hide_events': 2,
             'can_hide_events': 2,
         })
         })
 
 

+ 55 - 1
misago/threads/tests/test_privatethreadslists.py

@@ -1,4 +1,4 @@
-from django.core.urlresolvers import reverse
+from django.urls import reverse
 
 
 from misago.acl.testutils import override_acl
 from misago.acl.testutils import override_acl
 
 
@@ -67,3 +67,57 @@ class PrivateThreadsApiTests(PrivateThreadsApiTestCase):
         self.assertEqual(response_json['count'], 2)
         self.assertEqual(response_json['count'], 2)
         self.assertEqual(response_json['results'][0]['id'], reported.id)
         self.assertEqual(response_json['results'][0]['id'], reported.id)
         self.assertEqual(response_json['results'][1]['id'], visible.id)
         self.assertEqual(response_json['results'][1]['id'], visible.id)
+
+
+class PrivateThreadsListTests(PrivateThreadsApiTestCase):
+    def setUp(self):
+        super(PrivateThreadsListTests, self).setUp()
+
+        self.test_link = reverse('misago:private-threads')
+
+    def test_unauthenticated(self):
+        """view requires user to sign in and be able to access it"""
+        self.logout_user()
+
+        response = self.client.get(self.test_link)
+        self.assertContains(response, "sign in to use private threads", status_code=403)
+
+    def test_no_permission(self):
+        """view requires user to have permission to be able to access it"""
+        override_acl(self.user, {
+            'can_use_private_threads': 0
+        })
+
+        response = self.client.get(self.test_link)
+        self.assertContains(response, "use private threads", status_code=403)
+
+    def test_empty_list(self):
+        """view has no showstoppers on returning empty list"""
+        response = self.client.get(self.test_link)
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, "empty-message")
+
+    def test_thread_visibility(self):
+        """only participated threads are returned by private threads view"""
+        visible = testutils.post_thread(category=self.category, poster=self.user)
+        hidden = testutils.post_thread(category=self.category, poster=self.user)
+        reported = testutils.post_thread(category=self.category, poster=self.user)
+
+        add_owner(visible, self.user)
+
+        reported.has_reported_posts = True
+        reported.save()
+
+        response = self.client.get(self.test_link)
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, visible.get_absolute_url())
+
+        # threads with reported posts will also show to moderators
+        override_acl(self.user, {
+            'can_moderate_private_threads': 1
+        })
+
+        response = self.client.get(self.test_link)
+        self.assertEqual(response.status_code, 200)
+        self.assertContains(response, reported.get_absolute_url())
+        self.assertContains(response, visible.get_absolute_url())

+ 1 - 2
misago/threads/urls/__init__.py

@@ -66,13 +66,12 @@ urlpatterns += threads_list_patterns('category', CategoryThreads, (
 ))
 ))
 
 
 
 
-urlpatterns += threads_list_patterns('private-threads', CategoryThreads, (
+urlpatterns += threads_list_patterns('private-threads', PrivateThreads, (
     r'^private-threads/$',
     r'^private-threads/$',
     r'^private-threads/my/$',
     r'^private-threads/my/$',
     r'^private-threads/new/$',
     r'^private-threads/new/$',
     r'^private-threads/unread/$',
     r'^private-threads/unread/$',
     r'^private-threads/subscribed/$',
     r'^private-threads/subscribed/$',
-    r'^private-threads/unapproved/$',
 ))
 ))
 
 
 
 

+ 7 - 0
misago/threads/viewmodels/category.py

@@ -7,6 +7,8 @@ from misago.categories.serializers import BasicCategorySerializer
 from misago.core.viewmodel import ViewModel as BaseViewModel
 from misago.core.viewmodel import ViewModel as BaseViewModel
 from misago.core.shortcuts import validate_slug
 from misago.core.shortcuts import validate_slug
 
 
+from ..permissions import allow_use_private_threads
+
 
 
 __all__ = ['ThreadsRootCategory', 'ThreadsCategory', 'PrivateThreadsCategory']
 __all__ = ['ThreadsRootCategory', 'ThreadsCategory', 'PrivateThreadsCategory']
 
 
@@ -82,3 +84,8 @@ class ThreadsCategory(ThreadsRootCategory):
 class PrivateThreadsCategory(ViewModel):
 class PrivateThreadsCategory(ViewModel):
     def get_categories(self, request):
     def get_categories(self, request):
         return [Category.objects.private_threads()]
         return [Category.objects.private_threads()]
+
+    def get_category(self, request, categories, **kwargs):
+        allow_use_private_threads(request.user)
+
+        return categories[0]