diff --git a/django_messages/__init__.py b/django_messages/__init__.py index 4d068f0..471f7f0 100644 --- a/django_messages/__init__.py +++ b/django_messages/__init__.py @@ -1,3 +1,4 @@ VERSION = (0, 5, 1,) __version__ = '.'.join(map(str, VERSION)) -default_app_config = 'django_messages.apps.DjangoMessagesConfig' \ No newline at end of file +default_app_config = 'django_messages.apps.DjangoMessagesConfig' +from . import signals diff --git a/django_messages/admin.py b/django_messages/admin.py index 7511b1a..ea18137 100644 --- a/django_messages/admin.py +++ b/django_messages/admin.py @@ -11,7 +11,7 @@ from notification import models as notification else: notification = None - + from django_messages.models import Message class MessageAdminForm(forms.ModelForm): @@ -75,7 +75,7 @@ def save_model(self, request, obj, form, change): the message is effectively resent to those users. """ obj.save() - + if notification: # Getting the appropriate notice labels for the sender and recipients. if obj.parent_msg is None: @@ -84,7 +84,7 @@ def save_model(self, request, obj, form, change): else: sender_label = 'messages_replied' recipients_label = 'messages_reply_received' - + # Notification for the sender. notification.send([obj.sender], sender_label, {'message': obj,}) @@ -108,5 +108,6 @@ def save_model(self, request, obj, form, change): if notification: # Notification for the recipient. notification.send([user], recipients_label, {'message' : obj,}) - -admin.site.register(Message, MessageAdmin) + +if getattr(settings, 'DJANGO_MESSAGES_ADMIN_PANEL', True): + admin.site.register(Message, MessageAdmin) diff --git a/django_messages/forms.py b/django_messages/forms.py index fd40d1a..19cb462 100644 --- a/django_messages/forms.py +++ b/django_messages/forms.py @@ -1,33 +1,27 @@ from django import forms -from django.conf import settings from django.utils.translation import ugettext_lazy as _ from django.utils import timezone - -if "notification" in settings.INSTALLED_APPS and getattr(settings, 'DJANGO_MESSAGES_NOTIFY', True): - from notification import models as notification -else: - notification = None - from django_messages.models import Message from django_messages.fields import CommaSeparatedUserField +from django_messages import signals + class ComposeForm(forms.Form): + """ A simple default form for private messages. """ recipient = CommaSeparatedUserField(label=_(u"Recipient")) subject = forms.CharField(label=_(u"Subject"), max_length=120) body = forms.CharField(label=_(u"Body"), - widget=forms.Textarea(attrs={'rows': '12', 'cols':'55'})) - - + widget=forms.Textarea(attrs={'rows': '12', 'cols': '55'})) + def __init__(self, *args, **kwargs): recipient_filter = kwargs.pop('recipient_filter', None) super(ComposeForm, self).__init__(*args, **kwargs) if recipient_filter is not None: self.fields['recipient']._recipient_filter = recipient_filter - - + def save(self, sender, parent_msg=None): recipients = self.cleaned_data['recipient'] subject = self.cleaned_data['subject'] @@ -35,22 +29,20 @@ def save(self, sender, parent_msg=None): message_list = [] for r in recipients: msg = Message( - sender = sender, - recipient = r, - subject = subject, - body = body, + sender=sender, + recipient=r, + subject=subject, + body=body, ) if parent_msg is not None: msg.parent_msg = parent_msg parent_msg.replied_at = timezone.now() parent_msg.save() - msg.save() + msg.save() + signals.message_repled.send(sender=ComposeForm, message=msg, user=sender) + else: + msg.save() + signals.message_sent.send(sender=ComposeForm, message=msg, user=sender) + message_list.append(msg) - if notification: - if parent_msg is not None: - notification.send([sender], "messages_replied", {'message': msg,}) - notification.send([r], "messages_reply_received", {'message': msg,}) - else: - notification.send([sender], "messages_sent", {'message': msg,}) - notification.send([r], "messages_received", {'message': msg,}) return message_list diff --git a/django_messages/management.py b/django_messages/management.py index 366296b..a2fa618 100644 --- a/django_messages/management.py +++ b/django_messages/management.py @@ -12,6 +12,8 @@ def create_notice_types(app, created_models, verbosity, **kwargs): notification.create_notice_type("messages_reply_received", _("Reply Received"), _("you have received a reply to a message"), default=2) notification.create_notice_type("messages_deleted", _("Message Deleted"), _("you have deleted a message"), default=1) notification.create_notice_type("messages_recovered", _("Message Recovered"), _("you have undeleted a message"), default=1) + notification.create_notice_type("messages_marked_unread", _("Message Marked As Unread"), _("you have marked a message as unread"), default=1) + notification.create_notice_type("messages_purged", _("Message Purged"), _("you have purged a message"), default=1) signals.post_syncdb.connect(create_notice_types, sender=notification) else: diff --git a/django_messages/migrations/0001_initial.py b/django_messages/migrations/0001_initial.py new file mode 100644 index 0000000..bae9d8e --- /dev/null +++ b/django_messages/migrations/0001_initial.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +from django.conf import settings + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Message', + fields=[ + ('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)), + ('subject', models.CharField(max_length=120, verbose_name='Subject')), + ('body', models.TextField(verbose_name='Body')), + ('sent_at', models.DateTimeField(null=True, verbose_name='sent at', blank=True)), + ('read_at', models.DateTimeField(null=True, verbose_name='read at', blank=True)), + ('replied_at', models.DateTimeField(null=True, verbose_name='replied at', blank=True)), + ('sender_deleted_at', models.DateTimeField(null=True, verbose_name='Sender deleted at', blank=True)), + ('recipient_deleted_at', models.DateTimeField(null=True, verbose_name='Recipient deleted at', blank=True)), + ('parent_msg', models.ForeignKey(null=True, to='django_messages.Message', verbose_name='Parent message', blank=True, related_name='next_messages')), + ('recipient', models.ForeignKey(null=True, to=settings.AUTH_USER_MODEL, verbose_name='Recipient', blank=True, related_name='received_messages')), + ('sender', models.ForeignKey(to=settings.AUTH_USER_MODEL, verbose_name='Sender', related_name='sent_messages')), + ], + options={ + 'ordering': ['-sent_at'], + 'verbose_name_plural': 'Messages', + 'verbose_name': 'Message', + }, + bases=(models.Model,), + ), + ] diff --git a/django_messages/migrations/0002_auto_20140926_1746.py b/django_messages/migrations/0002_auto_20140926_1746.py new file mode 100644 index 0000000..1b013da --- /dev/null +++ b/django_messages/migrations/0002_auto_20140926_1746.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('django_messages', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='message', + name='purged_for_recipient', + field=models.BooleanField(db_index=True, verbose_name='Purged for recipient', default=False), + preserve_default=True, + ), + migrations.AddField( + model_name='message', + name='purged_for_sender', + field=models.BooleanField(db_index=True, verbose_name='Purged for sender', default=False), + preserve_default=True, + ), + ] diff --git a/django_messages/migrations/__init__.py b/django_messages/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/django_messages/models.py b/django_messages/models.py index 5dd07f4..941b248 100644 --- a/django_messages/models.py +++ b/django_messages/models.py @@ -1,6 +1,5 @@ from django.conf import settings from django.db import models -from django.db.models import signals from django.utils import timezone from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ @@ -38,14 +37,17 @@ def trash_for(self, user): return self.filter( recipient=user, recipient_deleted_at__isnull=False, + purged_for_recipient=False, ) | self.filter( sender=user, sender_deleted_at__isnull=False, + purged_for_sender=False, ) @python_2_unicode_compatible class Message(models.Model): + """ A private message from user to user """ @@ -59,6 +61,8 @@ class Message(models.Model): replied_at = models.DateTimeField(_("replied at"), null=True, blank=True) sender_deleted_at = models.DateTimeField(_("Sender deleted at"), null=True, blank=True) recipient_deleted_at = models.DateTimeField(_("Recipient deleted at"), null=True, blank=True) + purged_for_sender = models.BooleanField(_("Purged for sender"), default=False, db_index=True) + purged_for_recipient = models.BooleanField(_("Purged for recipient"), default=False, db_index=True) objects = MessageManager() @@ -98,8 +102,3 @@ def inbox_count_for(user): mark them seen """ return Message.objects.filter(recipient=user, read_at__isnull=True, recipient_deleted_at__isnull=True).count() - -# fallback for email notification if django-notification could not be found -if "notification" not in settings.INSTALLED_APPS and getattr(settings, 'DJANGO_MESSAGES_NOTIFY', True): - from django_messages.utils import new_message_email - signals.post_save.connect(new_message_email, sender=Message) diff --git a/django_messages/signals.py b/django_messages/signals.py index e69de29..5547ae1 100644 --- a/django_messages/signals.py +++ b/django_messages/signals.py @@ -0,0 +1,64 @@ +from django.conf import settings +from django.dispatch import Signal + +message_deleted = Signal(providing_args=["message", "user"]) +message_sent = Signal(providing_args=["message", "user"]) +message_repled = Signal(providing_args=["message", "user"]) +mesage_recovered = Signal(providing_args=["message", "user"]) +message_marked_as_unread = Signal(providing_args=["message", "user"]) +message_purge = Signal(providing_args=["message", "user"]) + +try: + #If it's during installation, we should configure the settings otherwise it fails + settings.configure() +except RuntimeError: + # Already configured (installation is complete) + pass + +if "notification" in settings.INSTALLED_APPS and getattr(settings, 'DJANGO_MESSAGES_NOTIFY', True): + from notification import models as notification + from django_messages.forms import ComposeForm + from django_messages.views import delete, undelete, unread, purge + + def sent_notification(sender, **kwargs): + msg = kwargs['message'] + notification.send([msg.sender], "messages_sent", {'message': msg}) + notification.send([msg.recipient], "messages_received", {'message': msg}) + + def replied_notification(sender, **kwargs): + msg = kwargs['message'] + notification.send([msg.sender], "messages_replied", {'message': msg}) + notification.send([msg.recipient], "messages_reply_received", {'message': msg}) + + def deleted_notification(sender, **kwargs): + msg = kwargs['message'] + user = kwargs['user'] + notification.send([user], "messages_deleted", {'message': msg}) + + def recovered_notification(sender, **kwargs): + msg = kwargs['message'] + user = kwargs['user'] + notification.send([user], "messages_recovered", {'message': msg}) + + def unread_notification(sender, **kwargs): + msg = kwargs['message'] + user = kwargs['user'] + notification.send([user], "messages_marked_unread", {'message': msg}) + + def purge_notification(sender, **kwargs): + msg = kwargs['message'] + user = kwargs['user'] + notification.send([user], "messages_purged", {'message': msg}) + + message_deleted.connect(deleted_notification, sender=delete) + message_sent.connect(sent_notification, sender=ComposeForm) + message_repled.connect(replied_notification, sender=ComposeForm) + mesage_recovered.connect(recovered_notification, sender=undelete) + message_marked_as_unread.connect(unread_notification, sender=unread) + message_purge.connect(purge_notification, sender=purge) + + # fallback for email notification if django-notification could not be found + from django_messages.utils import new_message_email + from django.db.models import signals + from django_messages.models import Message + signals.post_save.connect(new_message_email, sender=Message) diff --git a/django_messages/templates/django_messages/trash.html b/django_messages/templates/django_messages/trash.html index 02fb11e..a593a4b 100644 --- a/django_messages/templates/django_messages/trash.html +++ b/django_messages/templates/django_messages/trash.html @@ -1,30 +1,31 @@ -{% extends "django_messages/base.html" %} -{% load i18n %} +{% extends "django_messages/base.html" %} +{% load i18n %} {% load url from future %} -{% block content %} +{% block content %}
{% trans "No messages." %}
-{% endif %} +{% endif %}{% trans "Deleted Messages are removed from the trash at unregular intervals, don't rely on this feature for long-time storage." %}
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/django_messages/templates/django_messages/view.html b/django_messages/templates/django_messages/view.html index e360177..ebb9b83 100644 --- a/django_messages/templates/django_messages/view.html +++ b/django_messages/templates/django_messages/view.html @@ -20,6 +20,7 @@