forked from mirror/django-mailbox
clear code
This commit is contained in:
parent
b02fd73d1c
commit
8f944190ad
5 changed files with 26 additions and 93 deletions
|
|
@ -208,7 +208,7 @@ class Mailbox(models.Model):
|
||||||
@property
|
@property
|
||||||
def tenant_id(self):
|
def tenant_id(self):
|
||||||
"""Returns (if specified) the tenant id for Office365."""
|
"""Returns (if specified) the tenant id for Office365."""
|
||||||
tenant_id = self._query_string.get('tentant_id', None)
|
tenant_id = self._query_string.get('tenant_id', None)
|
||||||
if not tenant_id:
|
if not tenant_id:
|
||||||
return None
|
return None
|
||||||
return tenant_id[0]
|
return tenant_id[0]
|
||||||
|
|
@ -249,14 +249,13 @@ class Mailbox(models.Model):
|
||||||
conn.connect(self.username, self.password)
|
conn.connect(self.username, self.password)
|
||||||
elif self.type == 'office365':
|
elif self.type == 'office365':
|
||||||
conn = Office365Transport(
|
conn = Office365Transport(
|
||||||
|
self.location,
|
||||||
|
self.username,
|
||||||
port=self.port if self.port else None,
|
port=self.port if self.port else None,
|
||||||
ssl=True,
|
ssl=True,
|
||||||
archive=self.archive,
|
folder=self.folder
|
||||||
client_id=self.client_id,
|
|
||||||
client_secret=self.client_secret,
|
|
||||||
tenant_id=self.tenant_id
|
|
||||||
)
|
)
|
||||||
conn.connect(self.username, self.password)
|
conn.connect(self.client_id, self.client_secret, self.tenant_id)
|
||||||
elif self.type == 'maildir':
|
elif self.type == 'maildir':
|
||||||
conn = MaildirTransport(self.location)
|
conn = MaildirTransport(self.location)
|
||||||
elif self.type == 'mbox':
|
elif self.type == 'mbox':
|
||||||
|
|
|
||||||
|
|
@ -9,3 +9,8 @@ class EmailTransport:
|
||||||
message = email.message_from_bytes(contents)
|
message = email.message_from_bytes(contents)
|
||||||
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
def get_email_from_string(self, contents):
|
||||||
|
message = email.message_from_string(contents)
|
||||||
|
|
||||||
|
return message
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class Office365Transport(EmailTransport):
|
class Office365Transport(EmailTransport):
|
||||||
def __init__(
|
def __init__(
|
||||||
self, port=None, ssl=False, tls=False,
|
self, hostname, username, port=None, ssl=False, tls=False, folder=None
|
||||||
archive='', folder=None, client_id=None, client_secret=None, tenant_id=None
|
|
||||||
):
|
):
|
||||||
self.max_message_size = getattr(
|
self.max_message_size = getattr(
|
||||||
settings,
|
settings,
|
||||||
|
|
@ -23,8 +22,9 @@ class Office365Transport(EmailTransport):
|
||||||
'DJANGO_MAILBOX_INTEGRATION_TESTING_SUBJECT',
|
'DJANGO_MAILBOX_INTEGRATION_TESTING_SUBJECT',
|
||||||
None
|
None
|
||||||
)
|
)
|
||||||
|
self.hostname = hostname
|
||||||
|
self.username = username
|
||||||
self.port = port
|
self.port = port
|
||||||
self.archive = archive
|
|
||||||
self.folder = folder
|
self.folder = folder
|
||||||
self.tls = tls
|
self.tls = tls
|
||||||
if ssl:
|
if ssl:
|
||||||
|
|
@ -35,85 +35,23 @@ class Office365Transport(EmailTransport):
|
||||||
#self.transport = imaplib.IMAP4
|
#self.transport = imaplib.IMAP4
|
||||||
if not self.port:
|
if not self.port:
|
||||||
self.port = 143
|
self.port = 143
|
||||||
self.client_id = client_id
|
|
||||||
self.client_secret = client_secret
|
|
||||||
self.tenant_id = tenant_id
|
|
||||||
|
|
||||||
def connect(self, username, password):
|
def connect(self, client_id, client_secret, tenant_id):
|
||||||
credentials = (self.client_id, self.client_secret)
|
credentials = (client_id, client_secret)
|
||||||
|
|
||||||
# the default protocol will be Microsoft Graph
|
self.account = O365.Account(credentials, auth_flow_type='credentials', tenant_id=tenant_id)
|
||||||
# the default authentication method will be "on behalf of a user"
|
self.account.authenticate()
|
||||||
|
|
||||||
self.server = O365.Account(credentials, auth_flow_type='credentials', tenant_id=self.tenant_id)
|
self.mailbox = self.account.mailbox(resource=self.username)
|
||||||
if self.server.authenticate(scopes=['mailbox']):
|
self.mailbox_folder = self.mailbox.inbox_folder()
|
||||||
print('Authenticated!')
|
if self.folder:
|
||||||
|
self.mailbox_folder = self.mailbox.get_folder(folder_name=self.folder)
|
||||||
def _get_all_message_ids(self):
|
|
||||||
# # Fetch all the message uids
|
|
||||||
# response, message_ids = self.server.uid('search', None, 'ALL')
|
|
||||||
# message_id_string = message_ids[0].strip()
|
|
||||||
# # Usually `message_id_string` will be a list of space-separated
|
|
||||||
# # ids; we must make sure that it isn't an empty string before
|
|
||||||
# # splitting into individual UIDs.
|
|
||||||
# if message_id_string:
|
|
||||||
# return message_id_string.decode().split(' ')
|
|
||||||
return []
|
|
||||||
|
|
||||||
def _get_small_message_ids(self, message_ids):
|
|
||||||
# Using existing message uids, get the sizes and
|
|
||||||
# return only those that are under the size
|
|
||||||
# limit
|
|
||||||
safe_message_ids = []
|
|
||||||
|
|
||||||
status, data = self.server.uid(
|
|
||||||
'fetch',
|
|
||||||
','.join(message_ids),
|
|
||||||
'(RFC822.SIZE)'
|
|
||||||
)
|
|
||||||
|
|
||||||
for each_msg in data:
|
|
||||||
each_msg = each_msg.decode()
|
|
||||||
try:
|
|
||||||
uid = each_msg.split(' ')[2]
|
|
||||||
size = each_msg.split(' ')[4].rstrip(')')
|
|
||||||
if int(size) <= int(self.max_message_size):
|
|
||||||
safe_message_ids.append(uid)
|
|
||||||
except ValueError as e:
|
|
||||||
logger.warning(
|
|
||||||
"ValueError: {} working on {}".format(e, each_msg[0])
|
|
||||||
)
|
|
||||||
pass
|
|
||||||
return safe_message_ids
|
|
||||||
|
|
||||||
def get_message(self, condition=None):
|
def get_message(self, condition=None):
|
||||||
message_ids = self._get_all_message_ids()
|
for message in self.mailbox.get_messages(order_by='receivedDateTime'):
|
||||||
|
|
||||||
if not message_ids:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Limit the uids to the small ones if we care about that
|
|
||||||
if self.max_message_size:
|
|
||||||
message_ids = self._get_small_message_ids(message_ids)
|
|
||||||
|
|
||||||
if self.archive:
|
|
||||||
typ, folders = self.server.list(pattern=self.archive)
|
|
||||||
if folders[0] is None:
|
|
||||||
# If the archive folder does not exist, create it
|
|
||||||
self.server.create(self.archive)
|
|
||||||
|
|
||||||
for uid in message_ids:
|
|
||||||
try:
|
try:
|
||||||
typ, msg_contents = self.server.uid('fetch', uid, '(RFC822)')
|
mime_content = message.get_mime_content()
|
||||||
if not msg_contents:
|
message = self.get_email_from_bytes(mime_content)
|
||||||
continue
|
|
||||||
try:
|
|
||||||
message = self.get_email_from_bytes(msg_contents[0][1])
|
|
||||||
except TypeError:
|
|
||||||
# This happens if another thread/process deletes the
|
|
||||||
# message between our generating the ID list and our
|
|
||||||
# processing it here.
|
|
||||||
continue
|
|
||||||
|
|
||||||
if condition and not condition(message):
|
if condition and not condition(message):
|
||||||
continue
|
continue
|
||||||
|
|
@ -121,10 +59,5 @@ class Office365Transport(EmailTransport):
|
||||||
yield message
|
yield message
|
||||||
except MessageParseError:
|
except MessageParseError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if self.archive:
|
|
||||||
self.server.uid('copy', uid, self.archive)
|
|
||||||
|
|
||||||
self.server.uid('store', uid, "+FLAGS", "(\\Deleted)")
|
|
||||||
self.server.expunge()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,3 @@ class EmailTransport:
|
||||||
|
|
||||||
return message
|
return message
|
||||||
|
|
||||||
def get_email_from_string(self, contents):
|
|
||||||
message = email.message_from_string(contents)
|
|
||||||
|
|
||||||
return message
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ class Office365Transport(EmailTransport):
|
||||||
for message in self.mailbox.get_messages(order_by='receivedDateTime'):
|
for message in self.mailbox.get_messages(order_by='receivedDateTime'):
|
||||||
try:
|
try:
|
||||||
mime_content = message.get_mime_content()
|
mime_content = message.get_mime_content()
|
||||||
message = self.get_email_from_string(mime_content)
|
message = self.get_email_from_bytes(mime_content)
|
||||||
|
|
||||||
if condition and not condition(message):
|
if condition and not condition(message):
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue