Browse Source

Add users to private thread from new thread/reply screen. Check if they are not ignoring inviter.

Ralfp 12 years ago
parent
commit
6703d07c4c

+ 3 - 0
misago/acl/permissions/privatethreads.py

@@ -32,6 +32,9 @@ class PrivateThreadsACL(BaseACL):
     def can_participate(self):
     def can_participate(self):
         return self.acl['can_use_private_threads']
         return self.acl['can_use_private_threads']
         
         
+    def can_invite_ignoring(self):
+        return self.acl['can_invite_ignoring']
+        
     def is_mod(self):
     def is_mod(self):
         return self.acl['private_threads_mod']
         return self.acl['private_threads_mod']
 
 

+ 37 - 4
misago/apps/privatethreads/forms.py

@@ -1,11 +1,44 @@
 from django import forms
 from django import forms
-from misago.forms import Form
+from django.utils.translation import ugettext_lazy as _
 from misago.apps.threadtype.posting.forms import (NewThreadForm as NewThreadBaseForm,
 from misago.apps.threadtype.posting.forms import (NewThreadForm as NewThreadBaseForm,
                                                   EditThreadForm as EditThreadBaseForm,
                                                   EditThreadForm as EditThreadBaseForm,
                                                   NewReplyForm as NewReplyBaseForm,
                                                   NewReplyForm as NewReplyBaseForm,
                                                   EditReplyForm as EditReplyBaseForm)
                                                   EditReplyForm as EditReplyBaseForm)
-
-class NewThreadForm(NewThreadBaseForm):
+from misago.forms import Form
+from misago.models import User
+from misago.utils.strings import slugify
+
+class InviteUsersMixin(object):
+    def type_fields(self):
+        self.layout[0][1].append(('invite_users', {'label': _("Invite members to thread"), 'attrs': {'placeholder': _("user1, user2, user3...")}}))
+        self.fields['invite_users'] = forms.CharField(max_length=255, required=False)
+
+    def clean_invite_users(self):
+        self.invite_users = []
+        usernames = []
+        slugs = [self.request.user.username_slug]
+        for username in self.cleaned_data['invite_users'].split(','):
+            username = username.strip()
+            slug = slugify(username)
+            if len(slug) > 3 and not slug in slugs:
+                slugs.append(slug)
+                usernames.append(username)
+                try:
+                    user = User.objects.get(username_slug=slug)
+                    if not user.acl(self.request).private_threads.can_participate():
+                        raise forms.ValidationError(_('%(user)s cannot participate in private threads.') % {'user': user.username})
+                    if (not self.request.acl.private_threads.can_invite_ignoring() and
+                        user.is_ignoring(self.request.user)):
+                        raise forms.ValidationError(_('%(user)s does not wish to participate in your private threads.') % {'user': user.username})
+                    self.invite_users.append(user)
+                except User.DoesNotExist:
+                    raise forms.ValidationError(_('User "%(username)s" could not be found.') % {'username': username})
+            if len(usernames) > 8:
+                raise forms.ValidationError(_('You cannot invite more than 8 members at single time. Post thread and then invite additional members.'))
+        return ', '.join(usernames)
+
+
+class NewThreadForm(NewThreadBaseForm, InviteUsersMixin):
     include_thread_weight = False
     include_thread_weight = False
     include_close_thread = False
     include_close_thread = False
 
 
@@ -15,7 +48,7 @@ class EditThreadForm(EditThreadBaseForm):
     include_close_thread = False
     include_close_thread = False
 
 
 
 
-class NewReplyForm(NewReplyBaseForm):
+class NewReplyForm(NewReplyBaseForm, InviteUsersMixin):
     include_thread_weight = False
     include_thread_weight = False
     include_close_thread = False
     include_close_thread = False
 
 

+ 3 - 0
misago/apps/privatethreads/jumps.py

