diff --git a/django_mailbox/models.py b/django_mailbox/models.py
index 69666d4..9c26d92 100644
--- a/django_mailbox/models.py
+++ b/django_mailbox/models.py
@@ -4,7 +4,9 @@ import urllib
import urlparse
from django.db import models
-from django_mailbox.transports import PopMailEnumerator, ImapMailEnumerator
+from django_mailbox.transports import Pop3Transport, ImapTransport,\
+ MaildirTransport, MboxTransport, BabylTransport, MHTransport, \
+ MMDFTransport
from django_mailbox.signals import message_received
class Mailbox(models.Model):
@@ -12,10 +14,10 @@ class Mailbox(models.Model):
uri = models.CharField(
max_length=255,
help_text="""
- Start your URI with imap://, imap+ssl://, pop3://, or pop3+ssl://.
+ Example: imap+ssl://myusername:mypassword@someserver
- Example: imap://myusername:mypassword@someserver
+ Internet transports include 'imap' and 'pop3'; common local file transports include 'maildir', 'mbox', and less commonly 'babyl', 'mh', and 'mmdf'.
Be sure to urlencode your username and password should they
@@ -60,18 +62,29 @@ class Mailbox(models.Model):
def get_connection(self):
if self.type == 'imap':
- conn = ImapMailEnumerator(
+ conn = ImapTransport(
self.location,
port=self.port if self.port else None,
ssl=self.use_ssl
)
+ conn.connect(self.username, self.password)
elif self.type == 'pop3':
- conn = PopMailEnumerator(
+ conn = Pop3Transport(
self.location,
port=self.port if self.port else None,
ssl=self.use_ssl
)
- conn.connect(self.username, self.password)
+ conn.connect(self.username, self.password)
+ elif self.type == 'maildir':
+ conn = MaildirTransport(self.location)
+ elif self.type == 'mbox':
+ conn = MboxTransport(self.location)
+ elif self.type == 'babyl':
+ conn = BabylTransport(self.location)
+ elif self.type == 'mh':
+ conn = MHTransport(self.location)
+ elif self.type == 'mmdf':
+ conn = MMDFTransport(self.location)
return conn
def get_new_mail(self):
@@ -79,10 +92,11 @@ class Mailbox(models.Model):
new_mail = []
for message in connection.get_message():
msg = Message()
+ print msg
msg.mailbox = self
- msg.subject = message['subject']
- msg.message_id = message['message-id']
- msg.from_address = rfc822.parseaddr(message['from'])[1]
+ 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.body = message.as_string()
msg.save()
new_mail.append(msg)
diff --git a/django_mailbox/transports.py b/django_mailbox/transports.py
index abed1ac..8b13789 100644
--- a/django_mailbox/transports.py
+++ b/django_mailbox/transports.py
@@ -1,66 +1 @@
-import email
-from imaplib import IMAP4, IMAP4_SSL
-from poplib import POP3, POP3_SSL
-
-class PopMailEnumerator(object):
- def __init__(self, hostname, port=None, ssl=False):
- self.hostname = hostname
- self.port = port
- if ssl:
- self.transport = POP3_SSL
- if not self.port:
- self.port = 995
- else:
- self.transport = POP3
- if not self.port:
- self.port = 110
-
- def connect(self, username, password):
- self.server = self.transport(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=None, ssl=False):
- self.hostname = hostname
- self.port = port
- if ssl:
- self.transport = IMAP4_SSL
- if not self.port:
- self.port = 993
- else:
- self.transport = IMAP4
- if not self.port:
- self.port = 143
-
- def connect(self, username, password):
- self.server = self.transport(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
diff --git a/django_mailbox/transports/__init__.py b/django_mailbox/transports/__init__.py
new file mode 100644
index 0000000..fc17082
--- /dev/null
+++ b/django_mailbox/transports/__init__.py
@@ -0,0 +1,7 @@
+from django_mailbox.transports.imap import ImapTransport
+from django_mailbox.transports.pop3 import Pop3Transport
+from django_mailbox.transports.maildir import MaildirTransport
+from django_mailbox.transports.mbox import MboxTransport
+from django_mailbox.transports.babyl import BabylTransport
+from django_mailbox.transports.mh import MHTransport
+from django_mailbox.transports.mmdf import MMDFTransport
diff --git a/django_mailbox/transports/babyl.py b/django_mailbox/transports/babyl.py
new file mode 100644
index 0000000..674aa2e
--- /dev/null
+++ b/django_mailbox/transports/babyl.py
@@ -0,0 +1,5 @@
+from mailbox import Babyl
+from django_mailbox.transports.generic import GenericFileMailbox
+
+class BabylTransport(GenericFileMailbox):
+ _variant = Babyl
diff --git a/django_mailbox/transports/generic.py b/django_mailbox/transports/generic.py
new file mode 100644
index 0000000..059d078
--- /dev/null
+++ b/django_mailbox/transports/generic.py
@@ -0,0 +1,18 @@
+class GenericFileMailbox(object):
+ _variant = None
+ _path = None
+
+ def __init__(self, path):
+ super(GenericFileMailbox, self).__init__()
+ self._path = path
+
+ def get_instance(self):
+ return self._variant(self._path)
+
+ def get_message(self):
+ repository = self.get_instance()
+ repository.lock()
+ for key, message in repository.items():
+ repository.remove(key)
+ yield message
+ repository.unlock()
diff --git a/django_mailbox/transports/imap.py b/django_mailbox/transports/imap.py
new file mode 100644
index 0000000..1c57b1c
--- /dev/null
+++ b/django_mailbox/transports/imap.py
@@ -0,0 +1,33 @@
+import email
+from imaplib import IMAP4, IMAP4_SSL
+
+class ImapTransport(object):
+ def __init__(self, hostname, port=None, ssl=False):
+ self.hostname = hostname
+ self.port = port
+ if ssl:
+ self.transport = IMAP4_SSL
+ if not self.port:
+ self.port = 993
+ else:
+ self.transport = IMAP4
+ if not self.port:
+ self.port = 143
+
+ def connect(self, username, password):
+ self.server = self.transport(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
diff --git a/django_mailbox/transports/maildir.py b/django_mailbox/transports/maildir.py
new file mode 100644
index 0000000..17f7511
--- /dev/null
+++ b/django_mailbox/transports/maildir.py
@@ -0,0 +1,8 @@
+from mailbox import Maildir
+from django_mailbox.transports.generic import GenericFileMailbox
+
+class MaildirTransport(GenericFileMailbox):
+ _variant = Maildir
+
+ def get_instance(self):
+ return self._variant(self._path, None)
diff --git a/django_mailbox/transports/mbox.py b/django_mailbox/transports/mbox.py
new file mode 100644
index 0000000..708bb33
--- /dev/null
+++ b/django_mailbox/transports/mbox.py
@@ -0,0 +1,5 @@
+from mailbox import mbox
+from django_mailbox.transports.generic import GenericFileMailbox
+
+class MboxTransport(GenericFileMailbox):
+ _variant = mbox
diff --git a/django_mailbox/transports/mh.py b/django_mailbox/transports/mh.py
new file mode 100644
index 0000000..574ccf3
--- /dev/null
+++ b/django_mailbox/transports/mh.py
@@ -0,0 +1,5 @@
+from mailbox import MH
+from django_mailbox.transports.generic import GenericFileMailbox
+
+class MHTransport(GenericFileMailbox):
+ _variant = MH
diff --git a/django_mailbox/transports/mmdf.py b/django_mailbox/transports/mmdf.py
new file mode 100644
index 0000000..ad46284
--- /dev/null
+++ b/django_mailbox/transports/mmdf.py
@@ -0,0 +1,5 @@
+from mailbox import MMDF
+from django_mailbox.transports.generic import GenericFileMailbox
+
+class MMDFTransport(GenericFileMailbox):
+ _variant = MMDF
diff --git a/django_mailbox/transports/pop3.py b/django_mailbox/transports/pop3.py
new file mode 100644
index 0000000..b6943ae
--- /dev/null
+++ b/django_mailbox/transports/pop3.py
@@ -0,0 +1,33 @@
+import email
+from poplib import POP3, POP3_SSL
+
+class Pop3Transport(object):
+ def __init__(self, hostname, port=None, ssl=False):
+ self.hostname = hostname
+ self.port = port
+ if ssl:
+ self.transport = POP3_SSL
+ if not self.port:
+ self.port = 995
+ else:
+ self.transport = POP3
+ if not self.port:
+ self.port = 110
+
+ def connect(self, username, password):
+ self.server = self.transport(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
diff --git a/readme.rst b/readme.rst
index 575bc19..2665f9e 100644
--- a/readme.rst
+++ b/readme.rst
@@ -7,8 +7,27 @@ This small Django application will allow you to specify IMAP or POP3 mailboxes t
WARNING! This app will delete any messages it can find in the inbox you specify-- please make sure you don't have anything important in there.
-URI Examples
-============
+Setting up your mailbox
+=======================
+
+Django Mailbox supports both common internet mailboxes like POP3 and IMAP as well as local file-based mailboxes.
+
+.. table:: Protocol Options
+
+ ============ ============== =========================================
+ Mailbox Type 'Protocol' Notes
+ ============ ============== =========================================
+ POP3 ``pop3://`` Can also specify SSL with ``pop3+ssl://``
+ IMAP ``imap://`` Can also specify SSL with ``imap+ssl://``
+ Maildir ``maildir://``
+ Mbox ``mbox://``
+ Babyl ``babyl://``
+ MH ``mh://``
+ MMDF ``mmdf://``
+ ============ ============== =========================================
+
+POP3 and IMAP Mailboxes
+-----------------------
Mailbox URIs are in the normal URI format::
@@ -23,6 +42,16 @@ If you have an account named 'contemporanea@gmail.com' with a password of '1234'
pop3+ssl://contemporanea%40gmail.com:1234@pop.gmail.com
+Local File-based Mailboxes
+--------------------------
+
+If you happen to want to consume a file-based mailbox like an Maildir, Mbox, Babyl, MH, or MMDF mailbox, you can use this too by entering the appropriate 'protocol' in the URI. If you had a maildir, for example, at @/var/mail/@, you would enter a URI like::
+
+ maildir:///var/mail
+
+.. important::
+ Note that there are three slashes in the above URI.
+
Subscribing to the incoming mail signal
=======================================
diff --git a/setup.py b/setup.py
index 84eb31c..aabc8ac 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name='django_mailbox',
- version='0.2',
+ version='1.0',
url='http://bitbucket.org/latestrevision/django-mailbox/',
description='Automatically import mail from POP3 or IMAP into Django',
author='Adam Coddington',