Browse Source

#477: start private thread

Rafał Pitoń 10 years ago
parent
commit
c9ea2241d0

+ 1 - 1
misago/templates/misago/posting/replyform.html

@@ -9,7 +9,7 @@
 <div class="thread-title">
 <div class="thread-title">
   <div class="row">
   <div class="row">
     <div class="col-md-{{ supporting_forms.after_title|yesno:"9,12" }}">
     <div class="col-md-{{ supporting_forms.after_title|yesno:"9,12" }}">
-      <input class="textinput textInput form-control title-input" id="{{ form.title.auto_id }}" name="title" type="text" {% if form.title.value %}value="{{ form.title.value }}"{% endif %} placeholder="{% trans "Thread title..." %}">
+      <input class="textinput textInput form-control title-input" id="{{ form.title.auto_id }}" name="{{ form.title.html_name }}" type="text" {% if form.title.value %}value="{{ form.title.value }}"{% endif %} placeholder="{% trans "Thread title..." %}">
     </div>
     </div>
 
 
     {% if supporting_forms.after_title %}
     {% if supporting_forms.after_title %}

+ 2 - 2
misago/templates/misago/posting/threadparticipantsform.html

@@ -1,6 +1,6 @@
 {% load i18n %}
 {% load i18n %}
 <div class="thread-participants">
 <div class="thread-participants">
-  <input id="{{ form.users.auto_id }}" name="users" type="hidden" {% if form.users.value %}value="{{ form.users.value }}"{% endif %}>
+  <input id="{{ form.users.auto_id }}" name="{{ form.users.html_name }}" type="hidden">
   <ul class="list-unstyled users-list"></ul>
   <ul class="list-unstyled users-list"></ul>
-  <input class="textinput textInput form-control user-input" id="{{ form.title.auto_id }}" name="title" type="text" placeholder="{% trans "User to message..." %}" data-api-url="{% url 'misago:api_suggestion_engine' %}">
+  <input class="textinput textInput form-control user-input" type="text" placeholder="{% trans "User to message..." %}" data-api-url="{% url 'misago:api_suggestion_engine' %}">
 </div>
 </div>

+ 46 - 3
misago/threads/forms/posting.py

@@ -1,9 +1,12 @@
+from django.contrib.auth import get_user_model
+from django.core.exceptions import PermissionDenied
 from django.utils.translation import ugettext_lazy as _, ungettext
 from django.utils.translation import ugettext_lazy as _, ungettext
 
 
 from misago.conf import settings
 from misago.conf import settings
 from misago.core import forms
 from misago.core import forms
 from misago.markup import common_flavour
 from misago.markup import common_flavour
 
 
+from misago.threads.permissions import allow_message_user
 from misago.threads.validators import validate_title
 from misago.threads.validators import validate_title
 
 
 
 
@@ -43,7 +46,7 @@ class ReplyForm(forms.Form):
             message = ungettext(
             message = ungettext(
                 "Posted message can't be longer than %(limit)s character.",
                 "Posted message can't be longer than %(limit)s character.",
                 "Posted message can't be longer than %(limit)s characters.",
                 "Posted message can't be longer than %(limit)s characters.",
-                settings.post_length_max,)
+                settings.post_length_max)
             message = message % {'limit': settings.post_length_max}
             message = message % {'limit': settings.post_length_max}
             raise forms.ValidationError(message)
             raise forms.ValidationError(message)
 
 
@@ -99,10 +102,50 @@ class ThreadParticipantsForm(forms.Form):
 
 
     users = forms.CharField(label=_("Invite users to thread"))
     users = forms.CharField(label=_("Invite users to thread"))
 
 
-    def __init__(self, thread=None, *args, **kwargs):
-        self.thread_instance = thread
+    def __init__(self, *args, **kwargs):
+        self.users_cache = []
+        self.user = kwargs.pop('user', None)
+
         super(ThreadParticipantsForm, self).__init__(*args, **kwargs)
         super(ThreadParticipantsForm, self).__init__(*args, **kwargs)
 
 
+    def clean(self):
+        cleaned_data = super(ThreadParticipantsForm, self).clean()
+
+        clean_usernames = []
+        for name in cleaned_data['users'].split(','):
+            clean_name = name.strip().lower()
+            if clean_name == self.user.slug:
+                raise forms.ValidationError(
+                    _("You can't addres message to yourself."))
+            if clean_name not in clean_usernames:
+                clean_usernames.append(clean_name)
+
+        max_participants = self.user.acl['max_private_thread_participants']
+        if max_participants and len(clean_usernames) > max_participants:
+            message = ungettext("You can't start private thread "
+                                "with more than than %(users)s user.",
+                                "You can't start private thread "
+                                "with more than than %(users)s users.",
+                                max_participants)
+            message = message % {'users': max_participants.post_length_max}
+            raise forms.ValidationError(message)
+
+        users_qs = get_user_model().objects.filter(slug__in=clean_usernames)
+        for user in users_qs:
+            try:
+                allow_message_user(self.user, user)
+            except PermissionDenied as e:
+                raise forms.ValidationError(unicode(e))
+            self.users_cache.append(user)
+
+        if len(self.users_cache) != len(clean_usernames):
+            raise forms.ValidationError(
+                _("One or more message recipients could not be found"))
+
+        cleaned_data['users'] = ','.join([u.slug for u in self.users_cache])
+
+        return cleaned_data
+
 
 
 class ThreadLabelFormBase(forms.Form):
 class ThreadLabelFormBase(forms.Form):
     is_supporting = True
     is_supporting = True

+ 6 - 3
misago/threads/posting/__init__.py

@@ -123,10 +123,13 @@ class EditorFormset(object):
         all_forms_valid = True
         all_forms_valid = True
         for form in self.get_forms_list():
         for form in self.get_forms_list():
             if not form.is_valid():
             if not form.is_valid():
-                all_forms_valid = False
-                for error in form.non_field_errors():
-                    self.errors.append(unicode(error))
+                if not form.is_bound:
+                    form_class = form.__class__.__name__
+                    raise ValueError("%s didn't receive any data" % form_class)
 
 
+                all_forms_valid = False
+                for field_errors in form.errors.as_data().values():
+                    self.errors.extend([unicode(e[0]) for e in field_errors])
         return all_forms_valid
         return all_forms_valid
 
 
     def save(self):
     def save(self):

+ 8 - 2
misago/threads/posting/participants.py

@@ -1,14 +1,20 @@
 from misago.threads.forms.posting import ThreadParticipantsForm
 from misago.threads.forms.posting import ThreadParticipantsForm
 from misago.threads.posting import PostingMiddleware, START
 from misago.threads.posting import PostingMiddleware, START
+from misago.threads.models import ThreadParticipant
 
 
 
 
 class ThreadParticipantsFormMiddleware(PostingMiddleware):
 class ThreadParticipantsFormMiddleware(PostingMiddleware):
     def use_this_middleware(self):
     def use_this_middleware(self):
-        return self.is_private
+        return self.is_private and self.mode == START
 
 
     def make_form(self):
     def make_form(self):
         if self.request.method == 'POST':
         if self.request.method == 'POST':
             return ThreadParticipantsForm(
             return ThreadParticipantsForm(
-                self.request.POST, prefix=self.prefix)
+                self.request.POST, user=self.request.user, prefix=self.prefix)
         else:
         else:
             return ThreadParticipantsForm(prefix=self.prefix)
             return ThreadParticipantsForm(prefix=self.prefix)
+
+    def save(self, form):
+        ThreadParticipant.objects.set_owner(self.thread, self.user)
+        for user in form.users_cache:
+            ThreadParticipant.objects.add_participant(self.thread, user)