forked from mirror/django-mailbox
Adding file-based transports including Maildir, Mbox, Babyl, MH, and MMDF.
This commit is contained in:
parent
6a0305f944
commit
aa0b79b36f
13 changed files with 174 additions and 77 deletions
|
|
@ -4,7 +4,9 @@ import urllib
|
||||||
import urlparse
|
import urlparse
|
||||||
|
|
||||||
from django.db import models
|
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
|
from django_mailbox.signals import message_received
|
||||||
|
|
||||||
class Mailbox(models.Model):
|
class Mailbox(models.Model):
|
||||||
|
|
@ -12,10 +14,10 @@ class Mailbox(models.Model):
|
||||||
uri = models.CharField(
|
uri = models.CharField(
|
||||||
max_length=255,
|
max_length=255,
|
||||||
help_text="""
|
help_text="""
|
||||||
Start your URI with imap://, imap+ssl://, pop3://, or pop3+ssl://.
|
Example: imap+ssl://myusername:mypassword@someserver
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
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'.
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
Be sure to urlencode your username and password should they
|
Be sure to urlencode your username and password should they
|
||||||
|
|
@ -60,18 +62,29 @@ class Mailbox(models.Model):
|
||||||
|
|
||||||
def get_connection(self):
|
def get_connection(self):
|
||||||
if self.type == 'imap':
|
if self.type == 'imap':
|
||||||
conn = ImapMailEnumerator(
|
conn = ImapTransport(
|
||||||
self.location,
|
self.location,
|
||||||
port=self.port if self.port else None,
|
port=self.port if self.port else None,
|
||||||
ssl=self.use_ssl
|
ssl=self.use_ssl
|
||||||
)
|
)
|
||||||
|
conn.connect(self.username, self.password)
|
||||||
elif self.type == 'pop3':
|
elif self.type == 'pop3':
|
||||||
conn = PopMailEnumerator(
|
conn = Pop3Transport(
|
||||||
self.location,
|
self.location,
|
||||||
port=self.port if self.port else None,
|
port=self.port if self.port else None,
|
||||||
ssl=self.use_ssl
|
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
|
return conn
|
||||||
|
|
||||||
def get_new_mail(self):
|
def get_new_mail(self):
|
||||||
|
|
@ -79,10 +92,11 @@ class Mailbox(models.Model):
|
||||||
new_mail = []
|
new_mail = []
|
||||||
for message in connection.get_message():
|
for message in connection.get_message():
|
||||||
msg = Message()
|
msg = Message()
|
||||||
|
print msg
|
||||||
msg.mailbox = self
|
msg.mailbox = self
|
||||||
msg.subject = message['subject']
|
msg.subject = message['subject'][0:255]
|
||||||
msg.message_id = message['message-id']
|
msg.message_id = message['message-id'][0:255]
|
||||||
msg.from_address = rfc822.parseaddr(message['from'])[1]
|
msg.from_address = rfc822.parseaddr(message['from'])[1][0:255]
|
||||||
msg.body = message.as_string()
|
msg.body = message.as_string()
|
||||||
msg.save()
|
msg.save()
|
||||||
new_mail.append(msg)
|
new_mail.append(msg)
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
||||||
|
|
|
||||||
7
django_mailbox/transports/__init__.py
Normal file
7
django_mailbox/transports/__init__.py
Normal file
|
|
@ -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
|
||||||
5
django_mailbox/transports/babyl.py
Normal file
5
django_mailbox/transports/babyl.py
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
from mailbox import Babyl
|
||||||
|
from django_mailbox.transports.generic import GenericFileMailbox
|
||||||
|
|
||||||
|
class BabylTransport(GenericFileMailbox):
|
||||||
|
_variant = Babyl
|
||||||
18
django_mailbox/transports/generic.py
Normal file
18
django_mailbox/transports/generic.py
Normal file
|
|
@ -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()
|
||||||
33
django_mailbox/transports/imap.py
Normal file
33
django_mailbox/transports/imap.py
Normal file
|
|
@ -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
|
||||||
8
django_mailbox/transports/maildir.py
Normal file
8
django_mailbox/transports/maildir.py
Normal file
|
|
@ -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)
|
||||||
5
django_mailbox/transports/mbox.py
Normal file
5
django_mailbox/transports/mbox.py
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
from mailbox import mbox
|
||||||
|
from django_mailbox.transports.generic import GenericFileMailbox
|
||||||
|
|
||||||
|
class MboxTransport(GenericFileMailbox):
|
||||||
|
_variant = mbox
|
||||||
5
django_mailbox/transports/mh.py
Normal file
5
django_mailbox/transports/mh.py
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
from mailbox import MH
|
||||||
|
from django_mailbox.transports.generic import GenericFileMailbox
|
||||||
|
|
||||||
|
class MHTransport(GenericFileMailbox):
|
||||||
|
_variant = MH
|
||||||
5
django_mailbox/transports/mmdf.py
Normal file
5
django_mailbox/transports/mmdf.py
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
from mailbox import MMDF
|
||||||
|
from django_mailbox.transports.generic import GenericFileMailbox
|
||||||
|
|
||||||
|
class MMDFTransport(GenericFileMailbox):
|
||||||
|
_variant = MMDF
|
||||||
33
django_mailbox/transports/pop3.py
Normal file
33
django_mailbox/transports/pop3.py
Normal file
|
|
@ -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
|
||||||
33
readme.rst
33
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.
|
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::
|
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
|
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
|
Subscribing to the incoming mail signal
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
|
|
|
||||||
2
setup.py
2
setup.py
|
|
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='django_mailbox',
|
name='django_mailbox',
|
||||||
version='0.2',
|
version='1.0',
|
||||||
url='http://bitbucket.org/latestrevision/django-mailbox/',
|
url='http://bitbucket.org/latestrevision/django-mailbox/',
|
||||||
description='Automatically import mail from POP3 or IMAP into Django',
|
description='Automatically import mail from POP3 or IMAP into Django',
|
||||||
author='Adam Coddington',
|
author='Adam Coddington',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue