Author: [email protected]
Date: Wed Mar 18 23:49:58 2009
New Revision: 99

Modified:
    branches/model-refactor/messages/admin.py
    branches/model-refactor/messages/forms.py
    branches/model-refactor/messages/management.py
    branches/model-refactor/messages/models.py
    branches/model-refactor/messages/templates/messages/base.html
    branches/model-refactor/messages/templates/messages/compose.html
    branches/model-refactor/messages/templates/messages/outbox.html
    branches/model-refactor/messages/templates/messages/trash.html
    branches/model-refactor/messages/templates/messages/view.html
    branches/model-refactor/messages/templatetags/inbox.py
    branches/model-refactor/messages/urls.py
    branches/model-refactor/messages/utils.py
    branches/model-refactor/messages/views.py

Log:
model-refactor: merged my own changes with the patch from robertrv. still  
some more work to be done ...

Modified: branches/model-refactor/messages/admin.py
==============================================================================
--- branches/model-refactor/messages/admin.py   (original)
+++ branches/model-refactor/messages/admin.py   Wed Mar 18 23:49:58 2009
@@ -3,7 +3,7 @@
  from django.contrib import admin
  from django.contrib.auth.models import User, Group

-from messages.models import Message
+from messages.models import Message, MessageRecipient

  class MessageAdminForm(forms.ModelForm):
      """
@@ -82,3 +82,4 @@
              obj.save()

  admin.site.register(Message, MessageAdmin)
+admin.site.register(MessageRecipient)

Modified: branches/model-refactor/messages/forms.py
==============================================================================
--- branches/model-refactor/messages/forms.py   (original)
+++ branches/model-refactor/messages/forms.py   Wed Mar 18 23:49:58 2009
@@ -3,14 +3,17 @@
  from django.conf import settings
  from django.utils.translation import ugettext_lazy as _
  from django.utils.translation import ugettext_noop
+from django.db.models import get_app
+from django.core.exceptions import ImproperlyConfigured
  from django.contrib.auth.models import User

-if "notification" in settings.INSTALLED_APPS:
-    from notification import models as notification
+if 'notification' in settings.INSTALLED_APPS:
+    notification = get_app('notification')
  else:
      notification = None

-from messages.models import Message
+
+from messages.models import Message, MessageRecipient
  from messages.fields import CommaSeparatedUserField

  class ComposeForm(forms.Form):
@@ -22,37 +25,36 @@
      body = forms.CharField(label=_(u"Body"),
          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):
+
+    def save(self, sender, parent_msg=None, draft=False):
          recipients = self.cleaned_data['recipient']
          subject = self.cleaned_data['subject']
          body = self.cleaned_data['body']
+        now = datetime.datetime.now()
          message_list = []
-        for r in recipients:
-            msg = Message(
-                sender = sender,
-                recipient = r,
-                subject = subject,
-                body = body,
-            )
+        msg = Message(sender=sender,subject=subject,body=body)
+        if not draft:
+            msg.sent_at = now
              if parent_msg is not None:
                  msg.parent_msg = parent_msg
-                parent_msg.replied_at = datetime.datetime.now()
+                parent_msg.replied_at = now
                  parent_msg.save()
-            msg.save()
+        msg.save()
+        for r in recipients:
+            mr = MessageRecipient(message=msg, user=r)
+            mr.save()
              message_list.append(msg)
              if notification:
-                if parent_msg is not None:
-                    notification.send([sender], "messages_replied",  
{'message': msg,})
-                     
notification.send(recipients, "messages_reply_received", {'message': msg,})
-                else:
-                    notification.send([sender], "messages_sent",  
{'message': msg,})
-                    notification.send(recipients, "messages_received",  
{'message': msg,})
+                if not draft:
+                    if parent_msg is not None:
+                        notification.send([sender], "messages_replied",  
{'message': msg,})
+                         
notification.send(recipients, "messages_reply_received", {'message': msg,})
+                    else:
+                        notification.send([sender], "messages_sent",  
{'message': msg,})
+                        notification.send(recipients, "messages_received",  
{'message': msg,})
          return message_list

Modified: branches/model-refactor/messages/management.py
==============================================================================
--- branches/model-refactor/messages/management.py      (original)
+++ branches/model-refactor/messages/management.py      Wed Mar 18 23:49:58 2009
@@ -1,10 +1,11 @@
-from django.db.models import get_models, signals
+from django.db.models import get_models, signals, get_app
  from django.conf import settings
  from django.utils.translation import ugettext_noop as _
+from django.core.exceptions import ImproperlyConfigured

-if "notification" in settings.INSTALLED_APPS:
-    from notification import models as notification
-
+try:
+    notification = get_app('notification')
+
      def create_notice_types(app, created_models, verbosity, **kwargs):
          notification.create_notice_type("messages_received", _("Message  
Received"), _("you have received a message"), default=2)
          notification.create_notice_type("messages_sent", _("Message  
Sent"), _("you have sent a message"), default=1)
@@ -12,7 +13,7 @@
          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 undelete a message"), default=1)
-
+
      signals.post_syncdb.connect(create_notice_types, sender=notification)
-else:
+except ImproperlyConfigured:
      print "Skipping creation of NoticeTypes as notification app not found"

Modified: branches/model-refactor/messages/models.py
==============================================================================
--- branches/model-refactor/messages/models.py  (original)
+++ branches/model-refactor/messages/models.py  Wed Mar 18 23:49:58 2009
@@ -14,8 +14,9 @@
          marked as deleted.
          """
          return self.filter(
-            recipient=user,
-            recipient_deleted_at__isnull=True,
+            recipients=user,
+            messagerecipient__deleted_at__isnull=True,
+            #recipient_deleted_at__isnull=True,
          )

      def outbox_for(self, user):