@@ -61,6 +61,9 @@ class InviteUserView(JumpView, TypeMixin):
                     self.request.messages.set_flash(Message(_('%(user)s is already participating in this thread.') % {'user': user.username}), 'info', 'threads')
                     self.request.messages.set_flash(Message(_('%(user)s is already participating in this thread.') % {'user': user.username}), 'info', 'threads')
             if not acl.private_threads.can_participate():
             if not acl.private_threads.can_participate():
                     self.request.messages.set_flash(Message(_('%(user)s cannot participate in private threads.') % {'user': user.username}), 'info', 'threads')
                     self.request.messages.set_flash(Message(_('%(user)s cannot participate in private threads.') % {'user': user.username}), 'info', 'threads')
+            elif (not self.request.acl.private_threads.can_invite_ignoring() and
+                    user.is_ignoring(self.request.user)):
+                self.request.messages.set_flash(Message(_('%(user)s does not wish to participate in your private threads.') % {'user': user.username}), 'info', 'threads')
             else:
             else:
                 self.thread.participants.add(user)
                 self.thread.participants.add(user)
                 user.email_user(self.request, 'private_thread_invite', _("You've been invited to private thread \"%(thread)s\" by %(user)s") % {'thread': self.thread.name, 'user': self.request.user.username}, {'author': self.request.user, 'thread': self.thread})
                 user.email_user(self.request, 'private_thread_invite', _("You've been invited to private thread \"%(thread)s\" by %(user)s") % {'thread': self.thread.name, 'user': self.request.user.username}, {'author': self.request.user, 'thread': self.thread})

+ 13 - 0
misago/apps/privatethreads/mixins.py

@@ -1,5 +1,6 @@
 from django.core.urlresolvers import reverse
 from django.core.urlresolvers import reverse
 from django.shortcuts import redirect
 from django.shortcuts import redirect
+from django.utils.translation import ugettext as _
 from misago.acl.exceptions import ACLError404
 from misago.acl.exceptions import ACLError404
 
 
 class TypeMixin(object):
 class TypeMixin(object):
@@ -13,6 +14,18 @@ class TypeMixin(object):
         except AttributeError:
         except AttributeError:
             pass
             pass
 
 
+    def invite_users(self, users):
+        sync_last_post = False
+        for user in users:
+            if not user in self.thread.participants.all():
+                self.thread.participants.add(user)
+                user.email_user(self.request, 'private_thread_invite', _("You've been invited to private thread \"%(thread)s\" by %(user)s") % {'thread': self.thread.name, 'user': self.request.user.username}, {'author': self.request.user, 'thread': self.thread})
+                if self.action == 'new_reply':
+                    self.thread.last_post.set_checkpoint(self.request, 'invited', user)
+        if sync_last_post:
+            self.thread.last_post.save(force_update=True)
+
+                
     def whitelist_mentions(self):
     def whitelist_mentions(self):
         participants = self.thread.participants.all()
         participants = self.thread.participants.all()
         mentioned = self.post.mentions.all()
         mentioned = self.post.mentions.all()

+ 7 - 4
misago/apps/privatethreads/posting.py

@@ -14,8 +14,10 @@ class NewThreadView(NewThreadBaseView, TypeMixin):
     def set_forum_context(self):
     def set_forum_context(self):
         self.forum = Forum.objects.get(special='private_threads')
         self.forum = Forum.objects.get(special='private_threads')
 
 
-    def after_form(self):
+    def after_form(self, form):
         self.thread.participants.add(self.request.user)
         self.thread.participants.add(self.request.user)
+        self.invite_users(form.invite_users)
+
         self.whitelist_mentions()
         self.whitelist_mentions()
 
 
     def response(self):
     def response(self):
@@ -29,7 +31,7 @@ class NewThreadView(NewThreadBaseView, TypeMixin):
 class EditThreadView(EditThreadBaseView, TypeMixin):
 class EditThreadView(EditThreadBaseView, TypeMixin):
     form_type = EditThreadForm
     form_type = EditThreadForm
 
 
