Rafał Pitoń 10 лет назад
Родитель
Сommit
70790d23d1

+ 6 - 0
misago/conf/defaults.py

@@ -202,6 +202,12 @@ MISAGO_POSTING_MIDDLEWARES = (
     'misago.threads.posting.savechanges.SaveChangesMiddleware',
 )
 
+MISAGO_THREAD_TYPES = (
+    'misago.threads.threadtypes.forumthread.ForumThread',
+    'misago.threads.threadtypes.privatethread.PrivateThread',
+    'misago.threads.threadtypes.report.Report',
+)
+
 
 # Register Misago directories
 

+ 13 - 22
misago/forums/models.py

@@ -13,6 +13,8 @@ from misago.conf import settings
 from misago.core.cache import cache
 from misago.core.utils import slugify
 
+from misago.threads import threadtypes
+
 
 CACHE_NAME = 'misago_forums_tree'
 FORUMS_TREE_ID = 1
@@ -83,13 +85,16 @@ class Forum(MPTTModel):
 
     objects = ForumManager()
 
-    def __unicode__(self):
-        if self.special_role == 'root_category':
-            return unicode(_('None (will become top level category)'))
-        elif self.special_role == 'private_threads':
-            return unicode(_('Private Threads'))
+    @property
+    def thread_type(self):
+        if self.special_role == 'root_category' or not self.special_role:
+            type_name = 'forum'
         else:
-            return self.name
+            type_name = self.special_role
+        return threadtypes.get(type_name)
+
+    def __unicode__(self):
+        return self.thread_type.get_forum_name(self)
 
     def lock(self):
         return Forum.objects.select_for_update().get(id=self.id)
@@ -140,24 +145,10 @@ class Forum(MPTTModel):
         return urlparse(self.redirect_url).hostname
 
     def get_absolute_url(self):
-        if self.special_role == 'private_threads':
-            return reverse('misago:private_threads')
-        else:
-            if self.level == 1:
-                formats = (reverse('misago:index'), self.slug, self.id)
-                return '%s#%s-%s' % formats
-            else:
-                return reverse('misago:%s' % self.role, kwargs={
-                    'forum_id': self.id, 'forum_slug': self.slug
-                })
+        return self.thread_type.get_forum_absolute_url(self)
 
     def get_new_thread_url(self):
-        if self.special_role == 'private_threads':
-            return reverse('misago:private_thread_new')
-        else:
-            return reverse('misago:thread_new' % self.role, kwargs={
-                'forum_id': self.id, 'forum_slug': self.slug
-            })
+        return self.thread_type.get_new_thread_url(self)
 
     def set_name(self, name):
         self.name = name

+ 1 - 1
misago/templates/misago/thread/events.html

@@ -25,7 +25,7 @@
     {% endif %}
 
     {% if forum.acl.can_hide_events %}
-    <form action="{% url 'misago:edit_event' event_id=event.id %}" class="event-form" method="post">
+    <form action="{{ event.get_edit_url }}" class="event-form" method="post">
       {% csrf_token %}
       {% if event.is_hidden %}
       <button type="submit" class="btn btn-default btn-flat btn-sm event-toggle">

+ 4 - 4
misago/templates/misago/thread/post.html

@@ -113,7 +113,7 @@
           {% endif %}
 
           {% if post.acl.can_unhide %}
-          <form action="{% url 'misago:unhide_post' post_id=post.id %}" method="post">
+          <form action="{{ post.get_unhide_url }}" method="post">
             {% csrf_token %}
             <button type="submit" class="btn btn-default btn-flat pull-right">
               <span class="fa fa-eye">
@@ -123,7 +123,7 @@
           {% endif %}
 
           {% if post.acl.can_hide %}
-          <form action="{% url 'misago:hide_post' post_id=post.id %}" method="post">
+          <form action="{{ post.get_hide_url }}" method="post">
             {% csrf_token %}
             <button type="submit" class="btn btn-warning btn-flat pull-right">
               <span class="fa fa-eye-slash">
@@ -133,7 +133,7 @@
           {% endif %}
 
           {% if post.acl.can_delete %}
-          <form action="{% url 'misago:delete_post' post_id=post.id %}" method="post" data-prompt="{% trans "Are you sure you want to delete this post?" %}">
+          <form action="{{ post.get_delete_url }}" method="post" data-prompt="{% trans "Are you sure you want to delete this post?" %}">
             {% csrf_token %}
             <button type="submit" class="btn btn-danger btn-flat pull-right">
               <span class="fa fa-times">
@@ -151,7 +151,7 @@
           </form>
 
           {% if post.acl.can_approve %}
-          <form action="{% url 'misago:approve_post' post_id=post.id %}" method="post">
+          <form action="{{ post.get_approve_url }}" method="post">
             {% csrf_token %}
             <button type="submit" class="btn btn-success btn-flat pull-right">
               <span class="fa fa-check">

+ 2 - 29
misago/threads/goto.py

@@ -38,41 +38,14 @@ def get_post_page(posts, post_qs):
 
 
 def hashed_reverse(thread, post, page=1):
-    link_name = thread.get_url_name()
-
-    if page > 1:
-        post_url = reverse(link_name, kwargs={
-            'thread_id': thread.id,
-            'thread_slug': thread.slug,
-            'page': page
-        })
-    else:
-        post_url = reverse(link_name, kwargs={
-            'thread_id': thread.id,
-            'thread_slug': thread.slug
-        })
-
-    return '%s#post-%s' % (post_url, post.pk)
+    return thread.get_post_url(post.pk, page)
 
 
 def last(user, thread):
     posts, qs = posts_queryset(user, thread)
     thread_pages = get_thread_pages(posts)
 
-    link_name = thread.get_url_name()
-    if thread_pages > 1:
-        post_url = reverse(link_name, kwargs={
-            'thread_id': thread.id,
-            'thread_slug': thread.slug,
-            'page': thread_pages
-        })
-    else:
-        post_url = reverse(link_name, kwargs={
-            'thread_id': thread.id,
-            'thread_slug': thread.slug
-        })
-
-    return '%s#post-%s' % (post_url, thread.last_post_id)
+    return thread.get_post_url(thread.last_post_id, thread_pages)
 
 
 def get_post_link(posts, qs, thread, post):

+ 8 - 0
misago/threads/models/event.py

@@ -3,6 +3,7 @@ from django.utils import timezone
 
 from misago.conf import settings
 
+from misago.threads import threadtypes
 from misago.threads.checksums import is_event_valid
 
 
@@ -27,3 +28,10 @@ class Event(models.Model):
         self.author = user
         self.author_name = user.username
         self.author_slug = user.slug
+
+    @property
+    def thread_type(self):
+        return self.forum.thread_type
+
+    def get_edit_url(self):
+        return self.thread_type.get_event_edit_url(self)

+ 19 - 20
misago/threads/models/post.py

@@ -5,6 +5,7 @@ from django.utils import timezone
 
 from misago.conf import settings
 
+from misago.threads import threadtypes
 from misago.threads.checksums import update_post_checksum, is_post_valid
 
 
@@ -49,13 +50,6 @@ class Post(models.Model):
     def __unicode__(self):
         return '%s...' % self.original[10:].strip()
 
-    def get_absolute_url(self):
-        return reverse(self.thread.get_url_name('post'), kwargs={
-            'thread_slug': self.thread.slug,
-            'thread_id': self.thread.id,
-            'post_id': self.id
-        })
-
     def delete(self, *args, **kwargs):
         from misago.threads.signals import delete_post
         delete_post.send(sender=self)
@@ -91,22 +85,27 @@ class Post(models.Model):
         self.thread = new_thread
         move_post.send(sender=self)
 
+    @property
+    def thread_type(self):
+        return self.forum.thread_type
+
     def get_absolute_url(self):
-        return reverse(self.thread.get_url_name('post'), kwargs={
-            'thread_slug': self.thread.slug,
-            'thread_id': self.thread.id,
-            'post_id': self.id
-        })
-
-    def get_edit_url(self):
-        return reverse('misago:edit_post', kwargs={
-            'forum_id': self.forum_id,
-            'thread_id': self.thread_id,
-            'post_id': self.id
-        })
+        return self.thread_type.get_post_absolute_url(self)
 
     def get_quote_url(self):
-        return reverse('misago:quote_post', kwargs={'post_id': self.id})
+        return self.thread_type.get_post_quote_url(self)
+
+    def get_approve_url(self):
+        return self.thread_type.get_post_approve_url(self)
+
+    def get_unhide_url(self):
+        return self.thread_type.get_post_unhide_url(self)
+
+    def get_hide_url(self):
+        return self.thread_type.get_post_hide_url(self)
+
+    def get_delete_url(self):
+        return self.thread_type.get_post_delete_url(self)
 
     @property
     def short(self):

+ 15 - 30
misago/threads/models/thread.py

@@ -129,49 +129,34 @@ class Thread(models.Model, PrivateThreadMixin):
             self.set_last_post(first_post)
 
     @property
-    def link_prefix(self):
-        if self.forum.special_role == 'private_threads':
-            return 'private_thread'
-        else:
-            return 'thread'
+    def thread_type(self):
+        return self.forum.thread_type
 
-    def get_url_name(self, suffix=None):
-        link = 'misago:%s' % self.link_prefix
-        if suffix:
-            link = '%s_%s' % (link, suffix)
-        return link
+    def get_absolute_url(self):
+        return self.thread_type.get_thread_absolute_url(self)
 
-    def get_url(self, suffix=None):
-        return reverse(self.get_url_name(suffix), kwargs={
-            'thread_slug': self.slug,
-            'thread_id': self.id
-        })
+    def get_post_url(self, post, page):
+        try:
+            post_id = post.id
+        except AttributeError:
+            post_id = post
 
-    def get_absolute_url(self):
-        return self.get_url()
+        return self.thread_type.get_thread_post_url(self, post_id, page)
 
     def get_last_reply_url(self):
-        return self.get_url('last')
+        return self.thread_type.get_thread_last_reply_url(self)
 
     def get_new_reply_url(self):
-        return self.get_url('new')
+        return self.thread_type.get_thread_new_reply_url(self)
 
     def get_moderated_url(self):
-        return self.get_url('moderated')
+        return self.thread_type.get_thread_moderated_url(self)
 
     def get_reported_url(self):
-        return self.get_url('reported')
+        return self.thread_type.get_thread_reported_url(self)
 
     def get_reply_api_url(self):
-        if self.forum.special_role == 'private_threads':
-            return reverse('misago:reply_private_thread', kwargs={
-                'thread_id': self.id,
-            })
-        else:
-            return reverse('misago:reply_thread', kwargs={
-                'forum_id': self.forum.id,
-                'thread_id': self.id,
-            })
+        return self.thread_type.get_reply_url(self)
 
     def set_title(self, title):
         self.title = title

+ 30 - 0
misago/threads/threadtypes/__init__.py

@@ -0,0 +1,30 @@
+from importlib import import_module
+
+from django.conf import settings
+from django.utils.translation import ugettext_lazy as _
+
+
+class ThreadTypeBase(object):
+    type_name = 'undefined'
+
+    def get_forum_name(self, forum):
+        return forum.name
+
+
+def load_types(types_list):
+    loaded_types = {}
+    for path in types_list:
+        module = import_module('.'.join(path.split('.')[:-1]))
+        type_obj = getattr(module, path.split('.')[-1])()
+        loaded_types[type_obj.type_name] = type_obj
+    return loaded_types
+
+
+THREAD_TYPES = load_types(settings.MISAGO_THREAD_TYPES)
+
+
+def get(thread_type):
+    try:
+        return THREAD_TYPES[thread_type]
+    except KeyError:
+        raise KeyError("thread type %s is undefined" % thread_type)

+ 119 - 0
misago/threads/threadtypes/forumthread.py

@@ -0,0 +1,119 @@
+from django.core.urlresolvers import reverse
+from django.utils.translation import ugettext_lazy as _
+
+from misago.threads.threadtypes import ThreadTypeBase
+
+
+class ForumThread(ThreadTypeBase):
+    type_name = 'forum'
+
+    def get_forum_name(self, forum):
+        if forum.special_role == 'root_category':
+            return _('None (will become top level category)')
+        else:
+            return forum.name
+
+    def get_forum_absolute_url(self, forum):
+        if forum.level == 1:
+            formats = (reverse('misago:index'), forum.slug, forum.id)
+            return '%s#%s-%s' % formats
+        else:
+            return reverse('misago:%s' % forum.role, kwargs={
+                'forum_id': forum.id, 'forum_slug': forum.slug
+            })
+
+    def get_new_thread_url(self, forum):
+        return reverse('misago:thread_new', kwargs={
+            'forum_id': forum.id, 'forum_slug': forum.slug
+        })
+
+    def get_reply_url(self, thread):
+        return reverse('misago:reply_thread', kwargs={
+            'forum_id': thread.forum.id,
+            'thread_id': thread.id,
+        })
+
+    def get_edit_post_url(self, post):
+        return reverse('misago:edit_post', kwargs={
+            'forum_id': post.forum_id,
+            'thread_id': post.thread_id,
+            'post_id': post.id
+        })
+
+    def get_thread_absolute_url(self, thread):
+        return reverse('misago:thread', kwargs={
+            'thread_slug': thread.slug,
+            'thread_id': thread.id
+        })
+
+    def get_thread_post_url(self, thread, post_id, page):
+        kwargs = {
+            'thread_slug': thread.slug,
+            'thread_id': thread.id,
+        }
+        if page > 1:
+            kwargs['page'] = page
+
+        url = reverse('misago:thread', kwargs=kwargs)
+        return '%s#post-%s' % (url, post_id)
+
+    def get_thread_last_reply_url(self, thread):
+        return reverse('misago:thread_last', kwargs={
+            'thread_slug': thread.slug,
+            'thread_id': thread.id
+        })
+
+    def get_thread_new_reply_url(self, thread):
+        return reverse('misago:thread_new', kwargs={
+            'thread_slug': thread.slug,
+            'thread_id': thread.id
+        })
+
+    def get_thread_moderated_url(self, thread):
+        return reverse('misago:thread_moderated', kwargs={
+            'thread_slug': thread.slug,
+            'thread_id': thread.id
+        })
+
+    def get_thread_reported_url(self, thread):
+        return reverse('misago:thread_reported', kwargs={
+            'thread_slug': thread.slug,
+            'thread_id': thread.id
+        })
+
+    def get_post_absolute_url(self, post):
+        return reverse('misago:thread_post', kwargs={
+            'thread_slug': post.thread.slug,
+            'thread_id': post.thread.id,
+            'post_id': post.id
+        })
+
+    def get_post_quote_url(self, post):
+        return reverse('misago:quote_post', kwargs={
+            'post_id': post.id
+        })
+
+    def get_post_approve_url(self, post):
+        return reverse('misago:approve_post', kwargs={
+            'post_id': post.id
+        })
+
+    def get_post_unhide_url(self, post):
+        return reverse('misago:unhide_post', kwargs={
+            'post_id': post.id
+        })
+
+    def get_post_hide_url(self, post):
+        return reverse('misago:hide_post', kwargs={
+            'post_id': post.id
+        })
+
+    def get_post_delete_url(self, post):
+        return reverse('misago:delete_post', kwargs={
+            'post_id': post.id
+        })
+
+    def get_event_edit_url(self, event):
+        return reverse('misago:edit_event', kwargs={
+            'event_id': event.id
+        })

+ 102 - 0
misago/threads/threadtypes/privatethread.py

@@ -0,0 +1,102 @@
+from django.core.urlresolvers import reverse
+from django.utils.translation import ugettext_lazy as _
+
+from misago.threads.threadtypes import ThreadTypeBase
+
+
+class PrivateThread(ThreadTypeBase):
+    type_name = 'private_threads'
+
+    def get_forum_name(self, forum):
+        return _('Private Threads')
+
+    def get_forum_absolute_url(self, forum):
+        return reverse('misago:private_threads')
+
+    def get_new_thread_url(self, forum):
+        return reverse('misago:private_thread_new')
+
+    def get_reply_url(self, thread):
+        return reverse('misago:reply_private_thread', kwargs={
+            'thread_id': thread.id,
+        })
+
+    def get_edit_post_url(self, post):
+        return reverse('misago:edit_private_post', kwargs={
+            'forum_id': post.forum_id,
+            'thread_id': post.thread_id,
+            'post_id': post.id
+        })
+
+    def get_thread_absolute_url(self, thread):
+        return reverse('misago:private_thread', kwargs={
+            'thread_slug': thread.slug,
+            'thread_id': thread.id
+        })
+
+    def get_thread_post_url(self, thread, post_id, page):
+        kwargs = {
+            'thread_slug': thread.slug,
+            'thread_id': thread.id,
+        }
+        if page > 1:
+            kwargs['page'] = page
+
+        url = reverse('misago:private_thread', kwargs=kwargs)
+        return '%s#post-%s' % (url, post_id)
+
+    def get_thread_last_reply_url(self, thread):
+        return reverse('misago:private_thread_last', kwargs={
+            'thread_slug': thread.slug,
+            'thread_id': thread.id
+        })
+
+    def get_thread_new_reply_url(self, thread):
+        return reverse('misago:private_thread_new', kwargs={
+            'thread_slug': thread.slug,
+            'thread_id': thread.id
+        })
+
+    def get_thread_moderated_url(self, thread):
+        return reverse('misago:private_thread_moderated', kwargs={
+            'thread_slug': thread.slug,
+            'thread_id': thread.id
+        })
+
+    def get_thread_reported_url(self, thread):
+        return reverse('misago:private_thread_reported', kwargs={
+            'thread_slug': thread.slug,
+            'thread_id': thread.id
+        })
+
+    def get_post_absolute_url(self, post):
+        return reverse('misago:private_thread_post', kwargs={
+            'thread_slug': post.thread.slug,
+            'thread_id': post.thread.id,
+            'post_id': post.id
+        })
+
+    def get_post_quote_url(self, post):
+        return reverse('misago:quote_private_post', kwargs={
+            'post_id': post.id
+        })
+
+    def get_post_unhide_url(self, post):
+        return reverse('misago:unhide_private_post', kwargs={
+            'post_id': post.id
+        })
+
+    def get_post_hide_url(self, post):
+        return reverse('misago:hide_private_post', kwargs={
+            'post_id': post.id
+        })
+
+    def get_post_delete_url(self, post):
+        return reverse('misago:delete_private_post', kwargs={
+            'post_id': post.id
+        })
+
+    def get_event_edit_url(self, event):
+        return reverse('misago:edit_private_event', kwargs={
+            'event_id': event.id
+        })

+ 11 - 0
misago/threads/threadtypes/report.py

@@ -0,0 +1,11 @@
+from django.core.urlresolvers import reverse
+from django.utils.translation import ugettext_lazy as _
+
+from misago.threads.threadtypes import ThreadTypeBase
+
+
+class Report(ThreadTypeBase):
+    type_name = 'reports'
+
+    def get_forum_name(self, forum):
+        return _('Reports')

+ 6 - 5
misago/threads/views/generic/forum/view.py

@@ -19,7 +19,6 @@ class ForumView(ThreadsView):
     Basic view for forum threads lists
     """
     template = 'misago/threads/forum.html'
-    link_name = 'misago:forum'
 
     Threads = ForumThreads
     Sorting = Sorting
@@ -40,14 +39,16 @@ class ForumView(ThreadsView):
         page_number = kwargs.pop('page', None)
         cleaned_kwargs = self.clean_kwargs(request, kwargs)
 
-        sorting = self.Sorting(self.link_name, cleaned_kwargs)
+        link_name = request.resolver_match.view_name
+
+        sorting = self.Sorting(link_name, cleaned_kwargs)
         cleaned_kwargs = sorting.clean_kwargs(cleaned_kwargs)
 
-        filtering = self.Filtering(forum, self.link_name, cleaned_kwargs)
+        filtering = self.Filtering(forum, link_name, cleaned_kwargs)
         cleaned_kwargs = filtering.clean_kwargs(cleaned_kwargs)
 
         if cleaned_kwargs != kwargs:
-            return redirect(self.link_name, **cleaned_kwargs)
+            return redirect(link_name, **cleaned_kwargs)
 
         threads = self.Threads(request.user, forum)
         sorting.sort(threads)
@@ -60,7 +61,7 @@ class ForumView(ThreadsView):
                 return response
 
         return self.render(request, {
-            'link_name': self.link_name,
+            'link_name': link_name,
             'links_params': cleaned_kwargs,
 
             'forum': forum,

+ 1 - 1
misago/threads/views/generic/thread/view.py

@@ -98,7 +98,7 @@ class ThreadView(ViewBase):
             thread_reply_message = unicode(e)
 
         return self.render(request, {
-            'link_name': thread.get_url_name(),
+            'link_name': request.resolver_match.view_name,
             'links_params': {
                 'thread_id': thread.id, 'thread_slug': thread.slug
             },

+ 5 - 4
misago/threads/views/generic/threads/view.py

@@ -26,20 +26,21 @@ class ThreadsView(ViewBase):
         return cleaned_kwargs
 
     def dispatch(self, request, *args, **kwargs):
+        link_name = request.resolver_match.view_name
         page_number = kwargs.pop('page', None)
         cleaned_kwargs = self.clean_kwargs(request, kwargs)
 
         if self.Sorting:
-            sorting = self.Sorting(self.link_name, cleaned_kwargs)
+            sorting = self.Sorting(link_name, cleaned_kwargs)
             cleaned_kwargs = sorting.clean_kwargs(cleaned_kwargs)
 
         if self.Filtering:
             filtering = self.Filtering(
-                request.user, self.link_name, cleaned_kwargs)
+                request.user, link_name, cleaned_kwargs)
             cleaned_kwargs = filtering.clean_kwargs(cleaned_kwargs)
 
         if cleaned_kwargs != kwargs:
-            return redirect(self.link_name, **cleaned_kwargs)
+            return redirect(link_name, **cleaned_kwargs)
 
         threads = self.Threads(request.user)
 
@@ -59,7 +60,7 @@ class ThreadsView(ViewBase):
 
         # build template context
         context = {
-            'link_name': self.link_name,
+            'link_name': link_name,
             'links_params': cleaned_kwargs,
 
             'threads': threads.list(page_number),

+ 1 - 5
misago/users/validators.py

@@ -151,9 +151,6 @@ def validate_gmail_email(ip, username, email):
 """
 Registration validation
 """
-REGISTRATION_VALIDATORS = []
-
-
 def load_registration_validators(validators_list):
     loaded_validators = []
     for path in validators_list:
@@ -163,8 +160,7 @@ def load_registration_validators(validators_list):
 
 
 validators_list = settings.MISAGO_NEW_REGISTRATIONS_VALIDATORS
-if validators_list:
-    REGISTRATION_VALIDATORS = load_registration_validators(validators_list)
+REGISTRATION_VALIDATORS = load_registration_validators(validators_list)
 
 
 def validate_new_registration(ip, username, email, validators=None):