1
0
Fork 1
mirror of https://github.com/coddingtonbear/django-mailbox.git synced 2026-07-09 22:38:19 +02:00
This commit is contained in:
Scott Stafford 2022-12-29 21:17:41 -08:00 committed by GitHub
commit f24d46cec5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 104 additions and 20 deletions

View file

@ -1,3 +1,3 @@
__version__ = '4.8.2'
__version__ = "4.8.2"
default_app_config = 'django_mailbox.apps.MailBoxConfig'
default_app_config = "django_mailbox.apps.MailBoxConfig"

View file

@ -31,7 +31,7 @@ from django_mailbox import utils
from django_mailbox.signals import message_received
from django_mailbox.transports import Pop3Transport, ImapTransport, \
MaildirTransport, MboxTransport, BabylTransport, MHTransport, \
MMDFTransport, GmailImapTransport
MMDFTransport, GmailImapTransport, Office365Transport
logger = logging.getLogger(__name__)
@ -216,6 +216,14 @@ class Mailbox(models.Model):
archive=self.archive
)
conn.connect(self.username, self.password)
elif self.type == 'office365':
conn = Office365Transport(
self.location,
self.username,
folder=self.folder,
archive=self.archive
)
conn.connect()
elif self.type == 'pop3':
conn = Pop3Transport(
self.location,
@ -382,8 +390,13 @@ class Mailbox(models.Model):
except KeyError as exc:
# email.message.replace_header may raise 'KeyError' if the header
# 'content-transfer-encoding' is missing
logger.warning("Failed to parse message: %s", exc,)
return None
try:
# Before we give up, let's try mailman's approach:
# https://bugs.python.org/msg308362
body = message.as_bytes(self).decode('ascii', 'replace')
except KeyError as exc:
logger.warning("Failed to parse message: %s", exc,)
return None
msg.set_body(body)
if message['in-reply-to']:
try:

View file

@ -1,3 +1,3 @@
from django.dispatch.dispatcher import Signal
message_received = Signal(providing_args=['message'])
message_received = Signal()

View file

@ -15,8 +15,8 @@ class Migration(SchemaMigration):
# 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))
('from_message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False)),
('to_message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False))
))
db.create_unique('django_mailbox_message_references', ['from_message_id', 'to_message_id'])

View file

@ -15,8 +15,8 @@ class Migration(SchemaMigration):
# 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))
('from_message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False)),
('to_message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False))
))
db.create_unique('django_mailbox_message_references', ['from_message_id', 'to_message_id'])

View file

@ -17,8 +17,8 @@ class Migration(SchemaMigration):
# Adding M2M table for field attachments on 'Message'
db.create_table('django_mailbox_message_attachments', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('message', models.ForeignKey(orm['django_mailbox.message'], null=False)),
('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], null=False))
('message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False)),
('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], on_delete=models.CASCADE, null=False))
))
db.create_unique('django_mailbox_message_attachments', ['message_id', 'messageattachment_id'])

View file

@ -20,8 +20,8 @@ class Migration(SchemaMigration):
# Adding M2M table for field attachments on 'Message'
db.create_table('django_mailbox_message_attachments', (
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
('message', models.ForeignKey(orm['django_mailbox.message'], null=False)),
('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], null=False))
('message', models.ForeignKey(orm['django_mailbox.message'], on_delete=models.CASCADE, null=False)),
('messageattachment', models.ForeignKey(orm['django_mailbox.messageattachment'], on_delete=models.CASCADE, null=False))
))
db.create_unique('django_mailbox_message_attachments', ['message_id', 'messageattachment_id'])

View file

@ -9,7 +9,7 @@ from django_mailbox.models import Mailbox, Message
from django_mailbox.utils import convert_header_to_unicode
from django_mailbox import utils
from django_mailbox.tests.base import EmailMessageTestCase
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from django.core.mail import EmailMessage
__all__ = ['TestProcessEmail']
@ -367,12 +367,12 @@ class TestProcessEmail(EmailMessageTestCase):
email_object = self._get_email_object(
'message_with_long_content.eml',
)
size = len(force_text(email_object.as_string()))
size = len(force_str(email_object.as_string()))
msg = self.mailbox.process_incoming_message(email_object)
self.assertEqual(size,
len(force_text(msg.get_email_object().as_string())))
len(force_str(msg.get_email_object().as_string())))
def test_message_saved(self):
message = self._get_email_object('generic_message.eml')

View file

@ -8,3 +8,4 @@ from django_mailbox.transports.babyl import BabylTransport
from django_mailbox.transports.mh import MHTransport
from django_mailbox.transports.mmdf import MMDFTransport
from django_mailbox.transports.gmail import GmailImapTransport
from django_mailbox.transports.office365 import Office365Transport

View file

@ -0,0 +1,70 @@
import logging
import os
from django.conf import settings
from .base import EmailTransport, MessageParseError
logger = logging.getLogger(__name__)
class Office365Transport(EmailTransport):
def __init__(
self, hostname, username, archive='', folder=None
):
self.integration_testing_subject = getattr(
settings,
'DJANGO_MAILBOX_INTEGRATION_TESTING_SUBJECT',
None
)
self.hostname = hostname
self.username = username
self.archive = archive
self.folder = folder
def connect(self):
try:
import O365
except ImportError:
raise ValueError(
"Install o365 to use oauth2 auth for office365"
)
credentials = (settings.MICROSOFT_O365_CLIENT_ID, settings.MICROSOFT_O365_CLIENT_SECRET)
if not os.path.isdir(settings.O365_TOKEN_PATH):
os.mkdir(settings.O365_TOKEN_PATH)
token_path=os.path.join(settings.O365_TOKEN_PATH, 'token.txt')
self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=settings.MICROSOFT_O365_TENENT_ID, token_path=token_path)
self.account.authenticate()
self.mailbox = self.account.mailbox(resource=self.username)
self.mailbox_folder = self.mailbox.inbox_folder()
if self.folder:
self.mailbox_folder = self.mailbox.get_folder(folder_name=self.folder)
def get_message(self, condition=None):
archive_folder = None
if self.archive:
archive_folder = self.mailbox.get_folder(folder_name=self.archive)
if not archive_folder:
archive_folder = self.mailbox.create_child_folder(self.archive)
for o365message in self.mailbox_folder.get_messages(order_by='receivedDateTime'):
try:
mime_content = o365message.get_mime_content()
message = self.get_email_from_bytes(mime_content)
if condition and not condition(message):
continue
yield message
except MessageParseError:
continue
if self.archive and archive_folder:
o365message.copy(archive_folder)
o365message.delete()
return

View file

@ -244,7 +244,7 @@ sys.path.insert(0, os.path.abspath('..'))
import inspect
import django
from django.utils.html import strip_tags
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from django.conf import settings
settings.configure(INSTALLED_APPS=['django_mailbox', ])
django.setup()
@ -265,11 +265,11 @@ def process_docstring(app, what, name, obj, options, lines):
continue
# Decode and strip any html out of the field's help text
help_text = strip_tags(force_text(field.help_text))
help_text = strip_tags(force_str(field.help_text))
# Decode and capitalize the verbose name, for use if there isn't
# any help text
verbose_name = force_text(field.verbose_name).capitalize()
verbose_name = force_str(field.verbose_name).capitalize()
if help_text:
# Add the model field to the end of the docstring as a param