Browse Source

WIP #410: Filter threads list by prefix

Rafał Pitoń 10 years ago
parent
commit
5f86e53a74

+ 1 - 1
misago/project_template/requirements.txt

@@ -1,6 +1,6 @@
-https://github.com/django/django/archive/stable/1.7.x.zip#egg=django
 beautifulsoup4==4.3.2
 bleach==1.4
+django==1.7
 django-debug-toolbar==1.2.1
 django-crispy-forms==1.4.0
 django-mptt==0.6.1

+ 5 - 0
misago/static/misago/css/misago/typography.less

@@ -61,3 +61,8 @@
     }
   }
 }
+
+
+.label-solo {
+  font-size: @font-size-base;
+}

+ 13 - 1
misago/templates/misago/threads/show.html

@@ -2,7 +2,13 @@
 {% if filters %}
 <div class="btn-group pull-left">
   <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
-    {% trans "Show:" %} <strong>{{ filter_name }}</strong>
+    {% trans "Show:" %}{% if filter_by.is_label %}
+    <span class="label{% if filter_by.css_class %} label-{{ filter_by.css_class }}{% endif %}">
+      {{ filter_by.name }}
+    </span>
+    {% else %}
+    <strong>{{ filter_by.name }}</strong>
+    {% endif %}
   </button>
   <ul class="dropdown-menu" role="menu">
     <li class="dropdown-title">
@@ -11,7 +17,13 @@
     {% for filtering in filters %}
     <li>
       <a href="{{ filtering.url }}">
+        {% if filtering.is_label %}
+        <span class="label label-solo{% if filtering.css_class %} label-{{ filtering.css_class }}{% endif %}">
+          {{ filtering.name }}
+        </span>
+        {% else %}
         {{ filtering.name }}
+        {% endif %}
       </a>
     </li>
     {% endfor %}

+ 13 - 2
misago/threads/models/prefix.py

@@ -37,18 +37,29 @@ class PrefixManager(models.Manager):
 
 
 class Prefix(models.Model):
-    forums = models.ManyToManyField('misago_forums.Forum',
-                                    related_name='prefixes')
+    forums = models.ManyToManyField('misago_forums.Forum')
     name = models.CharField(max_length=255)
     slug = models.SlugField(max_length=255)
     css_class = models.CharField(max_length=255, null=True, blank=True)
 
     objects = PrefixManager()
 
+    def save(self, *args, **kwargs):
+        if self.pk:
+            self.strip_inavailable_prefixes()
+        Prefix.objects.clear_cache()
+        return super(Prefix, self).save(*args, **kwargs)
+
     def delete(self, *args, **kwargs):
         Prefix.objects.clear_cache()
         return super(Prefix, self).delete(*args, **kwargs)
 
+    def strip_inavailable_prefixes(self):
+        qs = self.thread_set
+        if self.forums:
+            qs = qs.exclude(forum__in=self.forums.all())
+        qs.update(prefix=None)
+
     def set_name(self, name):
         self.name = name
         self.slug = slugify(name)

+ 52 - 23
misago/threads/views/generic/forum.py

@@ -8,7 +8,7 @@ from misago.forums.lists import get_forums_list, get_forum_path
 
 from misago.threads.posting import (PostingInterrupt, EditorFormset,
                                     START, REPLY, EDIT)
-from misago.threads.models import ANNOUNCEMENT, Thread
+from misago.threads.models import ANNOUNCEMENT, Thread, Prefix
 from misago.threads.views.generic.threads import OrderThreadsMixin, ThreadsView
 
 
@@ -16,14 +16,17 @@ __all__ = ['FilterThreadsMixin', 'ForumView']
 
 
 class FilterThreadsMixin(object):
-    def get_filter_name(self, filters, filter_by):
+    def get_filter_dict(self, filters, filter_by):
         if filters:
             if filter_by:
                 for filtering in filters:
-                    if filtering[0] == filter_by:
-                        return filtering[1]
+                    if filtering['type'] == filter_by:
+                        return filtering
             else:
-                return _("All threads")
+                return {
+                    'name': _("All threads"),
+                    'is_label': False,
+                }
         else:
             return None
 
@@ -31,20 +34,20 @@ class FilterThreadsMixin(object):
         url_kwargs = links_params.copy()
         dicts = []
 
-        if filters and exclude_filter:
+        if exclude_filter:
             url_kwargs.pop('show', None)
             dicts.append({
                 'url': reverse(self.link_name, kwargs=url_kwargs),
                 'name': _("All threads"),
+                'is_label': False,
             })
 
         for filtering in filters:
-            if filtering[0] != exclude_filter:
-                url_kwargs['show'] = filtering[0]
-                dicts.append({
-                    'url': reverse(self.link_name, kwargs=url_kwargs),
-                    'name': filtering[1],
-                })
+            if filtering['type'] != exclude_filter:
+                filter_dict = filtering.copy()
+                url_kwargs['show'] = filtering['type']
+                filter_dict['url'] = reverse(self.link_name, kwargs=url_kwargs)
+                dicts.append(filter_dict)
 
         return dicts
 
@@ -59,7 +62,7 @@ class ForumView(FilterThreadsMixin, OrderThreadsMixin, ThreadsView):
                     order_by=None, filter_by=None):
         org_queryset = self.get_threads_queryset(request, forum)
         queryset = self.filter_all_querysets(request, forum, org_queryset)
-        queryset = self.set_custom_filter(request, queryset, filter_by)
+        queryset = self.set_custom_filter(request, forum, queryset, filter_by)
 
         announcements_qs = queryset.filter(weight=ANNOUNCEMENT)
         threads_qs = queryset.filter(weight__lt=ANNOUNCEMENT)
@@ -137,7 +140,7 @@ class ForumView(FilterThreadsMixin, OrderThreadsMixin, ThreadsView):
 
         return queryset
 
-    def set_custom_filter(self, request, queryset, filter_by):
+    def set_custom_filter(self, request, forum, queryset, filter_by):
         if filter_by == 'my-threads':
             return queryset.filter(starter_id=request.user.id)
         elif filter_by == 'reported':
@@ -147,7 +150,11 @@ class ForumView(FilterThreadsMixin, OrderThreadsMixin, ThreadsView):
         elif filter_by == 'moderated-posts':
             return queryset.filter(has_moderated_posts=True)
         else:
-            return queryset
+            for prefix in forum.prefixes:
+                if prefix.slug == filter_by:
+                    return queryset.filter(prefix_id=prefix.pk)
+            else:
+                return queryset
 
     def get_threads_queryset(self, request, forum):
         return forum.thread_set.all().order_by('-last_post_id')
@@ -160,18 +167,40 @@ class ForumView(FilterThreadsMixin, OrderThreadsMixin, ThreadsView):
         filters = []
         if request.user.is_authenticated():
             if forum.acl['can_see_all_threads']:
-                filters.append(('my-threads', _("My threads")))
+                filters.append({
+                    'type': 'my-threads',
+                    'name': _("My threads"),
+                    'is_label': False,
+                })
             if forum.acl['can_see_reports']:
-                filters.append(('reported', _("With reported posts")))
+                filters.append({
+                    'type': 'reported',
+                    'name': _("With reported posts"),
+                    'is_label': False,
+                })
             if forum.acl['can_review_moderated_content']:
-                filters.extend((
-                    ('moderated-threads', _("Moderated threads")),
-                    ('moderated-posts', _("With moderated posts")),
-                ))
+                filters.extend(({
+                    'type': 'moderated-threads',
+                    'name': _("Moderated threads"),
+                    'is_label': False,
+                },
+                {
+                    'type': 'moderated-posts',
+                    'name': _("With moderated posts"),
+                    'is_label': False,
+                }))
+        for prefix in forum.prefixes:
+            filters.append({
+                'type': prefix.slug,
+                'name': prefix.name,
+                'is_label': True,
+                'css_class': prefix.css_class,
+            })
         return filters
 
     def dispatch(self, request, *args, **kwargs):
         forum = self.get_forum(request, **kwargs)
+        forum.prefixes = Prefix.objects.get_forum_prefixes(forum)
         links_params = self.get_default_link_params(forum)
 
         if forum.lft + 1 < forum.rght:
@@ -195,7 +224,7 @@ class ForumView(FilterThreadsMixin, OrderThreadsMixin, ThreadsView):
 
         available_filters = self.get_available_filters(request, forum)
         if available_filters and kwargs.get('show'):
-            filter_methods = [f[0] for f in available_filters]
+            filter_methods = [f['type'] for f in available_filters]
             if kwargs.get('show') not in filter_methods:
                 kwargs.pop('show')
                 return redirect('misago:forum', **kwargs)
@@ -218,7 +247,7 @@ class ForumView(FilterThreadsMixin, OrderThreadsMixin, ThreadsView):
             'link_name': self.link_name,
             'links_params': links_params,
             'is_filtering': bool(filter_by),
-            'filter_name': self.get_filter_name(available_filters, filter_by),
+            'filter_by': self.get_filter_dict(available_filters, filter_by),
             'filters': self.get_filters_dicts(
                 available_filters, filter_by, links_params),
             'order_name': self.get_ordering_name(order_by),