@@ -26,6 +27,7 @@
          return self.filter(
              sender=user,
              sender_deleted_at__isnull=True,
+            sent_at__isnull=False,
          )

      def trash_for(self, user):
@@ -34,12 +36,23 @@
          user and are marked as deleted.
          """
          return self.filter(
-            recipient=user,
-            recipient_deleted_at__isnull=False,
+            recipients=user,
+            messagerecipient__deleted_at__isnull=False,
          ) | self.filter(
              sender=user,
              sender_deleted_at__isnull=False,
          )
+
+    def drafts_for(self, user):
+        """
+        Returns all messages where ``sent_at`` is Null and where the given
+        user is the sender and which are not yet deleted by the sender.
+        """
+        return self.filter(
+            sender=user,
+            sent_at__isnull=True,
+            sender_deleted_at__isnull=True,
+        )


  class Message(models.Model):
@@ -49,28 +62,13 @@
      subject = models.CharField(_("Subject"), max_length=120)
      body = models.TextField(_("Body"))
      sender = models.ForeignKey(User, related_name='sent_messages',  
verbose_name=_("Sender"))
-    recipient = models.ForeignKey(User, related_name='received_messages',  
null=True, blank=True, verbose_name=_("Recipient"))
+    recipients = models.ManyToManyField(User, through='MessageRecipient',  
related_name="received_messages", verbose_name=_("Recipients"))
      parent_msg = models.ForeignKey('self', related_name='next_messages',  
null=True, blank=True, verbose_name=_("Parent message"))
      sent_at = models.DateTimeField(_("sent at"), null=True, blank=True)
-    read_at = models.DateTimeField(_("read at"), null=True, blank=True)
-    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)

      objects = MessageManager()

-    def new(self):
-        """returns whether the recipient has read the message or not"""
-        if self.read_at is not None:
-            return False
-        return True
-
-    def replied(self):
-        """returns whether the recipient has written a reply to this  
message"""
-        if self.replied_at is not None:
-            return True
-        return False
-
      def __unicode__(self):
          return self.subject

@@ -78,24 +76,50 @@
          return ('messages_detail', [self.id])
      get_absolute_url = models.permalink(get_absolute_url)

-    def save(self, force_insert=False, force_update=False):
-        if not self.id:
-            self.sent_at = datetime.datetime.now()
-        super(Message, self).save(force_insert, force_update)
-
      class Meta:
          ordering = ['-sent_at']
          verbose_name = _("Message")
          verbose_name_plural = _("Messages")
+
+
+class MessageRecipient(models.Model):
+    """
+    Intermediate model to allow per recipient marking as
+    deleted, read etc. of a message.
+
+    """
+    user = models.ForeignKey(User, verbose_name=_("Recipient"))
+    message = models.ForeignKey(Message, verbose_name=_("Message"))
+    read_at = models.DateTimeField(_("read at"), null=True, blank=True)
+    deleted_at = models.DateTimeField(_("Recipient deleted at"),  
null=True, blank=True)
+    replied_at = models.DateTimeField(_("replied at"), null=True,  
blank=True)
+
+    def __unicode__(self):
+        return "%s (%s)" % (self.message, self.user)
+
+    def new(self):
+        """returns whether the recipient has read the message or not"""
+        return self.read_at is None
+
+    def replied(self):
+        """returns whether the recipient has written a reply to this  
message"""
+        return self.replied_at is not None
+
+    class Meta:
+        verbose_name = _("Recipient")
+        verbose_name_plural = _("Recipients")

+
  def inbox_count_for(user):
      """
      returns the number of unread messages for the given user but does not
      mark them seen
      """
-    return Message.objects.filter(recipient=user, read_at__isnull=True,  
recipient_deleted_at__isnull=True).count()
+    return Message.objects.filter(recipients=user,
+                                  messagerecipient__read_at__isnull=True,
+                                   
messagerecipient__deleted_at__isnull=True).count()

  # fallback for email notification if django-notification could not be found
-if "notification" not in settings.INSTALLED_APPS:
+if 'notification' not in settings.INSTALLED_APPS:
      from messages.utils import new_message_email
      signals.post_save.connect(new_message_email, sender=Message)

Modified: branches/model-refactor/messages/templates/messages/base.html
==============================================================================
--- branches/model-refactor/messages/templates/messages/base.html       
(original)
+++ branches/model-refactor/messages/templates/messages/base.html       Wed Mar 
 
18 23:49:58 2009
@@ -8,6 +8,7 @@
      <li><a href="{% url messages_inbox %} ">&raquo;&nbsp;{%  
trans "Inbox" %}</a></li>
      <li><a href="{% url messages_outbox %} ">&raquo;&nbsp;{% trans "Sent  
Messages" %}</a></li>
      <li><a href="{% url messages_compose %} ">&raquo;&nbsp;{% trans "New  
Message" %}</a></li>
+       <li><a href="{% url messages_drafts %}">&raquo;&nbsp;{%  
trans "Drafts" %}</a></li>
      <li><a href="{% url messages_trash %} ">&raquo;&nbsp;{%  
trans "Trash" %}</a></li>
  </ul>
  {% endblock %}

Modified: branches/model-refactor/messages/templates/messages/compose.html
==============================================================================
--- branches/model-refactor/messages/templates/messages/compose.html     
(original)
+++ branches/model-refactor/messages/templates/messages/compose.html    Wed  
Mar 18 23:49:58 2009
@@ -6,7 +6,8 @@
  <table>
  {{ form.as_table }}
  </table>
-<input type="submit" value="{% trans "Send" %} &raquo;"/>
+<input type="submit" value="{% trans "save as draft" %}&raquo;"  
name="_draft"/>
+<input type="submit" value="{% trans "Send" %} &raquo;" name="save"/>
  </form>

  {% endblock %}

Modified: branches/model-refactor/messages/templates/messages/outbox.html
==============================================================================
--- branches/model-refactor/messages/templates/messages/outbox.html      
(original)
+++ branches/model-refactor/messages/templates/messages/outbox.html     Wed Mar 
 
18 23:49:58 2009
@@ -9,7 +9,7 @@
      <tbody>
  {% for message in message_list %}
      <tr>
-        <td>{{ message.recipient }}</td>
+        <td>{{ message.recipients.all|join:", " }}</td>
          <td>
          <a href="{{ message.get_absolute_url }}">{{ message.subject }}</a>
          </td>

Modified: branches/model-refactor/messages/templates/messages/trash.html
==============================================================================
--- branches/model-refactor/messages/templates/messages/trash.html       
(original)
+++ branches/model-refactor/messages/templates/messages/trash.html      Wed Mar 
 
18 23:49:58 2009
@@ -4,15 +4,14 @@
  <h1>{% trans "Deleted Messages" %}</h1>
  <table class="messages">
      <thead>
-        <tr><th>{% trans "Sender" %}</th><th>{%  
trans "Subject" %}</th><th>{% trans "Date" %}</th><th>{%  
trans "Action" %}</th></tr>
+        <tr><th>{% trans "Sender" %}</th><th>{%  
trans "Recipient" %}</th><th>{% trans "Subject" %}</th><th>{%  
trans "Date" %}</th><th>{% trans "Action" %}</th></tr>
      </thead>
      <tbody>
  {% for message in message_list %}
      <tr>
          <td>{{ message.sender }}</td>
-        <td>
-        {{ message.subject }}
-        </td>
+               <td>{{ message.recipients.all|join:", " }}</td>
+        <td> {{ message.subject }}</td>
          <td>{{ message.sent_at|date:_("DATETIME_FORMAT") }}</td>
          <td><a href="{% url messages_undelete message.id %}">{%  
trans "undelete" %}</a></td>
      </tr>

Modified: branches/model-refactor/messages/templates/messages/view.html
==============================================================================
--- branches/model-refactor/messages/templates/messages/view.html       
(original)
+++ branches/model-refactor/messages/templates/messages/view.html       Wed Mar 
 
18 23:49:58 2009
@@ -10,12 +10,21 @@
      <dt>{% trans "Date" %} </dt>
      <dd>{{ message.sent_at|date:_("DATETIME_FORMAT")}}</dd>
      <dt>{% trans "Recipient" %}</dt>
-    <dd>{{ message.recipient }}</dd>
+    <dd>{{ message.recipients.all|join:", " }}</dd>
  </dl>
  {{ message.body|linebreaksbr }}<br /><br />

  {% ifequal message.recipient user %}
  <a href="{% url messages_reply message.id %}">{% trans "Reply" %}</a>
+
+{% if message.get_next_by_sent_at %}
+<a href="{% url messages_detail message.get_next_by_sent_at.id %}">next</a>
+{% endif %}
+{% if message.get_previous_by_sent_at %}
+<a href="{% url messages_detail  
message.get_previous_by_sent_at.id %}">prev</a>
+{% endif %}
+
  {% endifequal %}
  <a href="{% url messages_delete message.id %}">{% trans "Delete" %}</a>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
+
\ No newline at end of file

Modified: branches/model-refactor/messages/templatetags/inbox.py
==============================================================================
--- branches/model-refactor/messages/templatetags/inbox.py      (original)
+++ branches/model-refactor/messages/templatetags/inbox.py      Wed Mar 18  
23:49:58 2009
@@ -2,11 +2,9 @@

  class InboxOutput(Node):
      def render(self, context):
-        try:
-            user = context['user']
-            count = user.received_messages.filter(read_at__isnull=True,  
recipient_deleted_at__isnull=True).count()
-        except (KeyError, AttributeError):
-            count = ''
+        user = context['user']
+        count =  
user.received_messages.filter(messagerecipient__read_at__isnull=True,  
messagerecipient__deleted_at__isnull=True).count()
+        print  
user.received_messages.filter(messagerecipient__read_at__isnull=True,  
messagerecipient__deleted_at__isnull=True)
          return "%s" % (count)

  def do_print_inbox_count(parser, token):

Modified: branches/model-refactor/messages/urls.py
==============================================================================
--- branches/model-refactor/messages/urls.py    (original)
+++ branches/model-refactor/messages/urls.py    Wed Mar 18 23:49:58 2009
@@ -7,6 +7,7 @@
      url(r'^$', redirect_to, {'url': 'inbox/'}),
      url(r'^inbox/$', inbox, name='messages_inbox'),
      url(r'^outbox/$', outbox, name='messages_outbox'),
+    url(r'^drafts/$', drafts, name='messages_drafts'),
      url(r'^compose/$', compose, name='messages_compose'),
      url(r'^compose/(?P<recipient>[\+\w]+)/$', compose,  
name='messages_compose_to'),
      url(r'^reply/(?P<message_id>[\d]+)/$', reply, name='messages_reply'),

Modified: branches/model-refactor/messages/utils.py
==============================================================================
--- branches/model-refactor/messages/utils.py   (original)
+++ branches/model-refactor/messages/utils.py   Wed Mar 18 23:49:58 2009
@@ -6,10 +6,9 @@
  from django.conf import settings

  # favour django-mailer but fall back to django.core.mail
-
-if "mailer" in settings.INSTALLED_APPS:
+try:
      from mailer import send_mail
-else:
+except ImportError:
      from django.core.mail import send_mail

  def format_quote(text):

Modified: branches/model-refactor/messages/views.py
==============================================================================
--- branches/model-refactor/messages/views.py   (original)
+++ branches/model-refactor/messages/views.py   Wed Mar 18 23:49:58 2009
@@ -7,17 +7,19 @@
  from django.utils.translation import ugettext as _
  from django.utils.translation import ugettext_noop
  from django.core.urlresolvers import reverse
-from django.conf import settings
+from django.core.exceptions import ImproperlyConfigured
+from django.db.models import get_app

  from messages.models import Message
  from messages.forms import ComposeForm
  from messages.utils import format_quote

-if "notification" in settings.INSTALLED_APPS:
-    from notification import models as notification
-else:
+try:
+    notification = get_app('notification')
+except ImproperlyConfigured:
      notification = None

+
  def inbox(request, template_name='messages/inbox.html'):
      """
      Displays a list of received messages for the current user.
