diff --git a/django_mailbox/admin.py b/django_mailbox/admin.py index efe2a33..123f645 100644 --- a/django_mailbox/admin.py +++ b/django_mailbox/admin.py @@ -12,17 +12,27 @@ class MailboxAdmin(admin.ModelAdmin): list_display = ( 'name', 'uri', + 'active', ) actions = [get_new_mail] class MessageAdmin(admin.ModelAdmin): list_display = ( 'subject', - 'from_address', - 'received', + 'address', + 'processed', 'mailbox', + 'outgoing', + ) + ordering = ['-processed'] + list_filter = ( + 'mailbox', + 'outgoing', + ) + raw_id_fields = ( + 'in_reply_to', + 'references', ) - ordering = ['-received'] if getattr(settings, 'DJANGO_MAILBOX_ADMIN_ENABLED', True): admin.site.register(Message, MessageAdmin) diff --git a/django_mailbox/management/commands/getmail.py b/django_mailbox/management/commands/getmail.py index 5f1aad3..2ee8947 100644 --- a/django_mailbox/management/commands/getmail.py +++ b/django_mailbox/management/commands/getmail.py @@ -4,7 +4,7 @@ from django_mailbox.models import Mailbox class Command(BaseCommand): def handle(self, *args, **options): - mailboxes = Mailbox.objects.all() + mailboxes = Mailbox.active_mailboxes.all() if args: mailboxes = mailboxes.filter(name = ' '.join(args)) for mailbox in mailboxes: diff --git a/django_mailbox/migrations/0003_auto__add_field_mailbox_active.py b/django_mailbox/migrations/0003_auto__add_field_mailbox_active.py new file mode 100644 index 0000000..a067e50 --- /dev/null +++ b/django_mailbox/migrations/0003_auto__add_field_mailbox_active.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Mailbox.active' + db.add_column('django_mailbox_mailbox', 'active', + self.gf('django.db.models.fields.BooleanField')(default=True), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Mailbox.active' + db.delete_column('django_mailbox_mailbox', 'active') + + + models = { + 'django_mailbox.mailbox': { + 'Meta': {'object_name': 'Mailbox'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}) + }, + 'django_mailbox.message': { + 'Meta': {'object_name': 'Message'}, + 'body': ('django.db.models.fields.TextField', [], {}), + 'from_address': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': "orm['django_mailbox.Mailbox']"}), + 'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'received': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + } + } + + complete_apps = ['django_mailbox'] \ No newline at end of file diff --git a/django_mailbox/migrations/0004_auto__add_field_message_outgoing.py b/django_mailbox/migrations/0004_auto__add_field_message_outgoing.py new file mode 100644 index 0000000..20e889a --- /dev/null +++ b/django_mailbox/migrations/0004_auto__add_field_message_outgoing.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Message.outgoing' + db.add_column('django_mailbox_message', 'outgoing', + self.gf('django.db.models.fields.BooleanField')(default=False), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'Message.outgoing' + db.delete_column('django_mailbox_message', 'outgoing') + + + models = { + 'django_mailbox.mailbox': { + 'Meta': {'object_name': 'Mailbox'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}) + }, + 'django_mailbox.message': { + 'Meta': {'object_name': 'Message'}, + 'body': ('django.db.models.fields.TextField', [], {}), + 'from_address': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': "orm['django_mailbox.Mailbox']"}), + 'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'received': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + } + } + + complete_apps = ['django_mailbox'] diff --git a/django_mailbox/migrations/0005_rename_fields.py b/django_mailbox/migrations/0005_rename_fields.py new file mode 100644 index 0000000..35bc858 --- /dev/null +++ b/django_mailbox/migrations/0005_rename_fields.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + db.rename_column('django_mailbox_message', 'from_address', 'address') + db.rename_column('django_mailbox_message', 'received', 'processed') + + def backwards(self, orm): + db.rename_column('django_mailbox_message', 'address', 'from_address') + db.rename_column('django_mailbox_message', 'processed', 'received') + + models = { + 'django_mailbox.mailbox': { + 'Meta': {'object_name': 'Mailbox'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}) + }, + 'django_mailbox.message': { + 'Meta': {'object_name': 'Message'}, + 'address': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'body': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': "orm['django_mailbox.Mailbox']"}), + 'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + } + } + + complete_apps = ['django_mailbox'] diff --git a/django_mailbox/migrations/0006_auto__add_field_message_in_reply_to.py b/django_mailbox/migrations/0006_auto__add_field_message_in_reply_to.py new file mode 100644 index 0000000..7c8b9d7 --- /dev/null +++ b/django_mailbox/migrations/0006_auto__add_field_message_in_reply_to.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'Message.in_reply_to' + db.add_column('django_mailbox_message', 'in_reply_to', + self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='replies', null=True, to=orm['django_mailbox.Message']), + keep_default=False) + + # Adding M2M table for field references on 'Message' + db.create_table('django_mailbox_message_references', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('from_message', models.ForeignKey(orm['django_mailbox.message'], null=False)), + ('to_message', models.ForeignKey(orm['django_mailbox.message'], null=False)) + )) + db.create_unique('django_mailbox_message_references', ['from_message_id', 'to_message_id']) + + + def backwards(self, orm): + # Deleting field 'Message.in_reply_to' + db.delete_column('django_mailbox_message', 'in_reply_to_id') + + # Removing M2M table for field references on 'Message' + db.delete_table('django_mailbox_message_references') + + + models = { + 'django_mailbox.mailbox': { + 'Meta': {'object_name': 'Mailbox'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'uri': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '255', 'null': 'True', 'blank': 'True'}) + }, + 'django_mailbox.message': { + 'Meta': {'object_name': 'Message'}, + 'address': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'body': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'in_reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': "orm['django_mailbox.Message']"}), + 'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'messages'", 'to': "orm['django_mailbox.Mailbox']"}), + 'message_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'outgoing': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'processed': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'references': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'referenced_by'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['django_mailbox.Message']"}), + 'subject': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + } + } + + complete_apps = ['django_mailbox'] \ No newline at end of file diff --git a/django_mailbox/models.py b/django_mailbox/models.py index 41be837..d8897f2 100755 --- a/django_mailbox/models.py +++ b/django_mailbox/models.py @@ -9,6 +9,12 @@ from django_mailbox.transports import Pop3Transport, ImapTransport,\ MMDFTransport from django_mailbox.signals import message_received +class ActiveMailboxManager(models.Manager): + def get_query_set(self): + return super(ActiveMailboxManager, self).get_query_set().filter( + active=True, + ) + class Mailbox(models.Model): name = models.CharField(max_length=255) uri = models.CharField( @@ -27,6 +33,13 @@ class Mailbox(models.Model): null=True, default=None, ) + active = models.BooleanField( + blank=True, + default=True, + ) + + objects = models.Manager() + active_mailboxes = ActiveMailboxManager() @property def _protocol_info(self): @@ -97,9 +110,23 @@ class Mailbox(models.Model): msg.mailbox = self msg.subject = message['subject'][0:255] msg.message_id = message['message-id'][0:255] - msg.from_address = rfc822.parseaddr(message['from'])[1][0:255] + msg.address = rfc822.parseaddr(message['from'])[1][0:255] msg.body = message.as_string() + if message['in-reply-to']: + try: + msg.in_reply_to = Message.objects.filter(message_id=message['in-reply-to'])[0] + except IndexError: + pass msg.save() + if message['references']: + references = message['references'].split('\n') + for reference in references: + try: + msg.references.add( + Message.objects.filter(message_id=reference.strip())[0] + ) + except IndexError: + pass message_received.send(sender=self, message=msg) return msg @@ -119,17 +146,57 @@ class Mailbox(models.Model): class Meta: verbose_name_plural = "Mailboxes" +class IncomingMessageManager(models.Manager): + def get_query_set(self): + return super(IncomingMessageManager, self).get_query_set().filter( + outgoing=False, + ) + +class OutgoingMessageManager(models.Manager): + def get_query_set(self): + return super(OutgoingMessageManager, self).get_query_set().filter( + outgoing=True, + ) + class Message(models.Model): mailbox = models.ForeignKey(Mailbox, related_name='messages') subject = models.CharField(max_length=255) message_id = models.CharField(max_length=255) - from_address = models.CharField(max_length=255) + in_reply_to = models.ForeignKey( + 'django_mailbox.Message', + related_name='replies', + blank=True, + null=True, + ) + references = models.ManyToManyField( + 'django_mailbox.Message', + related_name='referenced_by', + blank=True, + null=True, + ) + address = models.CharField(max_length=255) + outgoing = models.BooleanField( + default=False, + blank=True, + ) body = models.TextField() - received = models.DateTimeField( - auto_now_add=True - ) + processed = models.DateTimeField( + auto_now_add=True + ) + + objects = models.Manager() + incoming_messages = IncomingMessageManager() + outgoing_messages = OutgoingMessageManager() + + @property + def from_address(self): + return self.get_email_object(self)['from'] + + @property + def to_address(self): + return self.get_email_object(self)['to'] def get_email_object(self): return email.message_from_string(self.body) diff --git a/setup.py b/setup.py index 34e12d3..21567aa 100755 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from distutils.core import setup setup( name='django-mailbox', - version='1.1.1', + version='1.2', url='http://bitbucket.org/latestrevision/django-mailbox/', description='Automatically import mail from POP3, IMAP, or a local mailbox into Django', author='Adam Coddington',