-    def after_form(self):
+    def after_form(self, form):
         self.whitelist_mentions()
         self.whitelist_mentions()
     
     
     def response(self):
     def response(self):
@@ -40,7 +42,8 @@ class EditThreadView(EditThreadBaseView, TypeMixin):
 class NewReplyView(NewReplyBaseView, TypeMixin):
 class NewReplyView(NewReplyBaseView, TypeMixin):
     form_type = NewReplyForm
     form_type = NewReplyForm
 
 
-    def after_form(self):
+    def after_form(self, form):
+        self.invite_users(form.invite_users)
         self.whitelist_mentions()
         self.whitelist_mentions()
 
 
     def response(self):
     def response(self):
@@ -54,7 +57,7 @@ class NewReplyView(NewReplyBaseView, TypeMixin):
 class EditReplyView(EditReplyBaseView, TypeMixin):
 class EditReplyView(EditReplyBaseView, TypeMixin):
     form_type = EditReplyForm
     form_type = EditReplyForm
 
 
-    def after_form(self):
+    def after_form(self, form):
         self.whitelist_mentions()
         self.whitelist_mentions()
 
 
     def response(self):
     def response(self):

+ 2 - 2
misago/apps/threadtype/posting/base.py

@@ -40,7 +40,7 @@ class PostingBaseView(ViewBase):
                                     post_content=old_post,
                                     post_content=old_post,
                                     )
                                     )
 
 
-    def after_form(self):
+    def after_form(self, form):
         pass
         pass
 
 
     def notify_users(self):
     def notify_users(self):
@@ -105,7 +105,7 @@ class PostingBaseView(ViewBase):
                     if form.is_valid():
                     if form.is_valid():
                         self.post_form(form)
                         self.post_form(form)
                         self.watch_thread()
                         self.watch_thread()
-                        self.after_form()
+                        self.after_form(form)
                         self.notify_users()
                         self.notify_users()
                         return self.response()
                         return self.response()
                     else:
                     else:

+ 11 - 1
templates/cranefly/private_threads/posting.html

@@ -58,13 +58,23 @@
             <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
             <input type="hidden" name="{{ csrf_id }}" value="{{ csrf_token }}">
             {% if 'thread_name' in form.fields %}
             {% if 'thread_name' in form.fields %}
             {{ form_theme.row_widget(form.fields.thread_name, width=8) }}
             {{ form_theme.row_widget(form.fields.thread_name, width=8) }}
+            {% endif %}
+            {% if action == 'new_thread' and 'invite_users' in form.fields %}
+            {{ form_theme.row_widget(form.fields.invite_users, width=8) }}
+            {% endif %}
+            {% if 'thread_name' in form.fields or (action == 'new_thread' and 'invite_users' in form.fields) %}
             <hr>
             <hr>
             <h4>Message Body</h4>
             <h4>Message Body</h4>
             {% endif %}
             {% endif %}
             {{ editor.editor(form.fields.post, get_button(), rows=8, extra=get_extra()) }}
             {{ editor.editor(form.fields.post, get_button(), rows=8, extra=get_extra()) }}
-            {% if 'edit_reason' in form.fields %}
+            {% if 'edit_reason' in form.fields or (action == 'new_reply' and 'invite_users' in form.fields) %}
             <hr>
             <hr>
+            {% if action == 'new_reply' and 'invite_users' in form.fields %}
+            {{ form_theme.row_widget(form.fields.invite_users, width=8) }}
+            {% endif %}
+            {% if 'edit_reason' in form.fields %}
             {{ form_theme.row_widget(form.fields.edit_reason, width=8) }}
             {{ form_theme.row_widget(form.fields.edit_reason, width=8) }}
+            {% endif %}
 
 
             <div class="form-actions">
             <div class="form-actions">
               <button type="submit" class="btn btn-primary">{{ get_button() }}</button>
               <button type="submit" class="btn btn-primary">{{ get_button() }}</button>