@@ -56,6 +58,18 @@
      }, context_instance=RequestContext(request))
  trash = login_required(trash)

+def drafts(request, template_name='messages/drafts.html'):
+    """
+    Displays a list of saved drafts.
+    Option arguments:
+        ``template_name``: name of the template to use.
+    """
+    message_list = Message.objects.drafts_for(request.user)
+    return render_to_response(template_name, {
+        'message_list': message_list,
+    }, context_instance=RequestContext(request))
+drafts = login_required(drafts)
+
  def compose(request, recipient=None, form_class=ComposeForm,
          template_name='messages/compose.html', success_url=None,  
recipient_filter=None):
      """
@@ -73,9 +87,15 @@
          sender = request.user
          form = form_class(request.POST, recipient_filter=recipient_filter)
          if form.is_valid():
-            form.save(sender=request.user)
-            request.user.message_set.create(
-                message=_(u"Message successfully sent."))
+            draft = request.POST.has_key('_draft')
+            form.save(sender=request.user, draft=draft)
+            if draft:
+                request.user.message_set.create(
+                    message=_(u'Message saved as draft.'))
+
+            else:
+                request.user.message_set.create(
+                    message=_(u"Message successfully sent."))
              if success_url is None:
                  success_url = reverse('messages_inbox')
              if request.GET.has_key('next'):
@@ -103,7 +123,7 @@
          sender = request.user
          form = form_class(request.POST, recipient_filter=recipient_filter)
          if form.is_valid():
-            form.save(sender=request.user, parent_msg=parent)
+            form.save(sender=request.user, parent_msg=parent,  
draft=request.POST.has_key('_draft'))
              request.user.message_set.create(
                  message=_(u"Message successfully sent."))
              if success_url is None:
@@ -146,8 +166,10 @@
      if message.sender == user:
          message.sender_deleted_at = now
          deleted = True
-    if message.recipient == user:
-        message.recipient_deleted_at = now
+    if user in (message.recipients.all()):
+        mr = message.messagerecipient_set.get(user=user, message=message)
+        mr.deleted_at = now
+        mr.save()
          deleted = True
      if deleted:
          message.save()
@@ -173,8 +195,10 @@
      if message.sender == user:
          message.sender_deleted_at = None
          undeleted = True
-    if message.recipient == user:
-        message.recipient_deleted_at = None
+    if user in message.recipients.all():
+        mr = message.messagerecipient_set.get(user=user, message=message)
+        mr.deleted_at = None
+        mr.save()
          undeleted = True
      if undeleted:
          message.save()
@@ -197,12 +221,14 @@
      user = request.user
      now = datetime.datetime.now()
      message = get_object_or_404(Message, id=message_id)
-    if (message.sender != user) and (message.recipient != user):
+    if (message.sender != user) and (user not in message.recipients.all()):
          raise Http404
-    if message.read_at is None and message.recipient == user:
-        message.read_at = now
-        message.save()
+    mr = message.messagerecipient_set.get(message=message, user=user)
+    if mr.read_at is None:
+        mr.read_at = now
+        mr.save()
      return render_to_response(template_name, {
          'message': message,
      }, context_instance=RequestContext(request))
  view = login_required(view)
+

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pinax-updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/pinax-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to