mirror of
https://github.com/coddingtonbear/django-mailbox.git
synced 2026-07-09 22:38:19 +02:00
Initial commit.
This commit is contained in:
commit
413b60e35f
13 changed files with 340 additions and 0 deletions
0
django_mailbox/__init__.py
Normal file
0
django_mailbox/__init__.py
Normal file
29
django_mailbox/admin.py
Normal file
29
django_mailbox/admin.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
|
||||
from django_mailbox.models import Message, Mailbox
|
||||
|
||||
def get_new_mail(mailbox_admin, request, queryset):
|
||||
for mailbox in queryset.all():
|
||||
mailbox.get_new_mail()
|
||||
get_new_mail.short_description = 'Get new mail'
|
||||
|
||||
class MailboxAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'name',
|
||||
'uri',
|
||||
)
|
||||
actions = [get_new_mail]
|
||||
|
||||
class MessageAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'subject',
|
||||
'from_address',
|
||||
'received',
|
||||
'mailbox',
|
||||
)
|
||||
ordering = ['-received']
|
||||
|
||||
if getattr(settings, 'DJANGO_MAILBOX_ADMIN_ENABLED', True):
|
||||
admin.site.register(Message, MessageAdmin)
|
||||
admin.site.register(Mailbox, MailboxAdmin)
|
||||
0
django_mailbox/management/__init__.py
Normal file
0
django_mailbox/management/__init__.py
Normal file
0
django_mailbox/management/commands/__init__.py
Normal file
0
django_mailbox/management/commands/__init__.py
Normal file
18
django_mailbox/management/commands/getmail.py
Normal file
18
django_mailbox/management/commands/getmail.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
from django.core.management.base import BaseCommand
|
||||
from django.dispatch import receiver
|
||||
|
||||
from django_mailbox.models import Mailbox
|
||||
from django_mailbox.signals import message_received
|
||||
|
||||
class Command(BaseCommand):
|
||||
def handle(self, *args, **options):
|
||||
mailboxes = Mailbox.objects.all()
|
||||
if args:
|
||||
mailboxes = mailboxes.filter(name = ' '.join(args))
|
||||
for mailbox in mailboxes:
|
||||
self.stdout.write('Gathering messages for %s\n' % mailbox.name)
|
||||
mailbox.get_new_mail()
|
||||
|
||||
@receiver(message_received)
|
||||
def incoming_message(self, sender, message, **kwargs):
|
||||
self.stdout.write('Received %s\n' % message.subject)
|
||||
59
django_mailbox/migrations/0001_initial.py
Normal file
59
django_mailbox/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# -*- 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 model 'Mailbox'
|
||||
db.create_table('django_mailbox_mailbox', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
|
||||
('uri', self.gf('django.db.models.fields.CharField')(max_length=255)),
|
||||
))
|
||||
db.send_create_signal('django_mailbox', ['Mailbox'])
|
||||
|
||||
# Adding model 'Message'
|
||||
db.create_table('django_mailbox_message', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('mailbox', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['django_mailbox.Mailbox'])),
|
||||
('subject', self.gf('django.db.models.fields.CharField')(max_length=255)),
|
||||
('message_id', self.gf('django.db.models.fields.CharField')(max_length=255)),
|
||||
('from_address', self.gf('django.db.models.fields.CharField')(max_length=255)),
|
||||
('body', self.gf('django.db.models.fields.TextField')()),
|
||||
('received', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
|
||||
))
|
||||
db.send_create_signal('django_mailbox', ['Message'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'Mailbox'
|
||||
db.delete_table('django_mailbox_mailbox')
|
||||
|
||||
# Deleting model 'Message'
|
||||
db.delete_table('django_mailbox_message')
|
||||
|
||||
|
||||
models = {
|
||||
'django_mailbox.mailbox': {
|
||||
'Meta': {'object_name': 'Mailbox'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'uri': ('django.db.models.fields.CharField', [], {'max_length': '255'})
|
||||
},
|
||||
'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', [], {'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']
|
||||
0
django_mailbox/migrations/__init__.py
Normal file
0
django_mailbox/migrations/__init__.py
Normal file
105
django_mailbox/models.py
Normal file
105
django_mailbox/models.py
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import email
|
||||
import rfc822
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
from django.db import models
|
||||
from django_mailbox.transports import PopMailEnumerator, ImapMailEnumerator
|
||||
from django_mailbox.signals import message_received
|
||||
|
||||
class Mailbox(models.Model):
|
||||
name = models.CharField(max_length=255)
|
||||
uri = models.CharField(
|
||||
max_length=255,
|
||||
help_text="""
|
||||
Start your URI with imap:// or pop3://.
|
||||
<br />
|
||||
<br />
|
||||
Example: imap://myusername:mypassword@someserver
|
||||
<br />
|
||||
<br />
|
||||
Be sure to urlencode your username and password should they
|
||||
contain illegal characters (like @, :, etc).
|
||||
"""
|
||||
)
|
||||
|
||||
@property
|
||||
def _protocol_info(self):
|
||||
return urlparse.urlparse(self.uri)
|
||||
|
||||
@property
|
||||
def _domain(self):
|
||||
return self._protocol_info.hostname
|
||||
|
||||
@property
|
||||
def port(self):
|
||||
return self._protocol_info.port
|
||||
|
||||
@property
|
||||
def username(self):
|
||||
return urllib.unquote(self._protocol_info.username)
|
||||
|
||||
@property
|
||||
def password(self):
|
||||
return urllib.unquote(self._protocol_info.password)
|
||||
|
||||
@property
|
||||
def location(self):
|
||||
return self._domain if self._domain else '' + self._protocol_info.path
|
||||
|
||||
@property
|
||||
def type(self):
|
||||
return self._protocol_info.scheme.lower()
|
||||
|
||||
def get_connection(self):
|
||||
if self.type == 'imap':
|
||||
conn = ImapMailEnumerator(
|
||||
self.location,
|
||||
self.port if self.port else 143
|
||||
)
|
||||
elif self.type == 'pop3':
|
||||
conn = PopMailEnumerator(
|
||||
self.location,
|
||||
self.port if self.port else 110
|
||||
)
|
||||
conn.connect(self.username, self.password)
|
||||
return conn
|
||||
|
||||
def get_new_mail(self):
|
||||
connection = self.get_connection()
|
||||
new_mail = []
|
||||
for message in connection.get_message():
|
||||
msg = Message()
|
||||
msg.mailbox = self
|
||||
msg.subject = message['subject']
|
||||
msg.message_id = message['message-id']
|
||||
msg.from_address = rfc822.parseaddr(message['from'])[1]
|
||||
msg.body = message.as_string()
|
||||
msg.save()
|
||||
new_mail.append(msg)
|
||||
message_received.send(sender=self, message=msg)
|
||||
return new_mail
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = "Mailboxes"
|
||||
|
||||
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)
|
||||
|
||||
body = models.TextField()
|
||||
|
||||
received = models.DateTimeField(
|
||||
auto_now_add=True
|
||||
)
|
||||
|
||||
def get_email_object(self):
|
||||
return email.message_from_string(self.body)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.subject
|
||||
3
django_mailbox/signals.py
Normal file
3
django_mailbox/signals.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from django.dispatch.dispatcher import Signal
|
||||
|
||||
message_received = Signal(providing_args=['message'])
|
||||
50
django_mailbox/transports.py
Normal file
50
django_mailbox/transports.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import email
|
||||
from imaplib import IMAP4
|
||||
from poplib import POP3
|
||||
|
||||
class PopMailEnumerator(object):
|
||||
def __init__(self, hostname, port):
|
||||
self.hostname = hostname
|
||||
self.port = port
|
||||
|
||||
def connect(self, username, password):
|
||||
self.server = POP3(self.hostname, self.port)
|
||||
self.server.user(username)
|
||||
self.server.pass_(password)
|
||||
|
||||
def get_message(self):
|
||||
message_count = len(self.server.list()[1])
|
||||
for i in range(message_count):
|
||||
try:
|
||||
msg_contents = "\r\n".join(self.server.retr(i + 1)[1])
|
||||
message = email.message_from_string(msg_contents)
|
||||
yield message
|
||||
except email.Errors.MessageParseError:
|
||||
continue
|
||||
self.server.dele(i + 1)
|
||||
self.server.quit()
|
||||
return
|
||||
|
||||
class ImapMailEnumerator(object):
|
||||
def __init__(self, hostname, port):
|
||||
self.hostname = hostname
|
||||
self.port = port
|
||||
|
||||
def connect(self, username, password):
|
||||
self.server = IMAP4(self.hostname, self.port)
|
||||
typ, msg = self.server.login(username, password)
|
||||
self.server.select()
|
||||
|
||||
def get_message(self):
|
||||
typ, inbox = self.server.search(None, 'ALL')
|
||||
for key in inbox[0].split():
|
||||
try:
|
||||
typ, msg_contents = self.server.fetch(key, '(RFC822)')
|
||||
message = email.message_from_string(msg_contents[0][1])
|
||||
yield message
|
||||
except email.Errors.MessageParseError:
|
||||
continue
|
||||
self.server.store(key, "+FLAGS", "\\Deleted");
|
||||
self.server.expunge()
|
||||
return
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue