Patrick Samson avatar Patrick Samson committed a090f53

Added the setting POSTMAN_DISABLE_USER_EMAILING ; No need for an immediate rejection notification for a User

Comments (0)

Files changed (8)

 # built documents.
 #
 # The short X.Y version.
-version = '1.0'
+version = '1.1'
 # The full version, including alpha/beta/rc tags.
-release = '1.0'
+release = '1.1'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.

docs/notification.rst

 
 For users
 ---------
+Special case: In case of a rejection by the auto moderation feature, the user is immediately aware of it,
+so there is no need for a notification in addition.
+
 If a notifier application is configured (see :ref:`optional_settings`), the following labels are used:
 
 * ``postman_rejection`` to notify the sender of the rejection

docs/quickstart.rst

     Set it to True if you do not allow additional recipients when replying.
 
     *Defaults to*: False.
+
+``POSTMAN_DISABLE_USER_EMAILING``
+    Set it to True if you do not want basic email notification to users.
+    This setting does not apply to visitors (refer to ``POSTMAN_DISALLOW_ANONYMOUS``),
+    nor to a notifier application (refer to ``POSTMAN_NOTIFIER_APP``)
+
+    *Defaults to*: False.
     
 ``POSTMAN_AUTO_MODERATE_AS``
     The default moderation status when no auto-moderation functions, if any, were decisive.
     # POSTMAN_DISALLOW_ANONYMOUS = True # default is False
     # POSTMAN_DISALLOW_MULTIRECIPIENTS = True # default is False
     # POSTMAN_DISALLOW_COPIES_ON_REPLY = True # default is False
+    # POSTMAN_DISABLE_USER_EMAILING = True # default is False
     # POSTMAN_AUTO_MODERATE_AS = True # default is None
     # POSTMAN_NOTIFIER_APP = None # default is 'notification'
     # POSTMAN_MAILER_APP = None # default is 'mailer'

postman/__init__.py

 """A messaging application for Django"""
 
 # following PEP 386: N.N[.N]+[{a|b|c|rc}N[.N]+][.postN][.devN]
-VERSION = (1, 0, 1)
+VERSION = (1, 1, 0)
 PREREL = ()
 POST = 0
 DEV = 0
         obj.clean_for_visitor()
         super(MessageAdmin, self).save_model(request, obj, form, change)
         obj.update_parent(form.initial_status)
-        obj.notify_users(form.initial_status)
+        obj.notify_users(form.initial_status, is_auto_moderated=False)
 
 class PendingMessageAdminForm(forms.ModelForm):
     class Meta:

postman/models.py

                         parent.replied_at = None
                     parent.save()
 
-    def notify_users(self, initial_status):
+    def notify_users(self, initial_status, is_auto_moderated=True):
         """Notify the rejection (to sender) or the acceptance (to recipient) of the message."""
         if initial_status == STATUS_PENDING:
             if self.is_rejected():
-                (notify_user if self.sender_id else email_visitor)(self, 'rejection')
+                # Bypass: for an online user, no need to notify when rejection is immediate.
+                # Only useful for a visitor as an archive copy of the message, otherwise lost.
+                if not (self.sender_id and is_auto_moderated):
+                    (notify_user if self.sender_id else email_visitor)(self, 'rejection')
             elif self.is_accepted():
                 (notify_user if self.recipient_id else email_visitor)(self, 'acceptance')
 
 from postman.models import ORDER_BY_KEY, ORDER_BY_MAPPER, Message, PendingMessage,\
     STATUS_PENDING, STATUS_ACCEPTED, STATUS_REJECTED
 from postman.urls import OPTION_MESSAGES
-from postman.utils import format_body, format_subject, notification
+# because of reload()'s, do "from postman.utils import notification" just before needs
+from postman.utils import format_body, format_subject
 
 if not 'pagination' in settings.INSTALLED_APPS:
     try:
     Usual generic tests.
     """
     def test_version(self):
-        self.assertEqual(sys.modules['postman'].__version__, "1.0.1")
+        self.assertEqual(sys.modules['postman'].__version__, "1.1.0")
 
 class BaseTest(TestCase):
     """
             'POSTMAN_DISALLOW_ANONYMOUS',
             'POSTMAN_DISALLOW_MULTIRECIPIENTS',
             'POSTMAN_DISALLOW_COPIES_ON_REPLY',
+            'POSTMAN_DISABLE_USER_EMAILING',
             'POSTMAN_AUTO_MODERATE_AS',
         ):
             if hasattr(settings, a):
                 delattr(settings, a)
-        settings.POSTMAN_NOTIFIER_APP = None
         settings.POSTMAN_MAILER_APP = None
         settings.POSTMAN_AUTOCOMPLETER_APP = {
             'arg_default': 'postman_single', # no default, mandatory to enable the feature
         "Reload some modules after a change in settings."
         clear_url_caches()
         try:
+            reload(sys.modules['postman.utils'])
             reload(sys.modules['postman.forms'])
             reload(sys.modules['postman.views'])
             reload(sys.modules['postman.urls'])
         url = reverse('postman_reply_auto_complete', args=[pk])
         self.assert_(self.client.login(username='foo', password='pass'))
         response = self.client.get(url)
-        # print response.context
         f = response.context['form'].fields['recipients']
         if hasattr(f, 'channel'):
             self.assertEqual(f.channel, 'postman_multiple')
         # note: accepted -> pending, with no other suitable reply
         # is covered in the accepted -> rejected case
 
-    def check_notification(self, m, mail_number, email=None, notice_label=None):
+    def check_notification(self, m, mail_number, email=None, is_auto_moderated=True, notice_label=None):
         "Check number of mails, recipient, and notice creation."
-        m.notify_users(STATUS_PENDING)
+        m.notify_users(STATUS_PENDING, is_auto_moderated)
         self.assertEqual(len(mail.outbox), mail_number)
         if mail_number:
             self.assertEqual(mail.outbox[0].to, [email])
+        from utils import notification
         if notification and notice_label:
             notice = notification.Notice.objects.get()
             self.assertEqual(notice.notice_type.label, notice_label)
 
     def test_notification_rejection_visitor(self):
-        "Test notify_users() for rejection, from a visitor."
+        "Test notify_users() for rejection, sender is a visitor."
         m = Message.objects.create(subject='s', moderation_status=STATUS_REJECTED, email=self.email, recipient=self.user2)
         self.check_notification(m, 1, self.email)
 
     def test_notification_rejection_user(self):
-        "Test notify_users() for rejection, from a User."
+        "Test notify_users() for rejection, sender is a User."
         m = Message.objects.create(subject='s', moderation_status=STATUS_REJECTED, sender = self.user1, recipient=self.user2)
-        self.check_notification(m, 1, self.user1.email, notice_label='postman_rejection')
+        self.check_notification(m, 1, self.user1.email, is_auto_moderated=False, notice_label='postman_rejection')
+
+    def test_notification_rejection_user_auto_moderated(self):
+        "Test notify_users() for rejection, sender is a User, and is alerted online."
+        m = Message.objects.create(subject='s', moderation_status=STATUS_REJECTED, sender = self.user1, recipient=self.user2)
+        self.check_notification(m, 0, is_auto_moderated=True)
 
     def test_notification_rejection_user_inactive(self):
-        "Test notify_users() for rejection, from a User, but must be active."
+        "Test notify_users() for rejection, sender is a User, but must be active."
         m = Message.objects.create(subject='s', moderation_status=STATUS_REJECTED, sender = self.user1, recipient=self.user2)
         self.user1.is_active = False
-        self.check_notification(m, 0, notice_label='postman_rejection')
+        self.check_notification(m, 0, is_auto_moderated=False, notice_label='postman_rejection')
+
+    def test_notification_rejection_user_disable(self):
+        "Test notify_users() for rejection, sender is a User, but emailing is disabled."
+        m = Message.objects.create(subject='s', moderation_status=STATUS_REJECTED, sender = self.user1, recipient=self.user2)
+        settings.POSTMAN_DISABLE_USER_EMAILING = True
+        settings.POSTMAN_NOTIFIER_APP = None
+        self.reload_modules()
+        self.check_notification(m, 0, is_auto_moderated=False)
 
     def test_notification_acceptance_visitor(self):
-        "Test notify_users() for acceptance, to a visitor."
+        "Test notify_users() for acceptance, recipient is a visitor."
         m = Message.objects.create(subject='s', moderation_status=STATUS_ACCEPTED, sender=self.user1, email=self.email)
         self.check_notification(m, 1, self.email)
 
     def test_notification_acceptance_user(self):
-        "Test notify_users() for acceptance, to a User."
+        "Test notify_users() for acceptance, recipient is a User."
         m = Message.objects.create(subject='s', moderation_status=STATUS_ACCEPTED, sender=self.user1, recipient = self.user2)
         self.check_notification(m, 1, self.user2.email, notice_label='postman_message')
 
     def test_notification_acceptance_user_inactive(self):
-        "Test notify_users() for acceptance, to a User, but must be active."
+        "Test notify_users() for acceptance, recipient is a User, but must be active."
         m = Message.objects.create(subject='s', moderation_status=STATUS_ACCEPTED, sender=self.user1, recipient = self.user2)
         self.user2.is_active = False
         self.check_notification(m, 0, notice_label='postman_message')
 
+    def test_notification_acceptance_user_disable(self):
+        "Test notify_users() for acceptance, recipient is a User, but emailing is disabled."
+        m = Message.objects.create(subject='s', moderation_status=STATUS_ACCEPTED, sender=self.user1, recipient = self.user2)
+        settings.POSTMAN_DISABLE_USER_EMAILING = True
+        settings.POSTMAN_NOTIFIER_APP = None
+        self.reload_modules()
+        self.check_notification(m, 0, notice_label='postman_message')
+
     def test_notification_acceptance_reply(self):
-        "Test notify_users() for acceptance, for a reply, to a User."
+        "Test notify_users() for acceptance, for a reply, recipient is a User."
         p = Message.objects.create(subject='s', moderation_status=STATUS_ACCEPTED, sender=self.user2, recipient=self.user1)
         m = Message.objects.create(subject='s', moderation_status=STATUS_ACCEPTED, sender=self.user1, recipient=self.user2,
             parent=p, thread=p)
 else:
     from django.core.mail import send_mail
 
+# to disable email notification to users
+DISABLE_USER_EMAILING = getattr(settings, 'POSTMAN_DISABLE_USER_EMAILING', False)
+
 # default wrap width; referenced in forms.py
 WRAP_WIDTH = 55
 
     # Email subject *must not* contain newlines
     subject = ''.join(subject.splitlines())
     message = render_to_string(message_template, ctx_dict)
-    if settings.DEBUG and getattr(settings, 'DEV_DEBUG', False):
-        print "email from:", settings.DEFAULT_FROM_EMAIL, " - to:", recipient_list, " - subject:", subject
-        print message
-    else:
-        send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list, fail_silently=True)
+    # during the development phase, consider using the setting: EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+    send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, recipient_list, fail_silently=True)
 
 def email_visitor(object, action):
     """Email a visitor."""
     if notification:
         notification.send(users=[user], label=label, extra_context={'message': object, 'action': action})
     else:
-        if user.email and user.is_active:
+        if not DISABLE_USER_EMAILING and user.email and user.is_active:
             email('postman/email_user_subject.txt', 'postman/email_user.txt', [user.email], object, action)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.